~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-08-17 01:44:23 UTC
  • mto: This revision was merged to the branch mainline in revision 1118.
  • Revision ID: brian@gaz-20090817014423-jxi2qonsumm8mndf
Remove SQL level reference for DELAY (just now done correctly by default in
engine).

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
  /* db_create_options was stored as 2 bytes in FRM
 
315
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
 
316
   */
 
317
  share->db_create_options= (db_create_options & 0x0000FFFF);
 
318
  share->db_options_in_use= share->db_create_options;
 
319
 
 
320
 
 
321
  share->avg_row_length= table_options.has_avg_row_length() ?
 
322
    table_options.avg_row_length() : 0;
 
323
 
 
324
  share->page_checksum= table_options.has_page_checksum() ?
 
325
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
326
    : HA_CHOICE_UNDEF;
 
327
 
 
328
  share->row_type= table_options.has_row_type() ?
 
329
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
330
 
 
331
  share->block_size= table_options.has_block_size() ?
 
332
    table_options.block_size() : 0;
 
333
 
 
334
  share->table_charset= get_charset(table_options.has_collation_id()?
 
335
                                    table_options.collation_id() : 0);
 
336
 
 
337
  if (!share->table_charset)
 
338
  {
 
339
    /* unknown charset in head[38] or pre-3.23 frm */
 
340
    if (use_mb(default_charset_info))
 
341
    {
 
342
      /* Warn that we may be changing the size of character columns */
 
343
      errmsg_printf(ERRMSG_LVL_WARN,
 
344
                    _("'%s' had no or invalid character set, "
 
345
                      "and default character set is multi-byte, "
 
346
                      "so character column sizes may have changed"),
 
347
                    share->path.str);
 
348
    }
 
349
    share->table_charset= default_charset_info;
 
350
  }
 
351
 
 
352
  share->db_record_offset= 1;
 
353
 
 
354
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
355
 
 
356
  share->db_low_byte_first= true;
 
357
 
 
358
  share->max_rows= table_options.has_max_rows() ?
 
359
    table_options.max_rows() : 0;
 
360
 
 
361
  share->min_rows= table_options.has_min_rows() ?
 
362
    table_options.min_rows() : 0;
 
363
 
 
364
  share->keys= table.indexes_size();
 
365
 
 
366
  share->key_parts= 0;
 
367
  for (int indx= 0; indx < table.indexes_size(); indx++)
 
368
    share->key_parts+= table.indexes(indx).index_part_size();
 
369
 
 
370
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
371
                                     table.indexes_size() * sizeof(KEY)
 
372
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
373
 
 
374
  KEY_PART_INFO *key_part;
 
375
 
 
376
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
377
    (share->key_info+table.indexes_size());
 
378
 
 
379
 
 
380
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
381
                                            sizeof(ulong*)*share->key_parts);
 
382
 
 
383
  share->keynames.count= table.indexes_size();
 
384
  share->keynames.name= NULL;
 
385
  share->keynames.type_names= (const char**)
 
386
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
387
 
 
388
  share->keynames.type_lengths= (unsigned int*)
 
389
    alloc_root(&share->mem_root,
 
390
               sizeof(unsigned int) * (table.indexes_size()+1));
 
391
 
 
392
  share->keynames.type_names[share->keynames.count]= NULL;
 
393
  share->keynames.type_lengths[share->keynames.count]= 0;
 
394
 
 
395
  KEY* keyinfo= share->key_info;
 
396
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
397
  {
 
398
    drizzled::message::Table::Index indx= table.indexes(keynr);
 
399
 
 
400
    keyinfo->table= 0;
 
401
    keyinfo->flags= 0;
 
402
 
 
403
    if (indx.is_unique())
 
404
      keyinfo->flags|= HA_NOSAME;
 
405
 
 
406
    if (indx.has_options())
 
407
    {
 
408
      drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
 
409
      if (indx_options.pack_key())
 
410
        keyinfo->flags|= HA_PACK_KEY;
 
411
 
 
412
      if (indx_options.var_length_key())
 
413
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
414
 
 
415
      if (indx_options.null_part_key())
 
416
        keyinfo->flags|= HA_NULL_PART_KEY;
 
417
 
 
418
      if (indx_options.binary_pack_key())
 
419
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
420
 
 
421
      if (indx_options.has_partial_segments())
 
422
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
423
 
 
424
      if (indx_options.auto_generated_key())
 
425
        keyinfo->flags|= HA_GENERATED_KEY;
 
426
 
 
427
      if (indx_options.has_key_block_size())
 
428
      {
 
429
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
430
        keyinfo->block_size= indx_options.key_block_size();
 
431
      }
 
432
      else
 
433
      {
 
434
        keyinfo->block_size= 0;
 
435
      }
 
436
 
 
437
    }
 
438
 
 
439
    switch(indx.type())
 
440
    {
 
441
    case drizzled::message::Table::Index::UNKNOWN_INDEX:
 
442
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
443
      break;
 
444
    case drizzled::message::Table::Index::BTREE:
 
445
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
446
      break;
 
447
    case drizzled::message::Table::Index::RTREE:
 
448
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
449
      break;
 
450
    case drizzled::message::Table::Index::HASH:
 
451
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
452
      break;
 
453
    case drizzled::message::Table::Index::FULLTEXT:
 
454
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
455
 
 
456
    default:
 
457
      /* TODO: suitable warning ? */
 
458
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
459
      break;
 
460
    }
 
461
 
 
462
    keyinfo->key_length= indx.key_length();
 
463
 
 
464
    keyinfo->key_parts= indx.index_part_size();
 
465
 
 
466
    keyinfo->key_part= key_part;
 
467
    keyinfo->rec_per_key= rec_per_key;
 
468
 
 
469
    for (unsigned int partnr= 0;
 
470
        partnr < keyinfo->key_parts;
 
471
        partnr++, key_part++)
 
472
    {
 
473
      drizzled::message::Table::Index::IndexPart part;
 
474
      part= indx.index_part(partnr);
 
475
 
 
476
      *rec_per_key++= 0;
 
477
 
 
478
      key_part->field= NULL;
 
479
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
 
480
      key_part->null_bit= 0;
 
481
      /* key_part->null_offset is only set if null_bit (see later) */
 
482
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
483
      /* key_part->type ???? */
 
484
      key_part->key_part_flag= 0;
 
485
      if (part.has_in_reverse_order())
 
486
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
487
 
 
488
      key_part->length= part.compare_length();
 
489
 
 
490
      key_part->store_length= key_part->length;
 
491
 
 
492
      /* key_part->offset is set later */
 
493
      key_part->key_type= part.key_type();
 
494
 
 
495
    }
 
496
 
 
497
    if (!indx.has_comment())
 
498
    {
 
499
      keyinfo->comment.length= 0;
 
500
      keyinfo->comment.str= NULL;
 
501
    }
 
502
    else
 
503
    {
 
504
      keyinfo->flags|= HA_USES_COMMENT;
 
505
      keyinfo->comment.length= indx.comment().length();
 
506
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
507
                                         indx.comment().c_str(),
 
508
                                         keyinfo->comment.length);
 
509
    }
 
510
 
 
511
    keyinfo->name= strmake_root(&share->mem_root,
 
512
                                indx.name().c_str(),
 
513
                                indx.name().length());
 
514
 
 
515
    share->keynames.type_names[keynr]= keyinfo->name;
 
516
    share->keynames.type_lengths[keynr]= indx.name().length();
 
517
  }
 
518
 
 
519
  share->keys_for_keyread.reset();
 
520
  set_prefix(share->keys_in_use, share->keys);
 
521
 
 
522
  if (table_options.has_connect_string())
 
523
  {
 
524
    size_t len= table_options.connect_string().length();
 
525
    const char* str= table_options.connect_string().c_str();
 
526
 
 
527
    share->connect_string.length= len;
 
528
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
529
  }
 
530
 
 
531
  if (table_options.has_comment())
 
532
  {
 
533
    size_t len= table_options.comment().length();
 
534
    const char* str= table_options.comment().c_str();
 
535
 
 
536
    share->comment.length= len;
 
537
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
538
  }
 
539
 
 
540
  share->key_block_size= table_options.has_key_block_size() ?
 
541
    table_options.key_block_size() : 0;
 
542
 
 
543
  share->fields= table.field_size();
 
544
 
 
545
  share->field= (Field**) alloc_root(&share->mem_root,
 
546
                                     ((share->fields+1) * sizeof(Field*)));
 
547
  share->field[share->fields]= NULL;
 
548
 
 
549
  uint32_t null_fields= 0;
 
550
  share->reclength= 0;
 
551
 
 
552
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
 
553
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
 
554
 
 
555
  assert(field_offsets && field_pack_length); // TODO: fixme
 
556
 
 
557
  uint32_t interval_count= 0;
 
558
  uint32_t interval_parts= 0;
 
559
 
 
560
  uint32_t stored_columns_reclength= 0;
 
561
 
 
562
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
563
  {
 
564
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
565
    if (pfield.has_constraints() && pfield.constraints().is_nullable())
 
566
      null_fields++;
 
567
 
 
568
    enum_field_types drizzle_field_type=
 
569
      proto_field_type_to_drizzle_type(pfield.type());
 
570
 
 
571
    field_offsets[fieldnr]= stored_columns_reclength;
 
572
 
 
573
    /* the below switch is very similar to
 
574
       CreateField::create_length_to_internal_length in field.cc
 
575
       (which should one day be replace by just this code)
 
576
    */
 
577
    switch(drizzle_field_type)
 
578
    {
 
579
    case DRIZZLE_TYPE_BLOB:
 
580
    case DRIZZLE_TYPE_VARCHAR:
 
581
      {
 
582
        drizzled::message::Table::Field::StringFieldOptions field_options=
 
583
          pfield.string_options();
 
584
 
 
585
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
586
                                            field_options.collation_id() : 0);
 
587
 
 
588
        if (!cs)
 
589
          cs= default_charset_info;
 
590
 
 
591
        field_pack_length[fieldnr]=
 
592
          calc_pack_length(drizzle_field_type,
 
593
                           field_options.length() * cs->mbmaxlen);
 
594
 
 
595
      }
 
596
      break;
 
597
    case DRIZZLE_TYPE_ENUM:
 
598
      {
 
599
        drizzled::message::Table::Field::SetFieldOptions field_options=
 
600
          pfield.set_options();
 
601
 
 
602
        field_pack_length[fieldnr]=
 
603
          get_enum_pack_length(field_options.field_value_size());
 
604
 
 
605
        interval_count++;
 
606
        interval_parts+= field_options.field_value_size();
 
607
      }
 
608
      break;
 
609
    case DRIZZLE_TYPE_NEWDECIMAL:
 
610
      {
 
611
        drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
612
 
 
613
        field_pack_length[fieldnr]=
 
614
          my_decimal_get_binary_size(fo.precision(), fo.scale());
 
615
      }
 
616
      break;
 
617
    default:
 
618
      /* Zero is okay here as length is fixed for other types. */
 
619
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
 
620
    }
 
621
 
 
622
    share->reclength+= field_pack_length[fieldnr];
 
623
    stored_columns_reclength+= field_pack_length[fieldnr];
 
624
 
 
625
  }
 
626
 
 
627
  /* data_offset added to stored_rec_length later */
 
628
  share->stored_rec_length= stored_columns_reclength;
 
629
 
 
630
  share->null_fields= null_fields;
 
631
 
 
632
  ulong null_bits= null_fields;
 
633
  if (!table_options.pack_record())
 
634
    null_bits++;
 
635
  ulong data_offset= (null_bits + 7)/8;
 
636
 
 
637
 
 
638
  share->reclength+= data_offset;
 
639
  share->stored_rec_length+= data_offset;
 
640
 
 
641
  ulong rec_buff_length;
 
642
 
 
643
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
644
  share->rec_buff_length= rec_buff_length;
 
645
 
 
646
  unsigned char* record= NULL;
 
647
 
 
648
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
 
649
                                     rec_buff_length)))
 
650
    abort();
 
651
 
 
652
  memset(record, 0, rec_buff_length);
 
653
 
 
654
  int null_count= 0;
 
655
 
 
656
  if (!table_options.pack_record())
 
657
  {
 
658
    null_count++; // one bit for delete mark.
 
659
    *record|= 1;
 
660
  }
 
661
 
 
662
  share->default_values= record;
 
663
 
 
664
  if (interval_count)
 
665
  {
 
666
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
667
                                           interval_count*sizeof(TYPELIB));
 
668
  }
 
669
  else
 
670
    share->intervals= NULL;
 
671
 
 
672
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
673
                                  (share->fields+1)*sizeof(char*));
 
674
 
 
675
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
676
                                  (share->fields+1)*sizeof(unsigned int));
 
677
 
 
678
  share->fieldnames.type_names[share->fields]= NULL;
 
679
  share->fieldnames.type_lengths[share->fields]= 0;
 
680
  share->fieldnames.count= share->fields;
 
681
 
 
682
 
 
683
  /* Now fix the TYPELIBs for the intervals (enum values)
 
684
     and field names.
 
685
   */
 
686
 
 
687
  uint32_t interval_nr= 0;
 
688
 
 
689
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
690
  {
 
691
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
692
 
 
693
    /* field names */
 
694
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
 
695
                                                        pfield.name().c_str(),
 
696
                                                        pfield.name().length());
 
697
 
 
698
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
 
699
 
 
700
    /* enum typelibs */
 
701
    if (pfield.type() != drizzled::message::Table::Field::ENUM)
 
702
      continue;
 
703
 
 
704
    drizzled::message::Table::Field::SetFieldOptions field_options=
 
705
      pfield.set_options();
 
706
 
 
707
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
708
                                             field_options.collation_id() : 0);
 
709
 
 
710
    if (!charset)
 
711
      charset= default_charset_info;
 
712
 
 
713
    TYPELIB *t= &(share->intervals[interval_nr]);
 
714
 
 
715
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
716
                           (field_options.field_value_size()+1)*sizeof(char*));
 
717
 
 
718
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
719
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
 
720
 
 
721
    t->type_names[field_options.field_value_size()]= NULL;
 
722
    t->type_lengths[field_options.field_value_size()]= 0;
 
723
 
 
724
    t->count= field_options.field_value_size();
 
725
    t->name= NULL;
 
726
 
 
727
    for (int n= 0; n < field_options.field_value_size(); n++)
 
728
    {
 
729
      t->type_names[n]= strmake_root(&share->mem_root,
 
730
                                     field_options.field_value(n).c_str(),
 
731
                                     field_options.field_value(n).length());
 
732
 
 
733
      /* Go ask the charset what the length is as for "" length=1
 
734
         and there's stripping spaces or some other crack going on.
 
735
       */
 
736
      uint32_t lengthsp;
 
737
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
738
                                        field_options.field_value(n).length());
 
739
      t->type_lengths[n]= lengthsp;
 
740
    }
 
741
    interval_nr++;
 
742
  }
 
743
 
 
744
 
 
745
  /* and read the fields */
 
746
  interval_nr= 0;
 
747
 
 
748
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
749
 
 
750
  if (use_hash)
 
751
    use_hash= !hash_init(&share->name_hash,
 
752
                         system_charset_info,
 
753
                         share->fields, 0, 0,
 
754
                         (hash_get_key) get_field_name, 0, 0);
 
755
 
 
756
  unsigned char* null_pos= record;;
 
757
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
 
758
 
 
759
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
760
  {
 
761
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
762
 
 
763
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
764
 
 
765
    switch(pfield.format())
 
766
    {
 
767
    case drizzled::message::Table::Field::DefaultFormat:
 
768
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
769
      break;
 
770
    case drizzled::message::Table::Field::FixedFormat:
 
771
      column_format= COLUMN_FORMAT_TYPE_FIXED;
 
772
      break;
 
773
    case drizzled::message::Table::Field::DynamicFormat:
 
774
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
 
775
      break;
 
776
    default:
 
777
      assert(1);
 
778
    }
 
779
 
 
780
    Field::utype unireg_type= Field::NONE;
 
781
 
 
782
    if (pfield.has_numeric_options()
 
783
       && pfield.numeric_options().is_autoincrement())
 
784
    {
 
785
      unireg_type= Field::NEXT_NUMBER;
 
786
    }
 
787
 
 
788
    if (pfield.has_options()
 
789
       && pfield.options().has_default_value()
 
790
       && pfield.options().default_value().compare("NOW()") == 0)
 
791
    {
 
792
      if (pfield.options().has_update_value()
 
793
         && pfield.options().update_value().compare("NOW()") == 0)
 
794
      {
 
795
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
796
      }
 
797
      else if (!pfield.options().has_update_value())
 
798
      {
 
799
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
800
      }
 
801
      else
 
802
        assert(1); // Invalid update value.
 
803
    }
 
804
    else if (pfield.has_options()
 
805
             && pfield.options().has_update_value()
 
806
             && pfield.options().update_value().compare("NOW()") == 0)
 
807
    {
 
808
      unireg_type= Field::TIMESTAMP_UN_FIELD;
 
809
    }
 
810
 
 
811
    LEX_STRING comment;
 
812
    if (!pfield.has_comment())
 
813
    {
 
814
      comment.str= (char*)"";
 
815
      comment.length= 0;
 
816
    }
 
817
    else
 
818
    {
 
819
      size_t len= pfield.comment().length();
 
820
      const char* str= pfield.comment().c_str();
 
821
 
 
822
      comment.str= strmake_root(&share->mem_root, str, len);
 
823
      comment.length= len;
 
824
    }
 
825
 
 
826
    enum_field_types field_type;
 
827
 
 
828
    field_type= proto_field_type_to_drizzle_type(pfield.type());
 
829
 
 
830
    const CHARSET_INFO *charset= &my_charset_bin;
 
831
 
 
832
    if (field_type==DRIZZLE_TYPE_BLOB
 
833
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
834
    {
 
835
      drizzled::message::Table::Field::StringFieldOptions field_options=
 
836
        pfield.string_options();
 
837
 
 
838
      charset= get_charset(field_options.has_collation_id()?
 
839
                           field_options.collation_id() : 0);
 
840
 
 
841
      if (!charset)
 
842
        charset= default_charset_info;
 
843
 
 
844
    }
 
845
 
 
846
    if (field_type==DRIZZLE_TYPE_ENUM)
 
847
    {
 
848
      drizzled::message::Table::Field::SetFieldOptions field_options=
 
849
        pfield.set_options();
 
850
 
 
851
      charset= get_charset(field_options.has_collation_id()?
 
852
                           field_options.collation_id() : 0);
 
853
 
 
854
      if (!charset)
 
855
        charset= default_charset_info;
 
856
 
 
857
    }
 
858
 
 
859
    Item *default_value= NULL;
 
860
 
 
861
    if (pfield.options().has_default_value()
 
862
       || pfield.options().has_default_null()
 
863
       || pfield.options().has_default_bin_value())
 
864
    {
 
865
      default_value= default_value_item(field_type,
 
866
                                        charset,
 
867
                                        pfield.options().default_null(),
 
868
                                        &pfield.options().default_value(),
 
869
                                        &pfield.options().default_bin_value());
 
870
    }
 
871
 
 
872
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
 
873
 
 
874
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
875
    memset(&temp_table, 0, sizeof(temp_table));
 
876
    temp_table.s= share;
 
877
    temp_table.in_use= session;
 
878
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
 
879
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
880
 
 
881
    Field* f= make_field(share, &share->mem_root,
 
882
                         record+field_offsets[fieldnr]+data_offset,
 
883
                         pfield.options().length(),
 
884
                         null_pos,
 
885
                         null_bit_pos,
 
886
                         pack_flag,
 
887
                         field_type,
 
888
                         charset,
 
889
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
890
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
891
                         share->intervals+(interval_nr++)
 
892
                         : (TYPELIB*) 0),
 
893
                        share->fieldnames.type_names[fieldnr]);
 
894
 
 
895
    share->field[fieldnr]= f;
 
896
 
 
897
    f->init(&temp_table); /* blob default values need table obj */
 
898
 
 
899
    if (!(f->flags & NOT_NULL_FLAG))
 
900
    {
 
901
      *f->null_ptr|= f->null_bit;
 
902
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
 
903
        null_pos++;
 
904
      null_count++;
 
905
    }
 
906
 
 
907
    if (default_value)
 
908
    {
 
909
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
910
      session->count_cuted_fields= CHECK_FIELD_WARN;
 
911
      int res= default_value->save_in_field(f, 1);
 
912
      session->count_cuted_fields= old_count_cuted_fields;
 
913
      if (res != 0 && res != 3)
 
914
      {
 
915
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
 
916
        error= 1;
 
917
        goto err;
 
918
      }
 
919
    }
 
920
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
 
921
            (f->flags & NOT_NULL_FLAG))
 
922
    {
 
923
      f->set_notnull();
 
924
      f->store((int64_t) 1, true);
 
925
    }
 
926
    else
 
927
      f->reset();
 
928
 
 
929
    /* hack to undo f->init() */
 
930
    f->table= NULL;
 
931
    f->orig_table= NULL;
 
932
 
 
933
    f->field_index= fieldnr;
 
934
    f->comment= comment;
 
935
    if (!default_value
 
936
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
937
       && (f->flags & NOT_NULL_FLAG)
 
938
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
 
939
      f->flags|= NO_DEFAULT_VALUE_FLAG;
 
940
 
 
941
    if (f->unireg_check == Field::NEXT_NUMBER)
 
942
      share->found_next_number_field= &(share->field[fieldnr]);
 
943
 
 
944
    if (share->timestamp_field == f)
 
945
      share->timestamp_field_offset= fieldnr;
 
946
 
 
947
    if (use_hash) /* supposedly this never fails... but comments lie */
 
948
      (void) my_hash_insert(&share->name_hash,
 
949
                            (unsigned char*)&(share->field[fieldnr]));
 
950
 
 
951
  }
 
952
 
 
953
  keyinfo= share->key_info;
 
954
  for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
 
955
  {
 
956
    key_part= keyinfo->key_part;
 
957
 
 
958
    for (unsigned int partnr= 0;
 
959
         partnr < keyinfo->key_parts;
 
960
         partnr++, key_part++)
 
961
    {
 
962
      /* Fix up key_part->offset by adding data_offset.
 
963
         We really should compute offset as well.
 
964
         But at least this way we are a little better. */
 
965
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
966
    }
 
967
  }
 
968
 
 
969
  /*
 
970
    We need to set the unused bits to 1. If the number of bits is a multiple
 
971
    of 8 there are no unused bits.
 
972
  */
 
973
 
 
974
  if (null_count & 7)
 
975
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
976
 
 
977
  share->null_bytes= (null_pos - (unsigned char*) record +
 
978
                      (null_bit_pos + 7) / 8);
 
979
 
 
980
  share->last_null_bit_pos= null_bit_pos;
 
981
 
 
982
  free(field_offsets);
 
983
  free(field_pack_length);
 
984
 
 
985
  if (!(handler_file= get_new_handler(share, session->mem_root,
 
986
                                     share->db_type())))
 
987
    abort(); // FIXME
 
988
 
 
989
  /* Fix key stuff */
 
990
  if (share->key_parts)
 
991
  {
 
992
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
 
993
                                       &share->keynames, 3) - 1);
 
994
 
 
995
    int64_t ha_option= handler_file->ha_table_flags();
 
996
 
 
997
    keyinfo= share->key_info;
 
998
    key_part= keyinfo->key_part;
 
999
 
 
1000
    for (uint32_t key= 0 ; key < share->keys ; key++,keyinfo++)
 
1001
    {
 
1002
      uint32_t usable_parts= 0;
 
1003
 
 
1004
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
 
1005
      {
 
1006
        /*
 
1007
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
1008
          declare this as a primary key.
 
1009
        */
 
1010
        primary_key=key;
 
1011
        for (uint32_t i= 0 ; i < keyinfo->key_parts ;i++)
 
1012
        {
 
1013
          uint32_t fieldnr= key_part[i].fieldnr;
 
1014
          if (!fieldnr ||
 
1015
              share->field[fieldnr-1]->null_ptr ||
 
1016
              share->field[fieldnr-1]->key_length() !=
 
1017
              key_part[i].length)
 
1018
          {
 
1019
            primary_key=MAX_KEY;                // Can't be used
 
1020
            break;
 
1021
          }
 
1022
        }
 
1023
      }
 
1024
 
 
1025
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1026
      {
 
1027
        Field *field;
 
1028
        if (!key_part->fieldnr)
 
1029
        {
 
1030
//          error= 4;                             // Wrong file
 
1031
          abort(); // goto err;
 
1032
        }
 
1033
        field= key_part->field= share->field[key_part->fieldnr-1];
 
1034
        key_part->type= field->key_type();
 
1035
        if (field->null_ptr)
 
1036
        {
 
1037
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
 
1038
                                        share->default_values);
 
1039
          key_part->null_bit= field->null_bit;
 
1040
          key_part->store_length+=HA_KEY_NULL_LENGTH;
 
1041
          keyinfo->flags|=HA_NULL_PART_KEY;
 
1042
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
 
1043
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
 
1044
        }
 
1045
        if (field->type() == DRIZZLE_TYPE_BLOB ||
 
1046
            field->real_type() == DRIZZLE_TYPE_VARCHAR)
 
1047
        {
 
1048
          if (field->type() == DRIZZLE_TYPE_BLOB)
 
1049
            key_part->key_part_flag|= HA_BLOB_PART;
 
1050
          else
 
1051
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
 
1052
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
 
1053
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
 
1054
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
 
1055
        }
 
1056
        if (i == 0 && key != primary_key)
 
1057
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
 
1058
                           (keyinfo->key_parts == 1)) ?
 
1059
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
 
1060
        if (i == 0)
 
1061
          field->key_start.set(key);
 
1062
        if (field->key_length() == key_part->length &&
 
1063
            !(field->flags & BLOB_FLAG))
 
1064
        {
 
1065
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
 
1066
          {
 
1067
            share->keys_for_keyread.set(key);
 
1068
            field->part_of_key.set(key);
 
1069
            field->part_of_key_not_clustered.set(key);
 
1070
          }
 
1071
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
 
1072
            field->part_of_sortkey.set(key);
 
1073
        }
 
1074
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
 
1075
            usable_parts == i)
 
1076
          usable_parts++;                       // For FILESORT
 
1077
        field->flags|= PART_KEY_FLAG;
 
1078
        if (key == primary_key)
 
1079
        {
 
1080
          field->flags|= PRI_KEY_FLAG;
 
1081
          /*
 
1082
            If this field is part of the primary key and all keys contains
 
1083
            the primary key, then we can use any key to find this column
 
1084
          */
 
1085
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
 
1086
          {
 
1087
            field->part_of_key= share->keys_in_use;
 
1088
            if (field->part_of_sortkey.test(key))
 
1089
              field->part_of_sortkey= share->keys_in_use;
 
1090
          }
 
1091
        }
 
1092
        if (field->key_length() != key_part->length)
 
1093
        {
 
1094
          key_part->key_part_flag|= HA_PART_KEY_SEG;
 
1095
        }
 
1096
      }
 
1097
      keyinfo->usable_key_parts= usable_parts; // Filesort
 
1098
 
 
1099
      set_if_bigger(share->max_key_length,keyinfo->key_length+
 
1100
                    keyinfo->key_parts);
 
1101
      share->total_key_length+= keyinfo->key_length;
 
1102
      /*
 
1103
        MERGE tables do not have unique indexes. But every key could be
 
1104
        an unique index on the underlying MyISAM table. (Bug #10400)
 
1105
      */
 
1106
      if ((keyinfo->flags & HA_NOSAME) ||
 
1107
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
 
1108
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
 
1109
    }
 
1110
    if (primary_key < MAX_KEY &&
 
1111
        (share->keys_in_use.test(primary_key)))
 
1112
    {
 
1113
      share->primary_key= primary_key;
 
1114
      /*
 
1115
        If we are using an integer as the primary key then allow the user to
 
1116
        refer to it as '_rowid'
 
1117
      */
 
1118
      if (share->key_info[primary_key].key_parts == 1)
 
1119
      {
 
1120
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1121
        if (field && field->result_type() == INT_RESULT)
 
1122
        {
 
1123
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
 
1124
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1125
                                      fieldnr);
 
1126
        }
 
1127
      }
 
1128
 
 
1129
    }
 
1130
    else
 
1131
      share->primary_key = MAX_KEY; // we do not have a primary key
 
1132
  }
 
1133
  else
 
1134
    share->primary_key= MAX_KEY;
 
1135
 
 
1136
  if (share->found_next_number_field)
 
1137
  {
 
1138
    Field *reg_field= *share->found_next_number_field;
 
1139
    if ((int) (share->next_number_index= (uint32_t)
 
1140
               find_ref_key(share->key_info, share->keys,
 
1141
                            share->default_values, reg_field,
 
1142
                            &share->next_number_key_offset,
 
1143
                            &share->next_number_keypart)) < 0)
 
1144
    {
 
1145
      /* Wrong field definition */
 
1146
      error= 4;
 
1147
      goto err;
 
1148
    }
 
1149
    else
 
1150
      reg_field->flags |= AUTO_INCREMENT_FLAG;
 
1151
  }
 
1152
 
 
1153
  if (share->blob_fields)
 
1154
  {
 
1155
    Field **ptr;
 
1156
    uint32_t k, *save;
 
1157
 
 
1158
    /* Store offsets to blob fields to find them fast */
 
1159
    if (!(share->blob_field= save=
 
1160
          (uint*) alloc_root(&share->mem_root,
 
1161
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
 
1162
      goto err;
 
1163
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
 
1164
    {
 
1165
      if ((*ptr)->flags & BLOB_FLAG)
 
1166
        (*save++)= k;
 
1167
    }
 
1168
  }
 
1169
 
 
1170
  share->db_low_byte_first= handler_file->low_byte_first();
 
1171
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
 
1172
 
 
1173
  my_bitmap_map *bitmaps;
 
1174
 
 
1175
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
 
1176
                                             share->column_bitmap_size)))
 
1177
    goto err;
 
1178
  bitmap_init(&share->all_set, bitmaps, share->fields);
 
1179
  bitmap_set_all(&share->all_set);
 
1180
 
 
1181
  if (handler_file)
 
1182
    delete handler_file;
 
1183
  return (0);
 
1184
 
 
1185
err:
 
1186
  share->error= error;
 
1187
  share->open_errno= my_errno;
 
1188
  share->errarg= 0;
 
1189
  hash_free(&share->name_hash);
 
1190
  if (handler_file)
 
1191
    delete handler_file;
 
1192
  share->open_table_error(error, share->open_errno, 0);
 
1193
 
 
1194
  return error;
 
1195
}
 
1196
 
 
1197
/*
 
1198
  Read table definition from a binary / text based .frm file
 
1199
 
 
1200
  SYNOPSIS
 
1201
  open_table_def()
 
1202
  session               Thread handler
 
1203
  share         Fill this with table definition
 
1204
 
 
1205
  NOTES
 
1206
    This function is called when the table definition is not cached in
 
1207
    table_def_cache
 
1208
    The data is returned in 'share', which is alloced by
 
1209
    alloc_table_share().. The code assumes that share is initialized.
 
1210
 
 
1211
  RETURN VALUES
 
1212
   0    ok
 
1213
   1    Error (see open_table_error)
 
1214
   2    Error (see open_table_error)
 
1215
   3    Wrong data in .frm file
 
1216
   4    Error (see open_table_error)
 
1217
   5    Error (see open_table_error: charset unavailable)
 
1218
   6    Unknown .frm version
 
1219
*/
 
1220
 
 
1221
int open_table_def(Session *session, TableShare *share)
 
1222
{
 
1223
  int error;
 
1224
  bool error_given;
 
1225
 
 
1226
  error= 1;
 
1227
  error_given= 0;
 
1228
 
 
1229
  drizzled::message::Table table;
 
1230
 
 
1231
  error= StorageEngine::getTableProto(share->normalized_path.str, &table);
 
1232
 
 
1233
  if (error != EEXIST)
 
1234
  {
 
1235
    if (error>0)
 
1236
    {
 
1237
      my_errno= error;
 
1238
      error= 1;
 
1239
    }
 
1240
    else
 
1241
    {
 
1242
      if (!table.IsInitialized())
 
1243
      {
 
1244
        error= 4;
 
1245
      }
 
1246
    }
 
1247
    goto err_not_open;
 
1248
  }
 
1249
 
 
1250
  error= parse_table_proto(session, table, share);
 
1251
 
 
1252
  share->table_category= get_table_category(& share->db);
 
1253
 
 
1254
  if (!error)
 
1255
    session->status_var.opened_shares++;
 
1256
 
 
1257
err_not_open:
 
1258
  if (error && !error_given)
 
1259
  {
 
1260
    share->error= error;
 
1261
    share->open_table_error(error, (share->open_errno= my_errno), 0);
 
1262
  }
 
1263
 
 
1264
  return(error);
 
1265
}
 
1266
 
 
1267
 
 
1268
/*
 
1269
  Open a table based on a TableShare
 
1270
 
 
1271
  SYNOPSIS
 
1272
    open_table_from_share()
 
1273
    session                     Thread handler
 
1274
    share               Table definition
 
1275
    alias               Alias for table
 
1276
    db_stat             open flags (for example HA_OPEN_KEYFILE|
 
1277
                        HA_OPEN_RNDFILE..) can be 0 (example in
 
1278
                        ha_example_table)
 
1279
    prgflag             READ_ALL etc..
 
1280
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
 
1281
    outparam            result table
 
1282
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
 
1283
                        if OTM_CREATE some errors are ignore
 
1284
                        if OTM_ALTER HA_OPEN is not called
 
1285
 
 
1286
  RETURN VALUES
 
1287
   0    ok
 
1288
   1    Error (see open_table_error)
 
1289
   2    Error (see open_table_error)
 
1290
   3    Wrong data in .frm file
 
1291
   4    Error (see open_table_error)
 
1292
   5    Error (see open_table_error: charset unavailable)
 
1293
   7    Table definition has changed in engine
 
1294
*/
 
1295
 
 
1296
int open_table_from_share(Session *session, TableShare *share, const char *alias,
 
1297
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
 
1298
                          Table *outparam, open_table_mode open_mode)
 
1299
{
 
1300
  int error;
 
1301
  uint32_t records, i, bitmap_size;
 
1302
  bool error_reported= false;
 
1303
  unsigned char *record, *bitmaps;
 
1304
  Field **field_ptr;
 
1305
 
 
1306
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1307
  assert(session->lex->is_lex_started);
 
1308
 
 
1309
  error= 1;
 
1310
  outparam->resetTable(session, share, db_stat);
 
1311
 
 
1312
 
 
1313
  if (!(outparam->alias= strdup(alias)))
 
1314
    goto err;
 
1315
 
 
1316
  /* Allocate handler */
 
1317
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
 
1318
  {
 
1319
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
 
1320
                                          share->db_type())))
 
1321
      goto err;
 
1322
  }
 
1323
  else
 
1324
  {
 
1325
    assert(!db_stat);
 
1326
  }
 
1327
 
 
1328
  error= 4;
 
1329
  records= 0;
 
1330
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
 
1331
    records=1;
 
1332
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
1333
    records++;
 
1334
 
 
1335
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
 
1336
                                   share->rec_buff_length * records)))
 
1337
    goto err;                                   /* purecov: inspected */
 
1338
 
 
1339
  if (records == 0)
 
1340
  {
 
1341
    /* We are probably in hard repair, and the buffers should not be used */
 
1342
    outparam->record[0]= outparam->record[1]= share->default_values;
 
1343
  }
 
1344
  else
 
1345
  {
 
1346
    outparam->record[0]= record;
 
1347
    if (records > 1)
 
1348
      outparam->record[1]= record+ share->rec_buff_length;
 
1349
    else
 
1350
      outparam->record[1]= outparam->record[0];   // Safety
 
1351
  }
 
1352
 
 
1353
#ifdef HAVE_purify
 
1354
  /*
 
1355
    We need this because when we read var-length rows, we are not updating
 
1356
    bytes after end of varchar
 
1357
  */
 
1358
  if (records > 1)
 
1359
  {
 
1360
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
 
1361
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
 
1362
    if (records > 2)
 
1363
      memcpy(outparam->record[1], share->default_values,
 
1364
             share->rec_buff_length);
 
1365
  }
 
1366
#endif
 
1367
 
 
1368
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1369
                                          (uint32_t) ((share->fields+1)*
 
1370
                                                  sizeof(Field*)))))
 
1371
    goto err;                                   /* purecov: inspected */
 
1372
 
 
1373
  outparam->field= field_ptr;
 
1374
 
 
1375
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
 
1376
 
 
1377
  outparam->null_flags= (unsigned char*) record+1;
 
1378
 
 
1379
  /* Setup copy of fields from share, but use the right alias and record */
 
1380
  for (i= 0 ; i < share->fields; i++, field_ptr++)
 
1381
  {
 
1382
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
 
1383
      goto err;
 
1384
  }
 
1385
  (*field_ptr)= 0;                              // End marker
 
1386
 
 
1387
  if (share->found_next_number_field)
 
1388
    outparam->found_next_number_field=
 
1389
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
 
1390
  if (share->timestamp_field)
 
1391
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
 
1392
 
 
1393
 
 
1394
  /* Fix key->name and key_part->field */
 
1395
  if (share->key_parts)
 
1396
  {
 
1397
    KEY *key_info, *key_info_end;
 
1398
    KEY_PART_INFO *key_part;
 
1399
    uint32_t n_length;
 
1400
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
 
1401
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
 
1402
      goto err;
 
1403
    outparam->key_info= key_info;
 
1404
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
 
1405
 
 
1406
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
 
1407
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
 
1408
                                                   share->key_parts));
 
1409
 
 
1410
    for (key_info_end= key_info + share->keys ;
 
1411
         key_info < key_info_end ;
 
1412
         key_info++)
 
1413
    {
 
1414
      KEY_PART_INFO *key_part_end;
 
1415
 
 
1416
      key_info->table= outparam;
 
1417
      key_info->key_part= key_part;
 
1418
 
 
1419
      for (key_part_end= key_part+ key_info->key_parts ;
 
1420
           key_part < key_part_end ;
 
1421
           key_part++)
 
1422
      {
 
1423
        Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
 
1424
 
 
1425
        if (field->key_length() != key_part->length &&
 
1426
            !(field->flags & BLOB_FLAG))
 
1427
        {
 
1428
          /*
 
1429
            We are using only a prefix of the column as a key:
 
1430
            Create a new field for the key part that matches the index
 
1431
          */
 
1432
          field= key_part->field=field->new_field(&outparam->mem_root,
 
1433
                                                  outparam, 0);
 
1434
          field->field_length= key_part->length;
 
1435
        }
 
1436
      }
 
1437
    }
 
1438
  }
 
1439
 
 
1440
  /* Allocate bitmaps */
 
1441
 
 
1442
  bitmap_size= share->column_bitmap_size;
 
1443
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
 
1444
    goto err;
 
1445
  bitmap_init(&outparam->def_read_set,
 
1446
              (my_bitmap_map*) bitmaps, share->fields);
 
1447
  bitmap_init(&outparam->def_write_set,
 
1448
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
 
1449
  bitmap_init(&outparam->tmp_set,
 
1450
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
 
1451
  outparam->default_column_bitmaps();
 
1452
 
 
1453
  /* The table struct is now initialized;  Open the table */
 
1454
  error= 2;
 
1455
  if (db_stat && open_mode != OTM_ALTER)
 
1456
  {
 
1457
    int ha_err;
 
1458
    if ((ha_err= (outparam->file->
 
1459
                  ha_open(outparam, share->normalized_path.str,
 
1460
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
 
1461
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
 
1462
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
 
1463
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
 
1464
                          HA_OPEN_ABORT_IF_LOCKED :
 
1465
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
 
1466
    {
 
1467
      /* Set a flag if the table is crashed and it can be auto. repaired */
 
1468
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
 
1469
                       outparam->file->auto_repair() &&
 
1470
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
 
1471
 
 
1472
      switch (ha_err)
 
1473
      {
 
1474
        case HA_ERR_NO_SUCH_TABLE:
 
1475
          /*
 
1476
            The table did not exists in storage engine, use same error message
 
1477
            as if the .frm file didn't exist
 
1478
          */
 
1479
          error= 1;
 
1480
          my_errno= ENOENT;
 
1481
          break;
 
1482
        case EMFILE:
 
1483
          /*
 
1484
            Too many files opened, use same error message as if the .frm
 
1485
            file can't open
 
1486
           */
 
1487
          error= 1;
 
1488
          my_errno= EMFILE;
 
1489
          break;
 
1490
        default:
 
1491
          outparam->file->print_error(ha_err, MYF(0));
 
1492
          error_reported= true;
 
1493
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
 
1494
            error= 7;
 
1495
          break;
 
1496
      }
 
1497
      goto err;                                 /* purecov: inspected */
 
1498
    }
 
1499
  }
 
1500
 
 
1501
#if defined(HAVE_purify)
 
1502
  memset(bitmaps, 0, bitmap_size*3);
 
1503
#endif
 
1504
 
 
1505
  session->status_var.opened_tables++;
 
1506
 
 
1507
  return (0);
 
1508
 
 
1509
 err:
 
1510
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
 
1511
    share->open_table_error(error, my_errno, 0);
 
1512
  delete outparam->file;
 
1513
  outparam->file= 0;                            // For easier error checking
 
1514
  outparam->db_stat= 0;
 
1515
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
 
1516
  free((char*) outparam->alias);
 
1517
  return (error);
 
1518
}
 
1519
 
 
1520
/*
 
1521
  Free information allocated by openfrm
 
1522
 
 
1523
  SYNOPSIS
 
1524
    closefrm()
 
1525
    table               Table object to free
 
1526
    free_share          Is 1 if we also want to free table_share
 
1527
*/
 
1528
 
 
1529
int Table::closefrm(bool free_share)
78
1530
{
79
1531
  int error= 0;
80
1532
 
81
1533
  if (db_stat)
82
 
    error= cursor->close();
83
 
  _alias.clear();
84
 
 
 
1534
    error= file->close();
 
1535
  free((char*) alias);
 
1536
  alias= NULL;
85
1537
  if (field)
86
1538
  {
87
1539
    for (Field **ptr=field ; *ptr ; ptr++)
88
 
    {
89
1540
      delete *ptr;
90
 
    }
91
1541
    field= 0;
92
1542
  }
93
 
  delete cursor;
94
 
  cursor= 0;                            /* For easier errorchecking */
95
 
 
 
1543
  delete file;
 
1544
  file= 0;                              /* For easier errorchecking */
96
1545
  if (free_share)
97
1546
  {
98
 
    release();
 
1547
    if (s->tmp_table == NO_TMP_TABLE)
 
1548
      TableShare::release(s);
 
1549
    else
 
1550
      s->free_table_share();
99
1551
  }
 
1552
  free_root(&mem_root, MYF(0));
100
1553
 
101
1554
  return error;
102
1555
}
103
1556
 
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
1557
 
198
1558
/* Deallocate temporary blob storage */
199
1559
 
203
1563
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
204
1564
       ptr != end ;
205
1565
       ptr++)
206
 
  {
207
 
    ((Field_blob*) table->getField(*ptr))->free();
208
 
  }
 
1566
    ((Field_blob*) table->field[*ptr])->free();
209
1567
}
210
1568
 
211
1569
 
212
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
213
 
{
214
 
  TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
 
1570
        /* error message when opening a form file */
 
1571
 
 
1572
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
 
1573
{
 
1574
  int err_no;
 
1575
  char buff[FN_REFLEN];
 
1576
  myf errortype= ME_ERROR+ME_WAITTANG;
 
1577
 
 
1578
  switch (pass_error) {
 
1579
  case 7:
 
1580
  case 1:
 
1581
    if (db_errno == ENOENT)
 
1582
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
 
1583
    else
 
1584
    {
 
1585
      sprintf(buff,"%s",normalized_path.str);
 
1586
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
 
1587
               errortype, buff, db_errno);
 
1588
    }
 
1589
    break;
 
1590
  case 2:
 
1591
  {
 
1592
    handler *file= 0;
 
1593
    const char *datext= "";
 
1594
 
 
1595
    if (db_type() != NULL)
 
1596
    {
 
1597
      if ((file= get_new_handler(this, current_session->mem_root,
 
1598
                                 db_type())))
 
1599
      {
 
1600
        if (!(datext= *db_type()->bas_ext()))
 
1601
          datext= "";
 
1602
      }
 
1603
    }
 
1604
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
 
1605
      ER_FILE_USED : ER_CANT_OPEN_FILE;
 
1606
    sprintf(buff,"%s%s", normalized_path.str,datext);
 
1607
    my_error(err_no,errortype, buff, db_errno);
 
1608
    delete file;
 
1609
    break;
 
1610
  }
 
1611
  case 5:
 
1612
  {
 
1613
    const char *csname= get_charset_name((uint32_t) pass_errarg);
 
1614
    char tmp[10];
 
1615
    if (!csname || csname[0] =='?')
 
1616
    {
 
1617
      snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
 
1618
      csname= tmp;
 
1619
    }
 
1620
    my_printf_error(ER_UNKNOWN_COLLATION,
 
1621
                    _("Unknown collation '%s' in table '%-.64s' definition"),
 
1622
                    MYF(0), csname, table_name.str);
 
1623
    break;
 
1624
  }
 
1625
  case 6:
 
1626
    sprintf(buff,"%s", normalized_path.str);
 
1627
    my_printf_error(ER_NOT_FORM_FILE,
 
1628
                    _("Table '%-.64s' was created with a different version "
 
1629
                    "of Drizzle and cannot be read"),
 
1630
                    MYF(0), buff);
 
1631
    break;
 
1632
  case 8:
 
1633
    break;
 
1634
  default:                              /* Better wrong error than none */
 
1635
  case 4:
 
1636
    sprintf(buff,"%s", normalized_path.str);
 
1637
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
 
1638
    break;
 
1639
  }
 
1640
  return;
 
1641
} /* open_table_error */
 
1642
 
 
1643
 
 
1644
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
 
1645
{
 
1646
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
215
1647
  if (!result)
216
1648
    return 0;
217
1649
  result->count= strings.elements;
218
1650
  result->name= "";
219
1651
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
220
1652
  
221
 
  if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
 
1653
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
222
1654
    return 0;
223
1655
    
224
1656
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
248
1680
  return (nr);
249
1681
} /* set_zone */
250
1682
 
 
1683
        /* Adjust number to next larger disk buffer */
 
1684
 
 
1685
ulong next_io_size(register ulong pos)
 
1686
{
 
1687
  register ulong offset;
 
1688
  if ((offset= pos & (IO_SIZE-1)))
 
1689
    return pos-offset+IO_SIZE;
 
1690
  return pos;
 
1691
} /* next_io_size */
 
1692
 
251
1693
 
252
1694
/*
253
1695
  Store an SQL quoted string.
275
1717
        (mblen= my_ismbchar(default_charset_info, pos, end)))
276
1718
    {
277
1719
      res->append(pos, mblen);
278
 
      pos+= mblen - 1;
 
1720
      pos+= mblen;
279
1721
      if (pos >= end)
280
1722
        break;
281
1723
      continue;
311
1753
}
312
1754
 
313
1755
 
 
1756
/*
 
1757
  Set up column usage bitmaps for a temporary table
 
1758
 
 
1759
  IMPLEMENTATION
 
1760
    For temporary tables, we need one bitmap with all columns set and
 
1761
    a tmp_set bitmap to be used by things like filesort.
 
1762
*/
 
1763
 
 
1764
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
1765
{
 
1766
  uint32_t field_count= s->fields;
 
1767
 
 
1768
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count);
 
1769
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
 
1770
 
 
1771
  /* write_set and all_set are copies of read_set */
 
1772
  def_write_set= def_read_set;
 
1773
  s->all_set= def_read_set;
 
1774
  bitmap_set_all(&this->s->all_set);
 
1775
  default_column_bitmaps();
 
1776
}
 
1777
 
 
1778
 
 
1779
 
 
1780
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
 
1781
{
 
1782
  create_info->max_rows= s->max_rows;
 
1783
  create_info->min_rows= s->min_rows;
 
1784
  create_info->table_options= s->db_create_options;
 
1785
  create_info->avg_row_length= s->avg_row_length;
 
1786
  create_info->block_size= s->block_size;
 
1787
  create_info->row_type= s->row_type;
 
1788
  create_info->default_table_charset= s->table_charset;
 
1789
  create_info->table_charset= 0;
 
1790
  create_info->comment= s->comment;
 
1791
 
 
1792
  return;
 
1793
}
 
1794
 
314
1795
int rename_file_ext(const char * from,const char * to,const char * ext)
315
1796
{
316
1797
  string from_s, to_s;
319
1800
  from_s.append(ext);
320
1801
  to_s.append(to);
321
1802
  to_s.append(ext);
322
 
  return (internal::my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
1803
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
1804
}
 
1805
 
 
1806
/*
 
1807
  DESCRIPTION
 
1808
    given a buffer with a key value, and a map of keyparts
 
1809
    that are present in this value, returns the length of the value
 
1810
*/
 
1811
uint32_t calculate_key_len(Table *table, uint32_t key,
 
1812
                       const unsigned char *,
 
1813
                       key_part_map keypart_map)
 
1814
{
 
1815
  /* works only with key prefixes */
 
1816
  assert(((keypart_map + 1) & keypart_map) == 0);
 
1817
 
 
1818
  KEY *key_info= table->s->key_info+key;
 
1819
  KEY_PART_INFO *key_part= key_info->key_part;
 
1820
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
 
1821
  uint32_t length= 0;
 
1822
 
 
1823
  while (key_part < end_key_part && keypart_map)
 
1824
  {
 
1825
    length+= key_part->store_length;
 
1826
    keypart_map >>= 1;
 
1827
    key_part++;
 
1828
  }
 
1829
  return length;
323
1830
}
324
1831
 
325
1832
/*
330
1837
    org_name            Name of database and length
331
1838
 
332
1839
  RETURN
333
 
    false error
334
 
    true ok
 
1840
    0   ok
 
1841
    1   error
335
1842
*/
336
1843
 
337
 
bool check_db_name(Session *session, identifier::Schema &schema_identifier)
 
1844
bool check_db_name(LEX_STRING *org_name)
338
1845
{
339
 
  if (not plugin::Authorization::isAuthorized(session->user(), schema_identifier))
340
 
  {
341
 
    return false;
342
 
  }
343
 
 
344
 
  return schema_identifier.isValid();
 
1846
  char *name= org_name->str;
 
1847
  uint32_t name_length= org_name->length;
 
1848
 
 
1849
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
 
1850
    return 1;
 
1851
 
 
1852
  if (name != any_db)
 
1853
    my_casedn_str(files_charset_info, name);
 
1854
 
 
1855
  return check_identifier_name(org_name);
345
1856
}
346
1857
 
 
1858
 
347
1859
/*
348
1860
  Allow anything as a table name, as long as it doesn't contain an
349
1861
  ' ' at the end
414
1926
    bitmap_clear_all(&table->def_read_set);
415
1927
    bitmap_clear_all(&table->def_write_set);
416
1928
  */
417
 
  def_read_set.reset();
418
 
  def_write_set.reset();
419
 
  column_bitmaps_set(def_read_set, def_write_set);
 
1929
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
 
1930
  column_bitmaps_set(&def_read_set, &def_write_set);
420
1931
}
421
1932
 
422
1933
 
423
1934
/*
424
 
  Tell Cursor we are going to call position() and rnd_pos() later.
 
1935
  Tell handler we are going to call position() and rnd_pos() later.
425
1936
 
426
1937
  NOTES:
427
1938
  This is needed for handlers that uses the primary key to find the
432
1943
void Table::prepare_for_position()
433
1944
{
434
1945
 
435
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
436
 
      getShare()->hasPrimaryKey())
 
1946
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
 
1947
      s->primary_key < MAX_KEY)
437
1948
  {
438
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
1949
    mark_columns_used_by_index_no_reset(s->primary_key);
439
1950
  }
440
1951
  return;
441
1952
}
453
1964
 
454
1965
void Table::mark_columns_used_by_index(uint32_t index)
455
1966
{
456
 
  boost::dynamic_bitset<> *bitmap= &tmp_set;
 
1967
  MY_BITMAP *bitmap= &tmp_set;
457
1968
 
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);
 
1969
  (void) file->extra(HA_EXTRA_KEYREAD);
 
1970
  bitmap_clear_all(bitmap);
 
1971
  mark_columns_used_by_index_no_reset(index, bitmap);
 
1972
  column_bitmaps_set(bitmap, bitmap);
462
1973
  return;
463
1974
}
464
1975
 
478
1989
{
479
1990
 
480
1991
  key_read= 0;
481
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
1992
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
482
1993
  default_column_bitmaps();
483
1994
  return;
484
1995
}
490
2001
 
491
2002
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
492
2003
{
493
 
    mark_columns_used_by_index_no_reset(index, *read_set);
 
2004
    mark_columns_used_by_index_no_reset(index, read_set);
494
2005
}
495
2006
 
496
 
 
497
2007
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
498
 
                                                boost::dynamic_bitset<>& bitmap)
 
2008
                                                MY_BITMAP *bitmap)
499
2009
{
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
 
  }
 
2010
  KEY_PART_INFO *key_part= key_info[index].key_part;
 
2011
  KEY_PART_INFO *key_part_end= (key_part +
 
2012
                                key_info[index].key_parts);
 
2013
  for (;key_part != key_part_end; key_part++)
 
2014
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
507
2015
}
508
2016
 
509
2017
 
522
2030
    We must set bit in read set as update_auto_increment() is using the
523
2031
    store() to check overflow of auto_increment values
524
2032
  */
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);
 
2033
  setReadSet(found_next_number_field->field_index);
 
2034
  setWriteSet(found_next_number_field->field_index);
 
2035
  if (s->next_number_keypart)
 
2036
    mark_columns_used_by_index_no_reset(s->next_number_index);
529
2037
}
530
2038
 
531
2039
 
550
2058
void Table::mark_columns_needed_for_delete()
551
2059
{
552
2060
  /*
553
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2061
    If the handler has no cursor capabilites, or we have row-based
554
2062
    replication active for the current statement, we have to read
555
2063
    either the primary key, the hidden primary key or all columns to
556
2064
    be able to do an delete
557
2065
 
558
2066
  */
559
 
  if (not getShare()->hasPrimaryKey())
 
2067
  if (s->primary_key == MAX_KEY)
560
2068
  {
561
2069
    /* fallback to use all columns in the table to identify row */
562
2070
    use_all_columns();
563
2071
    return;
564
2072
  }
565
2073
  else
566
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
2074
    mark_columns_used_by_index_no_reset(s->primary_key);
567
2075
 
568
2076
  /* If we the engine wants all predicates we mark all keys */
569
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2077
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
570
2078
  {
571
2079
    Field **reg_field;
572
2080
    for (reg_field= field ; *reg_field ; reg_field++)
573
2081
    {
574
2082
      if ((*reg_field)->flags & PART_KEY_FLAG)
575
 
        setReadSet((*reg_field)->position());
 
2083
        setReadSet((*reg_field)->field_index);
576
2084
    }
577
2085
  }
578
2086
}
590
2098
    if neeed, either the primary key column or all columns to be read.
591
2099
    (see mark_columns_needed_for_delete() for details)
592
2100
 
593
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
2101
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
594
2102
    mark all USED key columns as 'to-be-read'. This allows the engine to
595
2103
    loop over the given record to find all changed keys and doesn't have to
596
2104
    retrieve the row again.
599
2107
void Table::mark_columns_needed_for_update()
600
2108
{
601
2109
  /*
602
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2110
    If the handler has no cursor capabilites, or we have row-based
603
2111
    logging active for the current statement, we have to read either
604
2112
    the primary key, the hidden primary key or all columns to be
605
2113
    able to do an update
606
2114
  */
607
 
  if (not getShare()->hasPrimaryKey())
 
2115
  if (s->primary_key == MAX_KEY)
608
2116
  {
609
2117
    /* fallback to use all columns in the table to identify row */
610
2118
    use_all_columns();
611
2119
    return;
612
2120
  }
613
2121
  else
614
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
2122
    mark_columns_used_by_index_no_reset(s->primary_key);
615
2123
 
616
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2124
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
617
2125
  {
618
2126
    /* Mark all used key columns for read */
619
2127
    Field **reg_field;
621
2129
    {
622
2130
      /* Merge keys is all keys that had a column refered to in the query */
623
2131
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
624
 
        setReadSet((*reg_field)->position());
 
2132
        setReadSet((*reg_field)->field_index);
625
2133
    }
626
2134
  }
627
2135
 
629
2137
 
630
2138
 
631
2139
/*
632
 
  Mark columns the Cursor needs for doing an insert
 
2140
  Mark columns the handler needs for doing an insert
633
2141
 
634
2142
  For now, this is used to mark fields used by the trigger
635
2143
  as changed.
653
2161
  {
654
2162
    Field_blob* const blob= (Field_blob*) field[*ptr];
655
2163
    length+= blob->get_length((const unsigned char*)
656
 
                              (data + blob->offset(getInsertRecord()))) +
 
2164
                              (data + blob->offset(record[0]))) +
657
2165
      HA_KEY_BLOB_LENGTH;
658
2166
  }
659
2167
  return length;
660
2168
}
661
2169
 
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
2170
/****************************************************************************
675
2171
 Functions for creating temporary tables.
676
2172
****************************************************************************/
 
2173
 
 
2174
 
 
2175
/* Prototypes */
 
2176
void free_tmp_table(Session *session, Table *entry);
 
2177
 
677
2178
/**
678
2179
  Create field for temporary table from given field.
679
2180
 
680
 
  @param session               Thread Cursor
 
2181
  @param session               Thread handler
681
2182
  @param org_field    field from which new field will be created
682
2183
  @param name         New field name
683
2184
  @param table         Temporary table
708
2209
  */
709
2210
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
710
2211
      (org_field->flags & BLOB_FLAG))
711
 
  {
712
 
    table->setVariableWidth();
713
2212
    new_field= new Field_varstring(convert_blob_length,
714
2213
                                   org_field->maybe_null(),
715
 
                                   org_field->field_name,
 
2214
                                   org_field->field_name, table->s,
716
2215
                                   org_field->charset());
717
 
  }
718
2216
  else
719
 
  {
720
2217
    new_field= org_field->new_field(session->mem_root, table,
721
 
                                    table == org_field->getTable());
722
 
  }
 
2218
                                    table == org_field->table);
723
2219
  if (new_field)
724
2220
  {
725
2221
    new_field->init(table);
732
2228
    if (org_field->maybe_null() || (item && item->maybe_null))
733
2229
      new_field->flags&= ~NOT_NULL_FLAG;        // Because of outer join
734
2230
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
735
 
      table->getMutableShare()->db_create_options|= HA_OPTION_PACK_RECORD;
 
2231
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
736
2232
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
737
2233
      ((Field_double *) new_field)->not_fixed= true;
738
2234
  }
741
2237
 
742
2238
 
743
2239
/**
 
2240
  Create field for information schema table.
 
2241
 
 
2242
  @param session                Thread handler
 
2243
  @param table          Temporary table
 
2244
  @param item           Item to create a field for
 
2245
 
 
2246
  @retval
 
2247
    0                   on error
 
2248
  @retval
 
2249
    new_created field
 
2250
*/
 
2251
 
 
2252
static Field *create_tmp_field_for_schema(Item *item, Table *table)
 
2253
{
 
2254
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
2255
  {
 
2256
    Field *field;
 
2257
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
2258
      field= new Field_blob(item->max_length, item->maybe_null,
 
2259
                            item->name, item->collation.collation);
 
2260
    else
 
2261
      field= new Field_varstring(item->max_length, item->maybe_null,
 
2262
                                 item->name,
 
2263
                                 table->s, item->collation.collation);
 
2264
    if (field)
 
2265
      field->init(table);
 
2266
    return field;
 
2267
  }
 
2268
  return item->tmp_table_field_from_field_type(table, 0);
 
2269
}
 
2270
 
 
2271
 
 
2272
/**
744
2273
  Create a temp table according to a field list.
745
2274
 
746
2275
  Given field pointers are changed to point at tmp_table for
772
2301
 
773
2302
Table *
774
2303
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
775
 
                 Order *group, bool distinct, bool save_sum_fields,
 
2304
                 order_st *group, bool distinct, bool save_sum_fields,
776
2305
                 uint64_t select_options, ha_rows rows_limit,
777
2306
                 const char *table_alias)
778
2307
{
779
 
  memory::Root *mem_root_save;
 
2308
  MEM_ROOT *mem_root_save, own_root;
 
2309
  Table *table;
 
2310
  TableShare *share;
780
2311
  uint  i,field_count,null_count,null_pack_length;
781
2312
  uint32_t  copy_func_count= param->func_count;
782
2313
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
783
2314
  uint32_t  blob_count,group_null_items, string_count;
784
2315
  uint32_t fieldnr= 0;
785
2316
  ulong reclength, string_total_length;
786
 
  bool  using_unique_constraint= false;
787
 
  bool  use_packed_rows= true;
 
2317
  bool  using_unique_constraint= 0;
 
2318
  bool  use_packed_rows= 0;
788
2319
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
789
 
  unsigned char *pos, *group_buff;
 
2320
  char  *tmpname,path[FN_REFLEN];
 
2321
  unsigned char *pos, *group_buff, *bitmaps;
790
2322
  unsigned char *null_flags;
791
2323
  Field **reg_field, **from_field, **default_field;
 
2324
  uint32_t *blob_field;
792
2325
  CopyField *copy= 0;
793
 
  KeyInfo *keyinfo;
794
 
  KeyPartInfo *key_part_info;
 
2326
  KEY *keyinfo;
 
2327
  KEY_PART_INFO *key_part_info;
795
2328
  Item **copy_func;
796
2329
  MI_COLUMNDEF *recinfo;
797
2330
  uint32_t total_uneven_bit_length= 0;
798
2331
  bool force_copy_fields= param->force_copy_fields;
799
 
  uint64_t max_rows= 0;
800
 
 
801
 
  session->status_var.created_tmp_tables++;
 
2332
 
 
2333
  status_var_increment(session->status_var.created_tmp_tables);
 
2334
 
 
2335
  /* if we run out of slots or we are not using tempool */
 
2336
  sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
2337
          session->thread_id, session->tmp_table++);
 
2338
 
 
2339
  /*
 
2340
    No need to change table name to lower case as we are only creating
 
2341
    MyISAM or HEAP tables here
 
2342
  */
 
2343
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
2344
 
802
2345
 
803
2346
  if (group)
804
2347
  {
805
 
    if (! param->quick_group)
806
 
    {
 
2348
    if (!param->quick_group)
807
2349
      group= 0;                                 // Can't use group key
808
 
    }
809
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
2350
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
810
2351
    {
811
2352
      /*
812
2353
        marker == 4 means two things:
816
2357
      */
817
2358
      (*tmp->item)->marker= 4;
818
2359
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
819
 
        using_unique_constraint= true;
 
2360
        using_unique_constraint=1;
820
2361
    }
821
2362
    if (param->group_length >= MAX_BLOB_WIDTH)
822
 
      using_unique_constraint= true;
 
2363
      using_unique_constraint=1;
823
2364
    if (group)
824
2365
      distinct= 0;                              // Can't use distinct
825
2366
  }
835
2376
    these items are stored in the temporary table.
836
2377
  */
837
2378
  if (param->precomputed_group_by)
838
 
  {
839
2379
    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))
 
2380
 
 
2381
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
2382
 
 
2383
  if (!multi_alloc_root(&own_root,
 
2384
                        &table, sizeof(*table),
 
2385
                        &share, sizeof(*share),
 
2386
                        &reg_field, sizeof(Field*) * (field_count+1),
 
2387
                        &default_field, sizeof(Field*) * (field_count),
 
2388
                        &blob_field, sizeof(uint32_t)*(field_count+1),
 
2389
                        &from_field, sizeof(Field*)*field_count,
 
2390
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
 
2391
                        &param->keyinfo, sizeof(*param->keyinfo),
 
2392
                        &key_part_info,
 
2393
                        sizeof(*key_part_info)*(param->group_parts+1),
 
2394
                        &param->start_recinfo,
 
2395
                        sizeof(*param->recinfo)*(field_count*2+4),
 
2396
                        &tmpname, (uint32_t) strlen(path)+1,
 
2397
                        &group_buff, (group && ! using_unique_constraint ?
 
2398
                                      param->group_length : 0),
 
2399
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
2400
                        NULL))
855
2401
  {
856
 
    return NULL;
 
2402
    return NULL;                                /* purecov: inspected */
857
2403
  }
858
2404
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
859
2405
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
860
2406
  {
861
 
    return NULL;
 
2407
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
2408
    return NULL;                                /* purecov: inspected */
862
2409
  }
863
2410
  param->items_to_copy= copy_func;
 
2411
  strcpy(tmpname,path);
864
2412
  /* make table according to fields */
865
2413
 
 
2414
  memset(table, 0, sizeof(*table));
 
2415
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
866
2416
  memset(default_field, 0, sizeof(Field*) * (field_count));
867
2417
  memset(from_field, 0, sizeof(Field*)*field_count);
868
2418
 
 
2419
  table->mem_root= own_root;
869
2420
  mem_root_save= session->mem_root;
870
 
  session->mem_root= table->getMemRoot();
 
2421
  session->mem_root= &table->mem_root;
871
2422
 
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);
 
2423
  table->field=reg_field;
 
2424
  table->alias= table_alias;
876
2425
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
877
2426
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
878
2427
  table->map=1;
879
2428
  table->copy_blobs= 1;
880
 
  assert(session);
881
2429
  table->in_use= session;
882
2430
  table->quick_keys.reset();
883
2431
  table->covering_keys.reset();
884
2432
  table->keys_in_use_for_query.reset();
885
2433
 
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();
 
2434
  table->setShare(share);
 
2435
  share->init(tmpname, tmpname);
 
2436
  share->blob_field= blob_field;
 
2437
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
2438
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
2439
  share->table_charset= param->table_charset;
 
2440
  share->primary_key= MAX_KEY;               // Indicate no primary key
 
2441
  share->keys_for_keyread.reset();
 
2442
  share->keys_in_use.reset();
892
2443
 
893
2444
  /* Calculate which type of fields we will store in the temporary table */
894
2445
 
936
2487
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
937
2488
                             tmp_from_field, &default_field[fieldnr],
938
2489
                             group != 0,not_all_columns,
939
 
                             false,
 
2490
                             distinct, 0,
940
2491
                             param->convert_blob_length);
941
2492
          if (!new_field)
942
2493
            goto err;                                   // Should be OOM
955
2506
          }
956
2507
          session->mem_root= mem_root_save;
957
2508
          session->change_item_tree(argp, new Item_field(new_field));
958
 
          session->mem_root= table->getMemRoot();
 
2509
          session->mem_root= &table->mem_root;
959
2510
          if (!(new_field->flags & NOT_NULL_FLAG))
960
2511
          {
961
2512
            null_count++;
965
2516
            */
966
2517
            (*argp)->maybe_null=1;
967
2518
          }
968
 
          new_field->setPosition(fieldnr++);
 
2519
          new_field->field_index= fieldnr++;
969
2520
        }
970
2521
      }
971
2522
    }
981
2532
        We here distinguish between UNION and multi-table-updates by the fact
982
2533
        that in the later case group is set to the row pointer.
983
2534
      */
984
 
      Field *new_field=
 
2535
      Field *new_field= (param->schema_table) ?
 
2536
        create_tmp_field_for_schema(item, table) :
985
2537
        create_tmp_field(session, table, item, type, &copy_func,
986
2538
                         tmp_from_field, &default_field[fieldnr],
987
2539
                         group != 0,
988
2540
                         !force_copy_fields &&
989
2541
                           (not_all_columns || group != 0),
 
2542
                         /*
 
2543
                           If item->marker == 4 then we force create_tmp_field
 
2544
                           to create a 64-bit longs for BIT fields because HEAP
 
2545
                           tables can't index BIT fields directly. We do the same
 
2546
                           for distinct, as we want the distinct index to be
 
2547
                           usable in this case too.
 
2548
                         */
 
2549
                         item->marker == 4 || param->bit_fields_as_long,
990
2550
                         force_copy_fields,
991
2551
                         param->convert_blob_length);
992
2552
 
1012
2572
        group_null_items++;
1013
2573
        new_field->flags|= GROUP_FLAG;
1014
2574
      }
1015
 
      new_field->setPosition(fieldnr++);
 
2575
      new_field->field_index= fieldnr++;
1016
2576
      *(reg_field++)= new_field;
1017
2577
    }
1018
2578
    if (!--hidden_field_count)
1030
2590
      null_count= 0;
1031
2591
    }
1032
2592
  }
1033
 
  assert(fieldnr == (uint32_t) (reg_field - table->getFields()));
1034
 
  assert(field_count >= (uint32_t) (reg_field - table->getFields()));
 
2593
  assert(fieldnr == (uint32_t) (reg_field - table->field));
 
2594
  assert(field_count >= (uint32_t) (reg_field - table->field));
1035
2595
  field_count= fieldnr;
1036
2596
  *reg_field= 0;
1037
2597
  *blob_field= 0;                               // End marker
1038
 
  table->getMutableShare()->setFieldSize(field_count);
 
2598
  share->fields= field_count;
1039
2599
 
1040
2600
  /* If result table is small; use a heap */
1041
2601
  /* 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)
 
2602
  if (blob_count || using_unique_constraint ||
 
2603
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
2604
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
1046
2605
  {
1047
 
    table->getMutableShare()->storage_engine= myisam_engine;
1048
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
2606
    share->storage_engine= myisam_engine;
 
2607
    table->file= get_new_handler(share, &table->mem_root,
 
2608
                                 share->db_type());
1049
2609
    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
 
    }
 
2610
        (param->group_parts > table->file->max_key_parts() ||
 
2611
         param->group_length > table->file->max_key_length()))
 
2612
      using_unique_constraint=1;
1055
2613
  }
1056
2614
  else
1057
2615
  {
1058
 
    table->getMutableShare()->storage_engine= heap_engine;
1059
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
2616
    share->storage_engine= heap_engine;
 
2617
    table->file= get_new_handler(share, &table->mem_root,
 
2618
                                 share->db_type());
1060
2619
  }
1061
 
  if (! table->cursor)
 
2620
  if (!table->file)
1062
2621
    goto err;
1063
2622
 
1064
2623
 
1065
 
  if (! using_unique_constraint)
 
2624
  if (!using_unique_constraint)
1066
2625
    reclength+= group_null_items;       // null flag is stored separately
1067
2626
 
1068
 
  table->getMutableShare()->blob_fields= blob_count;
 
2627
  share->blob_fields= blob_count;
1069
2628
  if (blob_count == 0)
1070
2629
  {
1071
2630
    /* We need to ensure that first byte is not 0 for the delete link */
1084
2643
  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
2644
    use_packed_rows= 1;
1086
2645
 
1087
 
  table->getMutableShare()->setRecordLength(reclength);
 
2646
  share->reclength= reclength;
1088
2647
  {
1089
2648
    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
 
    {
 
2649
    share->rec_buff_length= alloc_length;
 
2650
    if (!(table->record[0]= (unsigned char*)
 
2651
                            alloc_root(&table->mem_root, alloc_length*3)))
1093
2652
      goto err;
1094
 
    }
1095
 
    table->record[1]= table->getInsertRecord()+alloc_length;
1096
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
2653
    table->record[1]= table->record[0]+alloc_length;
 
2654
    share->default_values= table->record[1]+alloc_length;
1097
2655
  }
1098
2656
  copy_func[0]= 0;                              // End marker
1099
2657
  param->func_count= copy_func - param->items_to_copy;
1100
2658
 
1101
 
  table->setup_tmp_table_column_bitmaps();
 
2659
  table->setup_tmp_table_column_bitmaps(bitmaps);
1102
2660
 
1103
2661
  recinfo=param->start_recinfo;
1104
 
  null_flags=(unsigned char*) table->getInsertRecord();
1105
 
  pos=table->getInsertRecord()+ null_pack_length;
 
2662
  null_flags=(unsigned char*) table->record[0];
 
2663
  pos=table->record[0]+ null_pack_length;
1106
2664
  if (null_pack_length)
1107
2665
  {
1108
2666
    memset(recinfo, 0, sizeof(*recinfo));
1111
2669
    recinfo++;
1112
2670
    memset(null_flags, 255, null_pack_length);  // Set null fields
1113
2671
 
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;
 
2672
    table->null_flags= (unsigned char*) table->record[0];
 
2673
    share->null_fields= null_count+ hidden_null_count;
 
2674
    share->null_bytes= null_pack_length;
1117
2675
  }
1118
2676
  null_count= (blob_count == 0) ? 1 : 0;
1119
2677
  hidden_field_count=param->hidden_field_count;
1120
 
  for (i= 0,reg_field= table->getFields(); i < field_count; i++,reg_field++,recinfo++)
 
2678
  for (i= 0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
1121
2679
  {
1122
2680
    Field *field= *reg_field;
1123
2681
    uint32_t length;
1161
2719
         inherit the default value that is defined for the field referred
1162
2720
         by the Item_field object from which 'field' has been created.
1163
2721
      */
1164
 
      ptrdiff_t diff;
 
2722
      my_ptrdiff_t diff;
1165
2723
      Field *orig_field= default_field[i];
1166
2724
      /* Get the value from default_values */
1167
 
      diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
 
2725
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
 
2726
                            orig_field->table->record[0]);
1168
2727
      orig_field->move_field_offset(diff);      // Points now at default_values
1169
2728
      if (orig_field->is_real_null())
1170
2729
        field->set_null();
1173
2732
        field->set_notnull();
1174
2733
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
1175
2734
      }
1176
 
      orig_field->move_field_offset(-diff);     // Back to getInsertRecord()
 
2735
      orig_field->move_field_offset(-diff);     // Back to record[0]
1177
2736
    }
1178
2737
 
1179
2738
    if (from_field[i])
1192
2751
      recinfo->type=FIELD_NORMAL;
1193
2752
    if (!--hidden_field_count)
1194
2753
      null_count=(null_count+7) & ~7;           // move to next byte
 
2754
 
 
2755
    // fix table name in field entry
 
2756
    field->table_name= &table->alias;
1195
2757
  }
1196
2758
 
1197
2759
  param->copy_field_end=copy;
1199
2761
  table->storeRecordAsDefault();        // Make empty default record
1200
2762
 
1201
2763
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
1202
 
  {
1203
 
    max_rows= ~(uint64_t) 0;
1204
 
  }
 
2764
    share->max_rows= ~(ha_rows) 0;
1205
2765
  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
 
  }
 
2766
    share->max_rows= (ha_rows) (((share->db_type() == heap_engine) ?
 
2767
                                 min(session->variables.tmp_table_size,
 
2768
                                     session->variables.max_heap_table_size) :
 
2769
                                 session->variables.tmp_table_size) /
 
2770
                                 share->reclength);
1213
2771
 
1214
 
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
 
2772
  set_if_bigger(share->max_rows,(ha_rows)1);    // For dummy start options
1215
2773
  /*
1216
2774
    Push the LIMIT clause to the temporary table creation, so that we
1217
2775
    materialize only up to 'rows_limit' records instead of all result records.
1218
2776
  */
1219
 
  set_if_smaller(max_rows, rows_limit);
1220
 
 
1221
 
  table->getMutableShare()->setMaxRows(max_rows);
1222
 
 
 
2777
  set_if_smaller(share->max_rows, rows_limit);
1223
2778
  param->end_write_records= rows_limit;
1224
2779
 
1225
2780
  keyinfo= param->keyinfo;
1228
2783
  {
1229
2784
    table->group=group;                         /* Table is grouped by key */
1230
2785
    param->group_buff=group_buff;
1231
 
    table->getMutableShare()->keys=1;
1232
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
2786
    share->keys=1;
 
2787
    share->uniques= test(using_unique_constraint);
1233
2788
    table->key_info=keyinfo;
1234
2789
    keyinfo->key_part=key_part_info;
1235
2790
    keyinfo->flags=HA_NOSAME;
1238
2793
    keyinfo->rec_per_key= 0;
1239
2794
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1240
2795
    keyinfo->name= (char*) "group_key";
1241
 
    Order *cur_group= group;
 
2796
    order_st *cur_group= group;
1242
2797
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1243
2798
    {
1244
2799
      Field *field=(*cur_group->item)->get_tmp_table_field();
1245
2800
      bool maybe_null=(*cur_group->item)->maybe_null;
1246
2801
      key_part_info->null_bit= 0;
1247
2802
      key_part_info->field=  field;
1248
 
      key_part_info->offset= field->offset(table->getInsertRecord());
 
2803
      key_part_info->offset= field->offset(table->record[0]);
1249
2804
      key_part_info->length= (uint16_t) field->key_length();
1250
2805
      key_part_info->type=   (uint8_t) field->key_type();
1251
 
      key_part_info->key_type= 
 
2806
      key_part_info->key_type =
1252
2807
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1253
2808
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1254
2809
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1255
 
        0 : 1;
 
2810
        0 : FIELDFLAG_BINARY;
1256
2811
      if (!using_unique_constraint)
1257
2812
      {
1258
2813
        cur_group->buff=(char*) group_buff;
1261
2816
                                                     test(maybe_null),
1262
2817
                                                     field->null_ptr,
1263
2818
                                                     field->null_bit)))
1264
 
          goto err;
 
2819
          goto err; /* purecov: inspected */
1265
2820
        if (maybe_null)
1266
2821
        {
1267
2822
          /*
1273
2828
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
1274
2829
          key_part_info->null_bit=field->null_bit;
1275
2830
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
1276
 
                                              (unsigned char*) table->getInsertRecord());
 
2831
                                              (unsigned char*) table->record[0]);
1277
2832
          cur_group->buff++;                        // Pointer to field data
1278
2833
          group_buff++;                         // Skipp null flag
1279
2834
        }
1300
2855
        indexes on blobs with arbitrary length. Such indexes cannot be
1301
2856
        used for lookups.
1302
2857
      */
1303
 
      table->getMutableShare()->uniques= 1;
 
2858
      share->uniques= 1;
1304
2859
    }
1305
2860
    null_pack_length-=hidden_null_pack_length;
1306
2861
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1307
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
2862
                         (share->uniques ? test(null_pack_length) : 0));
1308
2863
    table->distinct= 1;
1309
 
    table->getMutableShare()->keys= 1;
1310
 
    if (!(key_part_info= (KeyPartInfo*)
1311
 
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
 
2864
    share->keys= 1;
 
2865
    if (!(key_part_info= (KEY_PART_INFO*)
 
2866
          alloc_root(&table->mem_root,
 
2867
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
1312
2868
      goto err;
1313
 
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KeyPartInfo));
 
2869
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
1314
2870
    table->key_info=keyinfo;
1315
2871
    keyinfo->key_part=key_part_info;
1316
2872
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
1324
2880
      blobs can distinguish NULL from 0. This extra field is not needed
1325
2881
      when we do not use UNIQUE indexes for blobs.
1326
2882
    */
1327
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
2883
    if (null_pack_length && share->uniques)
1328
2884
    {
1329
2885
      key_part_info->null_bit= 0;
1330
2886
      key_part_info->offset=hidden_null_pack_length;
1331
2887
      key_part_info->length=null_pack_length;
1332
 
      table->setVariableWidth();
1333
 
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
 
2888
      key_part_info->field= new Field_varstring(table->record[0],
1334
2889
                                                (uint32_t) key_part_info->length,
1335
2890
                                                0,
1336
2891
                                                (unsigned char*) 0,
1337
2892
                                                (uint32_t) 0,
 
2893
                                                Field::NONE,
1338
2894
                                                NULL,
 
2895
                                                table->s,
1339
2896
                                                &my_charset_bin);
1340
2897
      if (!key_part_info->field)
1341
2898
        goto err;
1342
2899
      key_part_info->field->init(table);
1343
 
      key_part_info->key_type= 1; /* binary comparison */
 
2900
      key_part_info->key_type=FIELDFLAG_BINARY;
1344
2901
      key_part_info->type=    HA_KEYTYPE_BINARY;
1345
2902
      key_part_info++;
1346
2903
    }
1347
2904
    /* Create a distinct key over the columns we are going to return */
1348
 
    for (i=param->hidden_field_count, reg_field=table->getFields() + i ;
 
2905
    for (i=param->hidden_field_count, reg_field=table->field + i ;
1349
2906
         i < field_count;
1350
2907
         i++, reg_field++, key_part_info++)
1351
2908
    {
1352
2909
      key_part_info->null_bit= 0;
1353
2910
      key_part_info->field=    *reg_field;
1354
 
      key_part_info->offset=   (*reg_field)->offset(table->getInsertRecord());
 
2911
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
1355
2912
      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.
 
2913
      /* TODO:
 
2914
        The below method of computing the key format length of the
 
2915
        key part is a copy/paste from opt_range.cc, and table.cc.
1358
2916
        This should be factored out, e.g. as a method of Field.
1359
2917
        In addition it is not clear if any of the Field::*_length
1360
2918
        methods is supposed to compute the same length. If so, it
1373
2931
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1374
2932
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1375
2933
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1376
 
        0 : 1;
 
2934
        0 : FIELDFLAG_BINARY;
1377
2935
    }
1378
2936
  }
1379
2937
 
1380
2938
  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)
 
2939
    goto err;                                    /* purecov: inspected */
 
2940
  share->db_record_offset= 1;
 
2941
  if (share->db_type() == myisam_engine)
1384
2942
  {
1385
2943
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1386
2944
                                       &param->recinfo, select_options))
1387
2945
      goto err;
1388
2946
  }
1389
 
  assert(table->in_use);
1390
2947
  if (table->open_tmp_table())
1391
2948
    goto err;
1392
2949
 
1396
2953
 
1397
2954
err:
1398
2955
  session->mem_root= mem_root_save;
1399
 
  table= NULL;
1400
 
 
1401
 
  return NULL;
 
2956
  table->free_tmp_table(session);                    /* purecov: inspected */
 
2957
  return NULL;                          /* purecov: inspected */
1402
2958
}
1403
2959
 
1404
2960
/****************************************************************************/
1405
2961
 
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;
 
2962
/**
 
2963
  Create a reduced Table object with properly set up Field list from a
 
2964
  list of field definitions.
 
2965
 
 
2966
    The created table doesn't have a table handler associated with
 
2967
    it, has no keys, no group/distinct, no copy_funcs array.
 
2968
    The sole purpose of this Table object is to use the power of Field
 
2969
    class to read/write data to/from table->record[0]. Then one can store
 
2970
    the record in any container (RB tree, hash, etc).
 
2971
    The table is created in Session mem_root, so are the table's fields.
 
2972
    Consequently, if you don't BLOB fields, you don't need to free it.
 
2973
 
 
2974
  @param session         connection handle
 
2975
  @param field_list  list of column definitions
 
2976
 
 
2977
  @return
 
2978
    0 if out of memory, Table object in case of success
 
2979
*/
 
2980
 
 
2981
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
 
2982
{
 
2983
  uint32_t field_count= field_list.elements;
 
2984
  uint32_t blob_count= 0;
 
2985
  Field **field;
 
2986
  CreateField *cdef;                           /* column definition */
 
2987
  uint32_t record_length= 0;
 
2988
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
2989
  uint32_t null_pack_length;              /* NULL representation array length */
 
2990
  uint32_t *blob_field;
 
2991
  unsigned char *bitmaps;
 
2992
  Table *table;
 
2993
  TableShare *share;
 
2994
 
 
2995
  if (!multi_alloc_root(session->mem_root,
 
2996
                        &table, sizeof(*table),
 
2997
                        &share, sizeof(*share),
 
2998
                        &field, (field_count + 1) * sizeof(Field*),
 
2999
                        &blob_field, (field_count+1) *sizeof(uint32_t),
 
3000
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
3001
                        NULL))
 
3002
    return NULL;
 
3003
 
 
3004
  memset(table, 0, sizeof(*table));
 
3005
  memset(share, 0, sizeof(*share));
 
3006
  table->field= field;
 
3007
  table->s= share;
 
3008
  share->blob_field= blob_field;
 
3009
  share->fields= field_count;
 
3010
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
3011
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
3012
 
 
3013
  /* Create all fields and calculate the total length of record */
 
3014
  List_iterator_fast<CreateField> it(field_list);
 
3015
  while ((cdef= it++))
 
3016
  {
 
3017
    *field= make_field(share, NULL, 0, cdef->length,
 
3018
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
3019
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
3020
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
 
3021
                       cdef->unireg_check,
 
3022
                       cdef->interval, cdef->field_name);
 
3023
    if (!*field)
 
3024
      goto error;
 
3025
    (*field)->init(table);
 
3026
    record_length+= (*field)->pack_length();
 
3027
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
3028
      null_count++;
 
3029
 
 
3030
    if ((*field)->flags & BLOB_FLAG)
 
3031
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
 
3032
 
 
3033
    field++;
 
3034
  }
 
3035
  *field= NULL;                             /* mark the end of the list */
 
3036
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
3037
  share->blob_fields= blob_count;
 
3038
 
 
3039
  null_pack_length= (null_count + 7)/8;
 
3040
  share->reclength= record_length + null_pack_length;
 
3041
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
3042
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
 
3043
  if (!table->record[0])
 
3044
    goto error;
 
3045
 
 
3046
  if (null_pack_length)
 
3047
  {
 
3048
    table->null_flags= (unsigned char*) table->record[0];
 
3049
    share->null_fields= null_count;
 
3050
    share->null_bytes= null_pack_length;
 
3051
  }
 
3052
 
 
3053
  table->in_use= session;           /* field->reset() may access table->in_use */
 
3054
  {
 
3055
    /* Set up field pointers */
 
3056
    unsigned char *null_pos= table->record[0];
 
3057
    unsigned char *field_pos= null_pos + share->null_bytes;
 
3058
    uint32_t null_bit= 1;
 
3059
 
 
3060
    for (field= table->field; *field; ++field)
 
3061
    {
 
3062
      Field *cur_field= *field;
 
3063
      if ((cur_field->flags & NOT_NULL_FLAG))
 
3064
        cur_field->move_field(field_pos);
 
3065
      else
 
3066
      {
 
3067
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
3068
        null_bit<<= 1;
 
3069
        if (null_bit == (1 << 8))
 
3070
        {
 
3071
          ++null_pos;
 
3072
          null_bit= 1;
 
3073
        }
 
3074
      }
 
3075
      cur_field->reset();
 
3076
 
 
3077
      field_pos+= cur_field->pack_length();
 
3078
    }
 
3079
  }
 
3080
  return table;
 
3081
error:
 
3082
  for (field= table->field; *field; ++field)
 
3083
    delete *field;                         /* just invokes field destructor */
 
3084
  return 0;
 
3085
}
 
3086
 
 
3087
bool Table::open_tmp_table()
 
3088
{
 
3089
  int error;
 
3090
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
 
3091
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
3092
  {
 
3093
    file->print_error(error,MYF(0)); /* purecov: inspected */
 
3094
    db_stat= 0;
 
3095
    return true;
 
3096
  }
 
3097
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
3098
  return false;
 
3099
}
 
3100
 
 
3101
 
 
3102
/*
 
3103
  Create MyISAM temporary table
 
3104
 
 
3105
  SYNOPSIS
 
3106
    create_myisam_tmp_table()
 
3107
      keyinfo         Description of the index (there is always one index)
 
3108
      start_recinfo   MyISAM's column descriptions
 
3109
      recinfo INOUT   End of MyISAM's column descriptions
 
3110
      options         Option bits
 
3111
 
 
3112
  DESCRIPTION
 
3113
    Create a MyISAM temporary table according to passed description. The is
 
3114
    assumed to have one unique index or constraint.
 
3115
 
 
3116
    The passed array or MI_COLUMNDEF structures must have this form:
 
3117
 
 
3118
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
3119
         when there are many nullable columns)
 
3120
      2. Table columns
 
3121
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
3122
 
 
3123
    This function may use the free element to create hash column for unique
 
3124
    constraint.
 
3125
 
 
3126
   RETURN
 
3127
     false - OK
 
3128
     true  - Error
 
3129
*/
 
3130
 
 
3131
bool Table::create_myisam_tmp_table(KEY *keyinfo,
 
3132
                                    MI_COLUMNDEF *start_recinfo,
 
3133
                                    MI_COLUMNDEF **recinfo,
 
3134
                                    uint64_t options)
 
3135
{
 
3136
  int error;
 
3137
  MI_KEYDEF keydef;
 
3138
  MI_UNIQUEDEF uniquedef;
 
3139
  TableShare *share= s;
 
3140
 
 
3141
  if (share->keys)
 
3142
  {                                             // Get keys for ni_create
 
3143
    bool using_unique_constraint= 0;
 
3144
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
 
3145
                                            sizeof(*seg) * keyinfo->key_parts);
 
3146
    if (!seg)
 
3147
      goto err;
 
3148
 
 
3149
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
3150
    if (keyinfo->key_length >= file->max_key_length() ||
 
3151
        keyinfo->key_parts > file->max_key_parts() ||
 
3152
        share->uniques)
 
3153
    {
 
3154
      /* Can't create a key; Make a unique constraint instead of a key */
 
3155
      share->keys=    0;
 
3156
      share->uniques= 1;
 
3157
      using_unique_constraint=1;
 
3158
      memset(&uniquedef, 0, sizeof(uniquedef));
 
3159
      uniquedef.keysegs=keyinfo->key_parts;
 
3160
      uniquedef.seg=seg;
 
3161
      uniquedef.null_are_equal=1;
 
3162
 
 
3163
      /* Create extra column for hash value */
 
3164
      memset(*recinfo, 0, sizeof(**recinfo));
 
3165
      (*recinfo)->type= FIELD_CHECK;
 
3166
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
3167
      (*recinfo)++;
 
3168
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
 
3169
    }
 
3170
    else
 
3171
    {
 
3172
      /* Create an unique key */
 
3173
      memset(&keydef, 0, sizeof(keydef));
 
3174
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
3175
      keydef.keysegs=  keyinfo->key_parts;
 
3176
      keydef.seg= seg;
 
3177
    }
 
3178
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
3179
    {
 
3180
      Field *key_field=keyinfo->key_part[i].field;
 
3181
      seg->flag=     0;
 
3182
      seg->language= key_field->charset()->number;
 
3183
      seg->length=   keyinfo->key_part[i].length;
 
3184
      seg->start=    keyinfo->key_part[i].offset;
 
3185
      if (key_field->flags & BLOB_FLAG)
 
3186
      {
 
3187
        seg->type=
 
3188
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
 
3189
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
3190
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
3191
                                  - share->blob_ptr_size);
 
3192
        seg->flag= HA_BLOB_PART;
 
3193
        seg->length= 0;                 // Whole blob in unique constraint
 
3194
      }
 
3195
      else
 
3196
      {
 
3197
        seg->type= keyinfo->key_part[i].type;
 
3198
      }
 
3199
      if (!(key_field->flags & NOT_NULL_FLAG))
 
3200
      {
 
3201
        seg->null_bit= key_field->null_bit;
 
3202
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
 
3203
        /*
 
3204
          We are using a GROUP BY on something that contains NULL
 
3205
          In this case we have to tell MyISAM that two NULL should
 
3206
          on INSERT be regarded at the same value
 
3207
        */
 
3208
        if (!using_unique_constraint)
 
3209
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
3210
      }
 
3211
    }
 
3212
  }
 
3213
  MI_CREATE_INFO create_info;
 
3214
  memset(&create_info, 0, sizeof(create_info));
 
3215
 
 
3216
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
3217
      OPTION_BIG_TABLES)
 
3218
    create_info.data_file_length= ~(uint64_t) 0;
 
3219
 
 
3220
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
 
3221
                       (uint32_t) (*recinfo-start_recinfo),
 
3222
                       start_recinfo,
 
3223
                       share->uniques, &uniquedef,
 
3224
                       &create_info,
 
3225
                       HA_CREATE_TMP_TABLE)))
 
3226
  {
 
3227
    file->print_error(error,MYF(0));    /* purecov: inspected */
 
3228
    db_stat= 0;
 
3229
    goto err;
 
3230
  }
 
3231
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
 
3232
  share->db_record_offset= 1;
 
3233
  return false;
 
3234
 err:
 
3235
  return true;
 
3236
}
 
3237
 
 
3238
 
 
3239
void Table::free_tmp_table(Session *session)
 
3240
{
 
3241
  MEM_ROOT own_root= mem_root;
 
3242
  const char *save_proc_info;
 
3243
 
 
3244
  save_proc_info=session->get_proc_info();
 
3245
  session->set_proc_info("removing tmp table");
 
3246
 
 
3247
  // Release latches since this can take a long time
 
3248
  ha_release_temporary_latches(session);
 
3249
 
 
3250
  if (file)
 
3251
  {
 
3252
    if (db_stat)
 
3253
      file->ha_drop_table(s->table_name.str);
 
3254
    else
 
3255
      s->db_type()->deleteTable(session, s->table_name.str);
 
3256
    delete file;
 
3257
  }
 
3258
 
 
3259
  /* free blobs */
 
3260
  for (Field **ptr= field ; *ptr ; ptr++)
 
3261
    (*ptr)->free();
 
3262
  free_io_cache();
 
3263
 
 
3264
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
 
3265
  session->set_proc_info(save_proc_info);
 
3266
}
 
3267
 
 
3268
/**
 
3269
  If a HEAP table gets full, create a MyISAM table and copy all rows
 
3270
  to this.
 
3271
*/
 
3272
 
 
3273
bool create_myisam_from_heap(Session *session, Table *table,
 
3274
                             MI_COLUMNDEF *start_recinfo,
 
3275
                             MI_COLUMNDEF **recinfo,
 
3276
                             int error, bool ignore_last_dupp_key_error)
 
3277
{
 
3278
  Table new_table;
 
3279
  TableShare share;
 
3280
  const char *save_proc_info;
 
3281
  int write_err;
 
3282
 
 
3283
  if (table->s->db_type() != heap_engine ||
 
3284
      error != HA_ERR_RECORD_FILE_FULL)
 
3285
  {
 
3286
    table->file->print_error(error,MYF(0));
 
3287
    return true;
 
3288
  }
 
3289
 
 
3290
  // Release latches since this can take a long time
 
3291
  ha_release_temporary_latches(session);
 
3292
 
 
3293
  new_table= *table;
 
3294
  share= *table->s;
 
3295
  new_table.s= &share;
 
3296
  new_table.s->storage_engine= myisam_engine;
 
3297
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
3298
                                        new_table.s->db_type())))
 
3299
    return true;                                // End of memory
 
3300
 
 
3301
  save_proc_info=session->get_proc_info();
 
3302
  session->set_proc_info("converting HEAP to MyISAM");
 
3303
 
 
3304
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
 
3305
                                        recinfo, session->lex->select_lex.options |
 
3306
                                        session->options))
 
3307
    goto err2;
 
3308
  if (new_table.open_tmp_table())
 
3309
    goto err1;
 
3310
  if (table->file->indexes_are_disabled())
 
3311
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
3312
  table->file->ha_index_or_rnd_end();
 
3313
  table->file->ha_rnd_init(1);
 
3314
  if (table->no_rows)
 
3315
  {
 
3316
    new_table.file->extra(HA_EXTRA_NO_ROWS);
 
3317
    new_table.no_rows=1;
 
3318
  }
 
3319
 
 
3320
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
 
3321
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
 
3322
 
 
3323
  /*
 
3324
    copy all old rows from heap table to MyISAM table
 
3325
    This is the only code that uses record[1] to read/write but this
 
3326
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
 
3327
  */
 
3328
  while (!table->file->rnd_next(new_table.record[1]))
 
3329
  {
 
3330
    write_err= new_table.file->ha_write_row(new_table.record[1]);
 
3331
    if (write_err)
 
3332
      goto err;
 
3333
  }
 
3334
  /* copy row that filled HEAP table */
 
3335
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
 
3336
  {
 
3337
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
3338
        !ignore_last_dupp_key_error)
 
3339
      goto err;
 
3340
  }
 
3341
 
 
3342
  /* remove heap table and change to use myisam table */
 
3343
  (void) table->file->ha_rnd_end();
 
3344
  (void) table->file->close();                  // This deletes the table !
 
3345
  delete table->file;
 
3346
  table->file= NULL;
 
3347
  new_table.s= table->s;                       // Keep old share
 
3348
  *table= new_table;
 
3349
  *table->s= share;
 
3350
 
 
3351
  table->file->change_table_ptr(table, table->s);
 
3352
  table->use_all_columns();
 
3353
  if (save_proc_info)
 
3354
  {
 
3355
    const char *new_proc_info=
 
3356
      (!strcmp(save_proc_info,"Copying to tmp table") ?
 
3357
      "Copying to tmp table on disk" : save_proc_info);
 
3358
    session->set_proc_info(new_proc_info);
 
3359
  }
 
3360
  return false;
 
3361
 
 
3362
 err:
 
3363
  table->file->print_error(write_err, MYF(0));
 
3364
  (void) table->file->ha_rnd_end();
 
3365
  (void) new_table.file->close();
 
3366
 err1:
 
3367
  new_table.s->db_type()->deleteTable(session, new_table.s->table_name.str);
 
3368
 err2:
 
3369
  delete new_table.file;
 
3370
  session->set_proc_info(save_proc_info);
 
3371
  table->mem_root= new_table.mem_root;
 
3372
  return true;
 
3373
}
 
3374
 
 
3375
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
 
3376
{
 
3377
  my_bitmap_map *old= bitmap->bitmap;
 
3378
  bitmap->bitmap= s->all_set.bitmap;
1418
3379
  return old;
1419
3380
}
1420
3381
 
1421
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
3382
void Table::restore_column_map(my_bitmap_map *old)
1422
3383
{
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
 
  }
 
3384
  read_set->bitmap= old;
1434
3385
}
1435
3386
 
1436
3387
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1439
3390
  uint32_t best= MAX_KEY;
1440
3391
  if (usable_keys->any())
1441
3392
  {
1442
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
3393
    for (uint32_t nr= 0; nr < s->keys ; nr++)
1443
3394
    {
1444
3395
      if (usable_keys->test(nr))
1445
3396
      {
1466
3417
{
1467
3418
  for (; *ptr ; ptr++)
1468
3419
  {
1469
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
3420
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1470
3421
      return true;
1471
3422
  }
1472
3423
  return false;
1473
3424
}
1474
3425
 
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
 
 
 
3426
/* Return false if row hasn't changed */
 
3427
 
 
3428
bool Table::compare_record()
 
3429
{
 
3430
  if (s->blob_fields + s->varchar_fields == 0)
 
3431
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
1536
3432
  /* 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
 
 
 
3433
  if (memcmp(null_flags,
 
3434
             null_flags + s->rec_buff_length,
 
3435
             s->null_bytes))
 
3436
    return true;                                // Diff in NULL value
1540
3437
  /* Compare updated fields */
1541
3438
  for (Field **ptr= field ; *ptr ; ptr++)
1542
3439
  {
1543
 
    if (isWriteSet((*ptr)->position()) &&
1544
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
3440
    if (isWriteSet((*ptr)->field_index) &&
 
3441
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1545
3442
      return true;
1546
3443
  }
1547
3444
  return false;
1553
3450
 */
1554
3451
void Table::storeRecord()
1555
3452
{
1556
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
3453
  memcpy(record[1], record[0], (size_t) s->reclength);
1557
3454
}
1558
3455
 
1559
3456
/*
1562
3459
 */
1563
3460
void Table::storeRecordAsInsert()
1564
3461
{
1565
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1566
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
3462
  memcpy(insert_values, record[0], (size_t) s->reclength);
1567
3463
}
1568
3464
 
1569
3465
/*
1572
3468
 */
1573
3469
void Table::storeRecordAsDefault()
1574
3470
{
1575
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
3471
  memcpy(s->default_values, record[0], (size_t) s->reclength);
1576
3472
}
1577
3473
 
1578
3474
/*
1581
3477
 */
1582
3478
void Table::restoreRecord()
1583
3479
{
1584
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
3480
  memcpy(record[0], record[1], (size_t) s->reclength);
1585
3481
}
1586
3482
 
1587
3483
/*
1590
3486
 */
1591
3487
void Table::restoreRecordAsDefault()
1592
3488
{
1593
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
3489
  memcpy(record[0], s->default_values, (size_t) s->reclength);
1594
3490
}
1595
3491
 
1596
3492
/*
1600
3496
void Table::emptyRecord()
1601
3497
{
1602
3498
  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;
 
3499
  memset(null_flags, 255, s->null_bytes);
1658
3500
}
1659
3501
 
1660
3502
/*****************************************************************************
1662
3504
  Returns -1 if row was not found, 0 if row was found and 1 on errors
1663
3505
*****************************************************************************/
1664
3506
 
1665
 
/** Help function when we get some an error from the table Cursor. */
 
3507
/** Help function when we get some an error from the table handler. */
1666
3508
 
1667
3509
int Table::report_error(int error)
1668
3510
{
1676
3518
    print them to the .err log
1677
3519
  */
1678
3520
  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));
 
3521
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
 
3522
                    error, s->path.str);
 
3523
  file->print_error(error,MYF(0));
1682
3524
 
1683
3525
  return 1;
1684
3526
}
1691
3533
  null_row= 0;
1692
3534
  status= STATUS_NO_RECORD;
1693
3535
  maybe_null= table_list->outer_join;
1694
 
  TableList *embedding= table_list->getEmbedding();
 
3536
  TableList *embedding= table_list->embedding;
1695
3537
  while (!maybe_null && embedding)
1696
3538
  {
1697
3539
    maybe_null= embedding->outer_join;
1698
 
    embedding= embedding->getEmbedding();
 
3540
    embedding= embedding->embedding;
1699
3541
  }
1700
3542
  tablenr= table_number;
1701
3543
  map= (table_map) 1 << table_number;
1702
3544
  force_index= table_list->force_index;
1703
 
  covering_keys= getShare()->keys_for_keyread;
 
3545
  covering_keys= s->keys_for_keyread;
1704
3546
  merge_keys.reset();
1705
3547
}
1706
3548
 
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
 
}
 
3549
Field *Table::find_field_in_table_sef(const char *name)
 
3550
{
 
3551
  Field **field_ptr;
 
3552
  if (s->name_hash.records)
 
3553
  {
 
3554
    field_ptr= (Field**)hash_search(&s->name_hash,(unsigned char*) name,
 
3555
                                    strlen(name));
 
3556
    if (field_ptr)
 
3557
    {
 
3558
      /*
 
3559
        field_ptr points to field in TableShare. Convert it to the matching
 
3560
        field in table
 
3561
      */
 
3562
      field_ptr= (field + (field_ptr - s->field));
 
3563
    }
 
3564
  }
 
3565
  else
 
3566
  {
 
3567
    if (!(field_ptr= field))
 
3568
      return (Field *)0;
 
3569
    for (; *field_ptr; ++field_ptr)
 
3570
      if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
 
3571
        break;
 
3572
  }
 
3573
  if (field_ptr)
 
3574
    return *field_ptr;
 
3575
  else
 
3576
    return (Field *)0;
 
3577
}
 
3578
 
1756
3579
 
1757
3580
/*
1758
 
  Is this instance of the table should be reopen or represents a name-lock?
 
3581
  Used by ALTER Table when the table is a temporary one. It changes something
 
3582
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old
 
3583
  name).
 
3584
  Prepares a table cache key, which is the concatenation of db, table_name and
 
3585
  session->slave_proxy_id, separated by '\0'.
1759
3586
*/
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 */
 
3587
 
 
3588
bool Table::rename_temporary_table(const char *db, const char *table_name)
 
3589
{
 
3590
  char *key;
 
3591
  uint32_t key_length;
 
3592
  TableShare *share= s;
 
3593
 
 
3594
  if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
 
3595
    return true;                                /* purecov: inspected */
 
3596
 
 
3597
  key_length= TableShare::createKey(key, db, table_name);
 
3598
  share->set_table_cache_key(key, key_length);
 
3599
 
 
3600
  return false;
 
3601
}
 
3602
 
 
3603
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
3604
template class List<String>;
 
3605
template class List_iterator<String>;
 
3606
#endif