~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-04-27 14:36:40 UTC
  • Revision ID: brian@gaz-20090427143640-f6zjmtt9vm55qgm2
Patch on show processlist from  davi@apache.org

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
/* Some general useful functions */
18
18
 
19
19
#include <drizzled/server_includes.h>
20
 
#include <drizzled/drizzled_error_messages.h>
21
 
 
22
 
#include "tmp_table.h"
23
 
#include "sj_tmp_table.h"
24
 
 
25
 
/* INFORMATION_SCHEMA name */
26
 
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
 
20
#include <drizzled/error.h>
 
21
#include <drizzled/gettext.h>
 
22
 
 
23
#include <drizzled/sj_tmp_table.h>
 
24
#include <drizzled/nested_join.h>
 
25
#include <drizzled/data_home.h>
 
26
#include <drizzled/sql_parse.h>
 
27
#include <drizzled/item/sum.h>
 
28
#include <drizzled/virtual_column_info.h>
 
29
#include <drizzled/table_list.h>
 
30
#include <drizzled/session.h>
 
31
#include <drizzled/sql_base.h>
 
32
#include <drizzled/field/blob.h>
 
33
#include <drizzled/field/varstring.h>
 
34
#include <drizzled/field/double.h>
 
35
#include <string>
 
36
#include <bitset>
 
37
 
 
38
#include <drizzled/unireg.h>
 
39
#include <drizzled/message/table.pb.h>
 
40
 
 
41
#include <drizzled/item/string.h>
 
42
#include <drizzled/item/int.h>
 
43
#include <drizzled/item/decimal.h>
 
44
#include <drizzled/item/float.h>
 
45
#include <drizzled/item/null.h>
 
46
 
 
47
 
 
48
using namespace std;
 
49
 
 
50
/* Keyword for parsing virtual column functions */
 
51
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
27
52
 
28
53
/* Functions defined in this file */
29
54
 
30
55
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
31
56
                      myf errortype, int errarg);
32
 
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
33
 
                           unsigned char *head, File file);
34
57
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
35
 
                              uint32_t types, char **names);
36
 
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length);
 
58
                              uint32_t types, char **names);
37
59
 
38
60
/*************************************************************************/
39
61
 
40
62
/* Get column name from column hash */
41
63
 
42
 
static unsigned char *get_field_name(Field **buff, size_t *length,
43
 
                             bool not_used __attribute__((unused)))
 
64
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
44
65
{
45
 
  *length= (uint) strlen((*buff)->field_name);
 
66
  *length= (uint32_t) strlen((*buff)->field_name);
46
67
  return (unsigned char*) (*buff)->field_name;
47
68
}
48
69
 
56
77
 
57
78
  DESCRIPTION
58
79
    Checks file name part starting with the rightmost '.' character,
59
 
    and returns it if it is equal to '.frm'. 
 
80
    and returns it if it is equal to '.frm'.
60
81
 
61
82
  TODO
62
83
    It is a good idea to get rid of this function modifying the code
71
92
char *fn_rext(char *name)
72
93
{
73
94
  char *res= strrchr(name, '.');
74
 
  if (res && !strcmp(res, reg_ext))
 
95
  if (res && !strcmp(res, ".dfe"))
75
96
    return res;
76
97
  return name + strlen(name);
77
98
}
81
102
  assert(db != NULL);
82
103
  assert(name != NULL);
83
104
 
84
 
  if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
 
105
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
85
106
      (my_strcasecmp(system_charset_info,
86
 
                    INFORMATION_SCHEMA_NAME.str,
 
107
                    INFORMATION_SCHEMA_NAME.c_str(),
87
108
                    db->str) == 0))
88
109
  {
89
110
    return TABLE_CATEGORY_INFORMATION;
132
153
 
133
154
    share->path.str= path_buff;
134
155
    share->path.length= path_length;
135
 
    my_stpcpy(share->path.str, path);
 
156
    strcpy(share->path.str, path);
136
157
    share->normalized_path.str=    share->path.str;
137
158
    share->normalized_path.length= path_length;
138
159
 
168
189
 
169
190
  SYNOPSIS
170
191
    init_tmp_table_share()
171
 
    thd         thread handle
 
192
    session         thread handle
172
193
    share       Share to fill
173
194
    key         Table_cache_key, as generated from create_table_def_key.
174
 
                must start with db name.    
 
195
                must start with db name.
175
196
    key_length  Length of key
176
197
    table_name  Table name
177
198
    path        Path to file (possible in lower case) without .frm
181
202
    don't have to be shared between threads or put into the table def
182
203
    cache, so we can do some things notable simpler and faster
183
204
 
184
 
    If table is not put in thd->temporary_tables (happens only when
 
205
    If table is not put in session->temporary_tables (happens only when
185
206
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
186
207
    use key_length= 0 as neither table_cache_key or key_length will be used).
187
208
*/
188
209
 
189
 
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
 
210
void init_tmp_table_share(Session *session, TABLE_SHARE *share, const char *key,
190
211
                          uint32_t key_length, const char *table_name,
191
212
                          const char *path)
192
213
{
204
225
  share->path.str=               (char*) path;
205
226
  share->normalized_path.str=    (char*) path;
206
227
  share->path.length= share->normalized_path.length= strlen(path);
207
 
  share->frm_version=            FRM_VER_TRUE_VARCHAR;
 
228
 
208
229
  /*
209
230
    Temporary tables are not replicated, but we set up these fields
210
231
    anyway to be able to catch errors.
216
237
    table_map_id is also used for MERGE tables to suppress repeated
217
238
    compatibility checks.
218
239
  */
219
 
  share->table_map_id= (ulong) thd->query_id;
 
240
  share->table_map_id= (ulong) session->query_id;
220
241
 
221
242
  return;
222
243
}
256
277
    pthread_cond_destroy(&share->cond);
257
278
  }
258
279
  hash_free(&share->name_hash);
259
 
  
260
 
  plugin_unlock(NULL, share->db_plugin);
261
 
  share->db_plugin= NULL;
 
280
 
 
281
  share->storage_engine= NULL;
262
282
 
263
283
  /* We must copy mem_root from share because share is allocated through it */
264
284
  memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
266
286
  return;
267
287
}
268
288
 
269
 
/*
270
 
  Read table definition from a binary / text based .frm file
271
 
  
272
 
  SYNOPSIS
273
 
  open_table_def()
274
 
  thd           Thread handler
275
 
  share         Fill this with table definition
276
 
  db_flags      Bit mask of the following flags: OPEN_VIEW
277
 
 
278
 
  NOTES
279
 
    This function is called when the table definition is not cached in
280
 
    table_def_cache
281
 
    The data is returned in 'share', which is alloced by
282
 
    alloc_table_share().. The code assumes that share is initialized.
283
 
 
284
 
  RETURN VALUES
285
 
   0    ok
286
 
   1    Error (see open_table_error)
287
 
   2    Error (see open_table_error)
288
 
   3    Wrong data in .frm file
289
 
   4    Error (see open_table_error)
290
 
   5    Error (see open_table_error: charset unavailable)
291
 
   6    Unknown .frm version
292
 
*/
293
 
 
294
 
int open_table_def(THD *thd, TABLE_SHARE *share, uint32_t db_flags  __attribute__((unused)))
 
289
enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
295
290
{
296
 
  int error, table_type;
297
 
  bool error_given;
298
 
  File file;
299
 
  unsigned char head[64], *disk_buff;
300
 
  char  path[FN_REFLEN];
301
 
  MEM_ROOT **root_ptr, *old_root;
302
 
 
303
 
  error= 1;
304
 
  error_given= 0;
305
 
  disk_buff= NULL;
306
 
 
307
 
  strxmov(path, share->normalized_path.str, reg_ext, NULL);
308
 
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
309
 
  {
310
 
    /*
311
 
      We don't try to open 5.0 unencoded name, if
312
 
      - non-encoded name contains '@' signs, 
313
 
        because '@' can be misinterpreted.
314
 
        It is not clear if '@' is escape character in 5.1,
315
 
        or a normal character in 5.0.
316
 
        
317
 
      - non-encoded db or table name contain "#mysql50#" prefix.
318
 
        This kind of tables must have been opened only by the
319
 
        my_open() above.
320
 
    */
321
 
    if (strchr(share->table_name.str, '@') ||
322
 
        !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
323
 
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
324
 
        !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
325
 
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
326
 
      goto err_not_open;
327
 
 
328
 
    /* Try unencoded 5.0 name */
329
 
    uint32_t length;
330
 
    strxnmov(path, sizeof(path)-1,
331
 
             mysql_data_home, "/", share->db.str, "/",
332
 
             share->table_name.str, reg_ext, NULL);
333
 
    length= unpack_filename(path, path) - reg_ext_length;
334
 
    /*
335
 
      The following is a safety test and should never fail
336
 
      as the old file name should never be longer than the new one.
337
 
    */
338
 
    assert(length <= share->normalized_path.length);
339
 
    /*
340
 
      If the old and the new names have the same length,
341
 
      then table name does not have tricky characters,
342
 
      so no need to check the old file name.
343
 
    */
344
 
    if (length == share->normalized_path.length ||
345
 
        ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
346
 
      goto err_not_open;
347
 
 
348
 
    /* Unencoded 5.0 table name found */
349
 
    path[length]= '\0'; // Remove .frm extension
350
 
    my_stpcpy(share->normalized_path.str, path);
351
 
    share->normalized_path.length= length;
352
 
  }
353
 
 
354
 
  error= 4;
355
 
  if (my_read(file, head, 64, MYF(MY_NABP)))
356
 
    goto err;
357
 
 
358
 
  if (head[0] == (unsigned char) 254 && head[1] == 1)
359
 
  {
360
 
    if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
361
 
        (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
362
 
    {
363
 
      table_type= 1;
364
 
    }
365
 
    else
366
 
    {
367
 
      error= 6;                                 // Unkown .frm version
368
 
      goto err;
369
 
    }
370
 
  }
371
 
  else
372
 
    goto err;
373
 
 
374
 
  /* No handling of text based files yet */
375
 
  if (table_type == 1)
376
 
  {
377
 
    root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
378
 
    old_root= *root_ptr;
379
 
    *root_ptr= &share->mem_root;
380
 
    error= open_binary_frm(thd, share, head, file);
381
 
    *root_ptr= old_root;
382
 
    error_given= 1;
383
 
  }
384
 
  else
 
291
  enum_field_types field_type;
 
292
 
 
293
  switch(proto_field_type)
 
294
  {
 
295
  case drizzled::message::Table::Field::TINYINT:
 
296
    field_type= DRIZZLE_TYPE_TINY;
 
297
    break;
 
298
  case drizzled::message::Table::Field::INTEGER:
 
299
    field_type= DRIZZLE_TYPE_LONG;
 
300
    break;
 
301
  case drizzled::message::Table::Field::DOUBLE:
 
302
    field_type= DRIZZLE_TYPE_DOUBLE;
 
303
    break;
 
304
  case drizzled::message::Table::Field::TIMESTAMP:
 
305
    field_type= DRIZZLE_TYPE_TIMESTAMP;
 
306
    break;
 
307
  case drizzled::message::Table::Field::BIGINT:
 
308
    field_type= DRIZZLE_TYPE_LONGLONG;
 
309
    break;
 
310
  case drizzled::message::Table::Field::DATETIME:
 
311
    field_type= DRIZZLE_TYPE_DATETIME;
 
312
    break;
 
313
  case drizzled::message::Table::Field::DATE:
 
314
    field_type= DRIZZLE_TYPE_DATE;
 
315
    break;
 
316
  case drizzled::message::Table::Field::VARCHAR:
 
317
    field_type= DRIZZLE_TYPE_VARCHAR;
 
318
    break;
 
319
  case drizzled::message::Table::Field::DECIMAL:
 
320
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
321
    break;
 
322
  case drizzled::message::Table::Field::ENUM:
 
323
    field_type= DRIZZLE_TYPE_ENUM;
 
324
    break;
 
325
  case drizzled::message::Table::Field::BLOB:
 
326
    field_type= DRIZZLE_TYPE_BLOB;
 
327
    break;
 
328
  case drizzled::message::Table::Field::VIRTUAL:
 
329
    field_type= DRIZZLE_TYPE_VIRTUAL;
 
330
    break;
 
331
  default:
 
332
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
385
333
    assert(1);
386
 
 
387
 
  share->table_category= get_table_category(& share->db, & share->table_name);
388
 
 
389
 
  if (!error)
390
 
    thd->status_var.opened_shares++;
391
 
 
392
 
err:
393
 
  my_close(file, MYF(MY_WME));
394
 
 
395
 
err_not_open:
396
 
  if (error && !error_given)
397
 
  {
398
 
    share->error= error;
399
 
    open_table_error(share, error, (share->open_errno= my_errno), 0);
400
 
  }
401
 
 
402
 
  return(error);
403
 
}
404
 
 
405
 
 
406
 
/*
407
 
  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
408
 
*/
409
 
 
410
 
static int open_binary_frm(THD *thd, TABLE_SHARE *share, unsigned char *head,
411
 
                           File file)
412
 
{
413
 
  int error, errarg= 0;
414
 
  uint32_t new_frm_ver, field_pack_length, new_field_pack_flag;
415
 
  uint32_t interval_count, interval_parts, read_length, int_length;
416
 
  uint32_t db_create_options, keys, key_parts, n_length;
417
 
  uint32_t key_info_length, com_length, null_bit_pos=0;
418
 
  uint32_t extra_rec_buf_length;
419
 
  uint32_t i,j;
420
 
  bool use_hash;
421
 
  unsigned char forminfo[288];
422
 
  char *keynames, *names, *comment_pos;
423
 
  unsigned char *record;
424
 
  unsigned char *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
425
 
  ulong pos, record_offset, *rec_per_key, rec_buff_length;
426
 
  handler *handler_file= 0;
427
 
  KEY   *keyinfo;
428
 
  KEY_PART_INFO *key_part;
429
 
  Field  **field_ptr, *reg_field;
430
 
  const char **interval_array;
431
 
  enum legacy_db_type legacy_db_type;
432
 
  my_bitmap_map *bitmaps;
433
 
  unsigned char *buff= 0;
434
 
  unsigned char *field_extra_info= 0;
435
 
 
436
 
  new_field_pack_flag= head[27];
437
 
  new_frm_ver= (head[2] - FRM_VER);
438
 
  field_pack_length= new_frm_ver < 2 ? 11 : 17;
439
 
  disk_buff= 0;
440
 
 
441
 
  error= 3;
442
 
  if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
443
 
    goto err;                                   /* purecov: inspected */
444
 
  my_seek(file,pos,MY_SEEK_SET,MYF(0));
445
 
  if (my_read(file,forminfo,288,MYF(MY_NABP)))
446
 
    goto err;
447
 
 
448
 
  share->frm_version= head[2];
449
 
  /*
450
 
    Check if .frm file created by MySQL 5.0. In this case we want to
451
 
    display CHAR fields as CHAR and not as VARCHAR.
452
 
    We do it this way as we want to keep the old frm version to enable
453
 
    MySQL 4.1 to read these files.
454
 
  */
455
 
  if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
456
 
    share->frm_version= FRM_VER_TRUE_VARCHAR;
457
 
 
458
 
  legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
459
 
  assert(share->db_plugin == NULL);
460
 
  /*
461
 
    if the storage engine is dynamic, no point in resolving it by its
462
 
    dynamically allocated legacy_db_type. We will resolve it later by name.
463
 
  */
464
 
  if (legacy_db_type > DB_TYPE_UNKNOWN && 
465
 
      legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
466
 
    share->db_plugin= ha_lock_engine(NULL, 
467
 
                                     ha_checktype(thd, legacy_db_type, 0, 0));
468
 
  share->db_create_options= db_create_options= uint2korr(head+30);
 
334
  }
 
335
 
 
336
  return field_type;
 
337
}
 
338
 
 
339
Item * default_value_item(enum_field_types field_type,
 
340
                          const CHARSET_INFO *charset,
 
341
                          bool default_null, const string *default_value,
 
342
                          const string *default_bin_value)
 
343
{
 
344
  Item *default_item= NULL;
 
345
  int error= 0;
 
346
 
 
347
  if(default_null)
 
348
  {
 
349
    return new Item_null();
 
350
  }
 
351
 
 
352
  switch(field_type)
 
353
  {
 
354
  case DRIZZLE_TYPE_TINY:
 
355
  case DRIZZLE_TYPE_LONG:
 
356
  case DRIZZLE_TYPE_LONGLONG:
 
357
    default_item= new Item_int(default_value->c_str(),
 
358
                               (int64_t) my_strtoll10(default_value->c_str(),
 
359
                                                      NULL,
 
360
                                                      &error),
 
361
                               default_value->length());
 
362
    break;
 
363
  case DRIZZLE_TYPE_DOUBLE:
 
364
    default_item= new Item_float(default_value->c_str(),
 
365
                                 default_value->length());
 
366
    break;
 
367
  case DRIZZLE_TYPE_NULL:
 
368
    assert(false);
 
369
  case DRIZZLE_TYPE_TIMESTAMP:
 
370
  case DRIZZLE_TYPE_DATETIME:
 
371
  case DRIZZLE_TYPE_DATE:
 
372
    if(default_value->compare("NOW()")==0)
 
373
      break;
 
374
  case DRIZZLE_TYPE_ENUM:
 
375
    default_item= new Item_string(default_value->c_str(),
 
376
                                  default_value->length(),
 
377
                                  system_charset_info);
 
378
    break;
 
379
  case DRIZZLE_TYPE_VARCHAR:
 
380
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
 
381
    if(charset==&my_charset_bin)
 
382
    {
 
383
      default_item= new Item_string(default_bin_value->c_str(),
 
384
                                    default_bin_value->length(),
 
385
                                    &my_charset_bin);
 
386
    }
 
387
    else
 
388
    {
 
389
      default_item= new Item_string(default_value->c_str(),
 
390
                                    default_value->length(),
 
391
                                    system_charset_info);
 
392
    }
 
393
    break;
 
394
  case DRIZZLE_TYPE_VIRTUAL:
 
395
    break;
 
396
  case DRIZZLE_TYPE_NEWDECIMAL:
 
397
    default_item= new Item_decimal(default_value->c_str(),
 
398
                                   default_value->length(),
 
399
                                   system_charset_info);
 
400
    break;
 
401
  }
 
402
 
 
403
  return default_item;
 
404
}
 
405
 
 
406
int parse_table_proto(Session *session, drizzled::message::Table &table, TABLE_SHARE *share)
 
407
{
 
408
  int error= 0;
 
409
  handler *handler_file= NULL;
 
410
 
 
411
  {
 
412
    LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
 
413
                              strlen(table.engine().name().c_str()) };
 
414
    share->storage_engine= ha_resolve_by_name(session, &engine_name);
 
415
  }
 
416
 
 
417
  share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
 
418
 
 
419
  drizzled::message::Table::TableOptions table_options;
 
420
 
 
421
  if(table.has_options())
 
422
    table_options= table.options();
 
423
 
 
424
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
 
425
 
 
426
  if(table_options.has_pack_keys())
 
427
  {
 
428
    if(table_options.pack_keys())
 
429
      db_create_options|= HA_OPTION_PACK_KEYS;
 
430
    else
 
431
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
 
432
  }
 
433
 
 
434
  if(table_options.pack_record())
 
435
    db_create_options|= HA_OPTION_PACK_RECORD;
 
436
 
 
437
  if(table_options.has_checksum())
 
438
  {
 
439
    if(table_options.checksum())
 
440
      db_create_options|= HA_OPTION_CHECKSUM;
 
441
    else
 
442
      db_create_options|= HA_OPTION_NO_CHECKSUM;
 
443
  }
 
444
 
 
445
  if(table_options.has_delay_key_write())
 
446
  {
 
447
    if(table_options.delay_key_write())
 
448
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
 
449
    else
 
450
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
 
451
  }
 
452
 
 
453
  /* db_create_options was stored as 2 bytes in FRM
 
454
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
 
455
   */
 
456
  share->db_create_options= (db_create_options & 0x0000FFFF);
469
457
  share->db_options_in_use= share->db_create_options;
470
 
  share->mysql_version= uint4korr(head+51);
471
 
  share->null_field_first= 0;
472
 
  if (!head[32])                                // New frm file in 3.23
473
 
  {
474
 
    share->avg_row_length= uint4korr(head+34);
475
 
    share->transactional= (ha_choice) (head[39] & 3);
476
 
    share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
477
 
    share->row_type= (row_type) head[40];
478
 
    share->block_size= uint4korr(head+43);
479
 
    share->table_charset= get_charset((uint) head[38],MYF(0));
480
 
    share->null_field_first= 1;
481
 
  }
 
458
 
 
459
 
 
460
  share->avg_row_length= table_options.has_avg_row_length() ?
 
461
    table_options.avg_row_length() : 0;
 
462
 
 
463
  share->page_checksum= table_options.has_page_checksum() ?
 
464
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
465
    : HA_CHOICE_UNDEF;
 
466
 
 
467
  share->row_type= table_options.has_row_type() ?
 
468
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
469
 
 
470
  share->block_size= table_options.has_block_size() ?
 
471
    table_options.block_size() : 0;
 
472
 
 
473
  share->table_charset= get_charset(table_options.has_collation_id()?
 
474
                                    table_options.collation_id() : 0);
 
475
 
482
476
  if (!share->table_charset)
483
477
  {
484
478
    /* unknown charset in head[38] or pre-3.23 frm */
485
479
    if (use_mb(default_charset_info))
486
480
    {
487
481
      /* Warn that we may be changing the size of character columns */
488
 
      sql_print_warning(_("'%s' had no or invalid character set, "
489
 
                        "and default character set is multi-byte, "
490
 
                        "so character column sizes may have changed"),
491
 
                        share->path.str);
 
482
      errmsg_printf(ERRMSG_LVL_WARN,
 
483
                    _("'%s' had no or invalid character set, "
 
484
                      "and default character set is multi-byte, "
 
485
                      "so character column sizes may have changed"),
 
486
                    share->path.str);
492
487
    }
493
488
    share->table_charset= default_charset_info;
494
489
  }
 
490
 
495
491
  share->db_record_offset= 1;
496
 
  if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
497
 
    share->blob_ptr_size= portable_sizeof_char_ptr;
498
 
  /* Set temporarily a good value for db_low_byte_first */
 
492
 
 
493
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
494
 
499
495
  share->db_low_byte_first= true;
500
 
  error=4;
501
 
  share->max_rows= uint4korr(head+18);
502
 
  share->min_rows= uint4korr(head+22);
503
 
 
504
 
  /* Read keyinformation */
505
 
  key_info_length= (uint) uint2korr(head+28);
506
 
  my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0));
507
 
  if (read_string(file,(unsigned char**) &disk_buff,key_info_length))
508
 
    goto err;                                   /* purecov: inspected */
509
 
  if (disk_buff[0] & 0x80)
510
 
  {
511
 
    share->keys=      keys=      (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
512
 
    share->key_parts= key_parts= uint2korr(disk_buff+2);
513
 
  }
514
 
  else
515
 
  {
516
 
    share->keys=      keys=      disk_buff[0];
517
 
    share->key_parts= key_parts= disk_buff[1];
518
 
  }
519
 
  share->keys_for_keyread.init(0);
520
 
  share->keys_in_use.init(keys);
521
 
 
522
 
  n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
523
 
  if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
524
 
                                    n_length + uint2korr(disk_buff+4))))
525
 
    goto err;                                   /* purecov: inspected */
526
 
  memset(keyinfo, 0, n_length);
527
 
  share->key_info= keyinfo;
528
 
  key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
529
 
  strpos=disk_buff+6;
530
 
 
531
 
  if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
532
 
                                         sizeof(ulong*)*key_parts)))
533
 
    goto err;
534
 
 
535
 
  for (i=0 ; i < keys ; i++, keyinfo++)
536
 
  {
537
 
    keyinfo->table= 0;                           // Updated in open_frm
538
 
    if (new_frm_ver >= 3)
539
 
    {
540
 
      keyinfo->flags=      (uint) uint2korr(strpos) ^ HA_NOSAME;
541
 
      keyinfo->key_length= (uint) uint2korr(strpos+2);
542
 
      keyinfo->key_parts=  (uint) strpos[4];
543
 
      keyinfo->algorithm=  (enum ha_key_alg) strpos[5];
544
 
      keyinfo->block_size= uint2korr(strpos+6);
545
 
      strpos+=8;
546
 
    }
547
 
 
548
 
    keyinfo->key_part=   key_part;
 
496
 
 
497
  share->max_rows= table_options.has_max_rows() ?
 
498
    table_options.max_rows() : 0;
 
499
 
 
500
  share->min_rows= table_options.has_min_rows() ?
 
501
    table_options.min_rows() : 0;
 
502
 
 
503
  share->keys= table.indexes_size();
 
504
 
 
505
  share->key_parts= 0;
 
506
  for(int indx= 0; indx < table.indexes_size(); indx++)
 
507
    share->key_parts+= table.indexes(indx).index_part_size();
 
508
 
 
509
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
510
                                     table.indexes_size() * sizeof(KEY)
 
511
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
512
 
 
513
  KEY_PART_INFO *key_part;
 
514
 
 
515
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
516
    (share->key_info+table.indexes_size());
 
517
 
 
518
 
 
519
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
520
                                            sizeof(ulong*)*share->key_parts);
 
521
 
 
522
  share->keynames.count= table.indexes_size();
 
523
  share->keynames.name= NULL;
 
524
  share->keynames.type_names= (const char**)
 
525
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
526
 
 
527
  share->keynames.type_lengths= (unsigned int*)
 
528
    alloc_root(&share->mem_root,
 
529
               sizeof(unsigned int) * (table.indexes_size()+1));
 
530
 
 
531
  share->keynames.type_names[share->keynames.count]= NULL;
 
532
  share->keynames.type_lengths[share->keynames.count]= 0;
 
533
 
 
534
  KEY* keyinfo= share->key_info;
 
535
  for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
536
  {
 
537
    drizzled::message::Table::Index indx= table.indexes(keynr);
 
538
 
 
539
    keyinfo->table= 0;
 
540
    keyinfo->flags= 0;
 
541
 
 
542
    if(indx.is_unique())
 
543
      keyinfo->flags|= HA_NOSAME;
 
544
 
 
545
    if(indx.has_options())
 
546
    {
 
547
      drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
 
548
      if(indx_options.pack_key())
 
549
        keyinfo->flags|= HA_PACK_KEY;
 
550
 
 
551
      if(indx_options.var_length_key())
 
552
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
553
 
 
554
      if(indx_options.null_part_key())
 
555
        keyinfo->flags|= HA_NULL_PART_KEY;
 
556
 
 
557
      if(indx_options.binary_pack_key())
 
558
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
559
 
 
560
      if(indx_options.has_partial_segments())
 
561
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
562
 
 
563
      if(indx_options.auto_generated_key())
 
564
        keyinfo->flags|= HA_GENERATED_KEY;
 
565
 
 
566
      if(indx_options.has_key_block_size())
 
567
      {
 
568
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
569
        keyinfo->block_size= indx_options.key_block_size();
 
570
      }
 
571
      else
 
572
      {
 
573
        keyinfo->block_size= 0;
 
574
      }
 
575
 
 
576
    }
 
577
 
 
578
    switch(indx.type())
 
579
    {
 
580
    case drizzled::message::Table::Index::UNKNOWN_INDEX:
 
581
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
582
      break;
 
583
    case drizzled::message::Table::Index::BTREE:
 
584
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
585
      break;
 
586
    case drizzled::message::Table::Index::RTREE:
 
587
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
588
      break;
 
589
    case drizzled::message::Table::Index::HASH:
 
590
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
591
      break;
 
592
    case drizzled::message::Table::Index::FULLTEXT:
 
593
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
594
 
 
595
    default:
 
596
      /* TODO: suitable warning ? */
 
597
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
598
      break;
 
599
    }
 
600
 
 
601
    keyinfo->key_length= indx.key_length();
 
602
 
 
603
    keyinfo->key_parts= indx.index_part_size();
 
604
 
 
605
    keyinfo->key_part= key_part;
549
606
    keyinfo->rec_per_key= rec_per_key;
550
 
    for (j=keyinfo->key_parts ; j-- ; key_part++)
 
607
 
 
608
    for(unsigned int partnr= 0;
 
609
        partnr < keyinfo->key_parts;
 
610
        partnr++, key_part++)
551
611
    {
 
612
      drizzled::message::Table::Index::IndexPart part;
 
613
      part= indx.index_part(partnr);
 
614
 
552
615
      *rec_per_key++=0;
553
 
      key_part->fieldnr=        (uint16_t) (uint2korr(strpos) & FIELD_NR_MASK);
554
 
      key_part->offset= (uint) uint2korr(strpos+2)-1;
555
 
      key_part->key_type=       (uint) uint2korr(strpos+5);
556
 
      // key_part->field=       (Field*) 0;     // Will be fixed later
557
 
      if (new_frm_ver >= 1)
558
 
      {
559
 
        key_part->key_part_flag= *(strpos+4);
560
 
        key_part->length=       (uint) uint2korr(strpos+7);
561
 
        strpos+=9;
562
 
      }
563
 
      else
564
 
      {
565
 
        key_part->length=       *(strpos+4);
566
 
        key_part->key_part_flag=0;
567
 
        if (key_part->length > 128)
568
 
        {
569
 
          key_part->length&=127;                /* purecov: inspected */
570
 
          key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
571
 
        }
572
 
        strpos+=7;
573
 
      }
574
 
      key_part->store_length=key_part->length;
575
 
    }
576
 
  }
577
 
  keynames=(char*) key_part;
578
 
  strpos+= (my_stpcpy(keynames, (char *) strpos) - keynames)+1;
579
 
 
580
 
  //reading index comments
581
 
  for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
582
 
  {
583
 
    if (keyinfo->flags & HA_USES_COMMENT)
584
 
    {
585
 
      keyinfo->comment.length= uint2korr(strpos);
586
 
      keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
587
 
                                         keyinfo->comment.length);
588
 
      strpos+= 2 + keyinfo->comment.length;
589
 
    } 
590
 
    assert(test(keyinfo->flags & HA_USES_COMMENT) == 
591
 
               (keyinfo->comment.length > 0));
592
 
  }
593
 
 
594
 
  share->reclength = uint2korr((head+16));
595
 
 
596
 
  record_offset= (ulong) (uint2korr(head+6)+
597
 
                          ((uint2korr(head+14) == 0xffff ?
598
 
                            uint4korr(head+47) : uint2korr(head+14))));
599
 
 
600
 
  if ((n_length= uint4korr(head+55)))
601
 
  {
602
 
    /* Read extra data segment */
603
 
    unsigned char *next_chunk, *buff_end;
604
 
    if (!(next_chunk= buff= (unsigned char*) my_malloc(n_length, MYF(MY_WME))))
605
 
      goto err;
606
 
    if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
607
 
    {
608
 
      goto err;
609
 
    }
610
 
    share->connect_string.length= uint2korr(buff);
611
 
    if (!(share->connect_string.str= strmake_root(&share->mem_root,
612
 
                                                  (char*) next_chunk + 2,
613
 
                                                  share->connect_string.
614
 
                                                  length)))
615
 
    {
616
 
      goto err;
617
 
    }
618
 
    next_chunk+= share->connect_string.length + 2;
619
 
    buff_end= buff + n_length;
620
 
    if (next_chunk + 2 < buff_end)
621
 
    {
622
 
      uint32_t str_db_type_length= uint2korr(next_chunk);
623
 
      LEX_STRING name;
624
 
      name.str= (char*) next_chunk + 2;
625
 
      name.length= str_db_type_length;
626
 
 
627
 
      plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
628
 
      if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
629
 
      {
630
 
        if (legacy_db_type > DB_TYPE_UNKNOWN &&
631
 
            legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
632
 
            legacy_db_type != ha_legacy_type(
633
 
                plugin_data(tmp_plugin, handlerton *)))
634
 
        {
635
 
          /* bad file, legacy_db_type did not match the name */
636
 
          free(buff);
637
 
          goto err;
638
 
        }
639
 
        /*
640
 
          tmp_plugin is locked with a local lock.
641
 
          we unlock the old value of share->db_plugin before
642
 
          replacing it with a globally locked version of tmp_plugin
643
 
        */
644
 
        plugin_unlock(NULL, share->db_plugin);
645
 
        share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
646
 
      }
647
 
      else if (!tmp_plugin)
648
 
      {
649
 
        /* purecov: begin inspected */
650
 
        error= 8;
651
 
        my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
652
 
        free(buff);
653
 
        goto err;
654
 
        /* purecov: end */
655
 
      }
656
 
      next_chunk+= str_db_type_length + 2;
657
 
    }
658
 
    if (share->mysql_version >= 50110)
659
 
    {
660
 
      /* New auto_partitioned indicator introduced in 5.1.11 */
661
 
      next_chunk++;
662
 
    }
663
 
    if (forminfo[46] == (unsigned char)255)
664
 
    {
665
 
      //reading long table comment
666
 
      if (next_chunk + 2 > buff_end)
667
 
      {
668
 
          free(buff);
669
 
          goto err;
670
 
      }
671
 
      share->comment.length = uint2korr(next_chunk);
672
 
      if (! (share->comment.str= strmake_root(&share->mem_root,
673
 
                               (char*)next_chunk + 2, share->comment.length)))
674
 
      {
675
 
          free(buff);
676
 
          goto err;
677
 
      }
678
 
      next_chunk+= 2 + share->comment.length;
679
 
    }
680
 
    assert(next_chunk <= buff_end);
681
 
    if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
682
 
    {
683
 
      /*
684
 
       New frm format in mysql_version 5.2.5 (originally in
685
 
       mysql-5.1.22-ndb-6.2.5)
686
 
       New column properties added:
687
 
       COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
688
 
       TABLESPACE name is now stored in frm
689
 
      */
690
 
      if (next_chunk >= buff_end)
691
 
      {
692
 
        if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
693
 
        {
694
 
          goto err;
695
 
        }
696
 
      }
697
 
      else
698
 
      {
699
 
        const uint32_t format_section_header_size= 8;
700
 
        uint32_t format_section_len= uint2korr(next_chunk+0);
701
 
 
702
 
        field_extra_info= next_chunk + format_section_header_size + 1;
703
 
        next_chunk+= format_section_len;
704
 
      }
705
 
    }
706
 
    assert (next_chunk <= buff_end);
707
 
    if (next_chunk > buff_end)
708
 
    {
709
 
      goto err;
710
 
    }
711
 
  }
712
 
  share->key_block_size= uint2korr(head+62);
713
 
 
714
 
  error=4;
715
 
  extra_rec_buf_length= uint2korr(head+59);
716
 
  rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
 
616
 
 
617
      key_part->field= NULL;
 
618
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
 
619
      key_part->null_bit= 0;
 
620
      /* key_part->null_offset is only set if null_bit (see later) */
 
621
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
622
      /* key_part->type ???? */
 
623
      key_part->key_part_flag= 0;
 
624
      if(part.has_in_reverse_order())
 
625
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
626
 
 
627
      key_part->length= part.compare_length();
 
628
 
 
629
      key_part->store_length= key_part->length;
 
630
 
 
631
      /* key_part->offset is set later */
 
632
      key_part->key_type= part.key_type();
 
633
 
 
634
    }
 
635
 
 
636
    if(!indx.has_comment())
 
637
    {
 
638
      keyinfo->comment.length= 0;
 
639
      keyinfo->comment.str= NULL;
 
640
    }
 
641
    else
 
642
    {
 
643
      keyinfo->flags|= HA_USES_COMMENT;
 
644
      keyinfo->comment.length= indx.comment().length();
 
645
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
646
                                         indx.comment().c_str(),
 
647
                                         keyinfo->comment.length);
 
648
    }
 
649
 
 
650
    keyinfo->name= strmake_root(&share->mem_root,
 
651
                                indx.name().c_str(),
 
652
                                indx.name().length());
 
653
 
 
654
    share->keynames.type_names[keynr]= keyinfo->name;
 
655
    share->keynames.type_lengths[keynr]= indx.name().length();
 
656
  }
 
657
 
 
658
  share->keys_for_keyread.init(0);
 
659
  share->keys_in_use.init(share->keys);
 
660
 
 
661
  if(table_options.has_connect_string())
 
662
  {
 
663
    size_t len= table_options.connect_string().length();
 
664
    const char* str= table_options.connect_string().c_str();
 
665
 
 
666
    share->connect_string.length= len;
 
667
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
668
  }
 
669
 
 
670
  if(table_options.has_comment())
 
671
  {
 
672
    size_t len= table_options.comment().length();
 
673
    const char* str= table_options.comment().c_str();
 
674
 
 
675
    share->comment.length= len;
 
676
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
677
  }
 
678
 
 
679
  share->key_block_size= table_options.has_key_block_size() ?
 
680
    table_options.key_block_size() : 0;
 
681
 
 
682
  share->fields= table.field_size();
 
683
  share->vfields= 0;
 
684
  share->stored_fields= share->fields;
 
685
 
 
686
  share->field= (Field**) alloc_root(&share->mem_root,
 
687
                                     ((share->fields+1) * sizeof(Field*)));
 
688
  share->field[share->fields]= NULL;
 
689
 
 
690
  uint32_t null_fields= 0;
 
691
  share->reclength= 0;
 
692
 
 
693
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
 
694
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
 
695
 
 
696
  assert(field_offsets && field_pack_length); // TODO: fixme
 
697
 
 
698
  uint32_t interval_count= 0;
 
699
  uint32_t interval_parts= 0;
 
700
 
 
701
  uint32_t stored_columns_reclength= 0;
 
702
 
 
703
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
704
  {
 
705
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
706
    if(pfield.has_constraints() && pfield.constraints().is_nullable())
 
707
      null_fields++;
 
708
 
 
709
    bool field_is_stored= true;
 
710
 
 
711
    enum_field_types drizzle_field_type=
 
712
      proto_field_type_to_drizzle_type(pfield.type());
 
713
 
 
714
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
715
    {
 
716
      drizzled::message::Table::Field::VirtualFieldOptions field_options=
 
717
        pfield.virtual_options();
 
718
 
 
719
      drizzle_field_type=proto_field_type_to_drizzle_type(field_options.type());
 
720
 
 
721
      field_is_stored= field_options.physically_stored();
 
722
    }
 
723
 
 
724
    field_offsets[fieldnr]= stored_columns_reclength;
 
725
 
 
726
    /* the below switch is very similar to
 
727
       Create_field::create_length_to_internal_length in field.cc
 
728
       (which should one day be replace by just this code)
 
729
    */
 
730
    switch(drizzle_field_type)
 
731
    {
 
732
    case DRIZZLE_TYPE_BLOB:
 
733
    case DRIZZLE_TYPE_VARCHAR:
 
734
      {
 
735
        drizzled::message::Table::Field::StringFieldOptions field_options=
 
736
          pfield.string_options();
 
737
 
 
738
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
739
                                            field_options.collation_id() : 0);
 
740
 
 
741
        if (!cs)
 
742
          cs= default_charset_info;
 
743
 
 
744
        field_pack_length[fieldnr]=
 
745
          calc_pack_length(drizzle_field_type,
 
746
                           field_options.length() * cs->mbmaxlen);
 
747
 
 
748
      }
 
749
      break;
 
750
    case DRIZZLE_TYPE_ENUM:
 
751
      {
 
752
        drizzled::message::Table::Field::SetFieldOptions field_options=
 
753
          pfield.set_options();
 
754
 
 
755
        field_pack_length[fieldnr]=
 
756
          get_enum_pack_length(field_options.field_value_size());
 
757
 
 
758
        interval_count++;
 
759
        interval_parts+= field_options.field_value_size();
 
760
      }
 
761
      break;
 
762
    case DRIZZLE_TYPE_NEWDECIMAL:
 
763
      {
 
764
        drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
765
 
 
766
        field_pack_length[fieldnr]=
 
767
          my_decimal_get_binary_size(fo.precision(), fo.scale());
 
768
      }
 
769
      break;
 
770
    default:
 
771
      /* Zero is okay here as length is fixed for other types. */
 
772
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
 
773
    }
 
774
 
 
775
    share->reclength+= field_pack_length[fieldnr];
 
776
 
 
777
    if(field_is_stored)
 
778
      stored_columns_reclength+= field_pack_length[fieldnr];
 
779
  }
 
780
 
 
781
  /* data_offset added to stored_rec_length later */
 
782
  share->stored_rec_length= stored_columns_reclength;
 
783
 
 
784
  /* fix up offsets for non-stored fields (at end of record) */
 
785
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
786
  {
 
787
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
788
 
 
789
    bool field_is_stored= true;
 
790
 
 
791
    enum_field_types drizzle_field_type=
 
792
      proto_field_type_to_drizzle_type(pfield.type());
 
793
 
 
794
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
795
    {
 
796
      drizzled::message::Table::Field::VirtualFieldOptions field_options=
 
797
        pfield.virtual_options();
 
798
 
 
799
      field_is_stored= field_options.physically_stored();
 
800
    }
 
801
 
 
802
    if(!field_is_stored)
 
803
    {
 
804
      field_offsets[fieldnr]= stored_columns_reclength;
 
805
      stored_columns_reclength+= field_pack_length[fieldnr];
 
806
    }
 
807
  }
 
808
  share->null_fields= null_fields;
 
809
 
 
810
  ulong null_bits= null_fields;
 
811
  if(!table_options.pack_record())
 
812
    null_bits++;
 
813
  ulong data_offset= (null_bits + 7)/8;
 
814
 
 
815
 
 
816
  share->reclength+= data_offset;
 
817
  share->stored_rec_length+= data_offset;
 
818
 
 
819
  ulong rec_buff_length;
 
820
 
 
821
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
717
822
  share->rec_buff_length= rec_buff_length;
 
823
 
 
824
  unsigned char* record= NULL;
 
825
 
718
826
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
719
827
                                     rec_buff_length)))
720
 
    goto err;                                   /* purecov: inspected */
 
828
    abort();
 
829
 
 
830
  memset(record, 0, rec_buff_length);
 
831
 
 
832
  int null_count= 0;
 
833
 
 
834
  if(!table_options.pack_record())
 
835
  {
 
836
    null_count++; // one bit for delete mark.
 
837
    *record|= 1;
 
838
  }
 
839
 
721
840
  share->default_values= record;
722
 
  if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
723
 
    goto err;                                   /* purecov: inspected */
724
 
 
725
 
  my_seek(file,pos+288,MY_SEEK_SET,MYF(0));
726
 
 
727
 
  share->fields= uint2korr(forminfo+258);
728
 
  pos= uint2korr(forminfo+260);                 /* Length of all screens */
729
 
  n_length= uint2korr(forminfo+268);
730
 
  interval_count= uint2korr(forminfo+270);
731
 
  interval_parts= uint2korr(forminfo+272);
732
 
  int_length= uint2korr(forminfo+274);
733
 
  share->null_fields= uint2korr(forminfo+282);
734
 
  com_length= uint2korr(forminfo+284);
735
 
  if (forminfo[46] != (unsigned char)255)
 
841
 
 
842
  if(interval_count)
736
843
  {
737
 
    share->comment.length=  (int) (forminfo[46]);
738
 
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
739
 
                                     share->comment.length);
 
844
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
845
                                           interval_count*sizeof(TYPELIB));
740
846
  }
741
 
 
742
 
 
743
 
  if (!(field_ptr = (Field **)
744
 
        alloc_root(&share->mem_root,
745
 
                   (uint) ((share->fields+1)*sizeof(Field*)+
746
 
                           interval_count*sizeof(TYPELIB)+
747
 
                           (share->fields+interval_parts+
748
 
                            keys+3)*sizeof(char *)+
749
 
                           (n_length+int_length+com_length)))))
750
 
    goto err;                                   /* purecov: inspected */
751
 
 
752
 
  share->field= field_ptr;
753
 
  read_length=(uint) (share->fields * field_pack_length +
754
 
                      pos+ (uint) (n_length+int_length+com_length));
755
 
  if (read_string(file,(unsigned char**) &disk_buff,read_length))
756
 
    goto err;                                   /* purecov: inspected */
757
 
  strpos= disk_buff+pos;
758
 
 
759
 
  share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
760
 
  interval_array= (const char **) (share->intervals+interval_count);
761
 
  names= (char*) (interval_array+share->fields+interval_parts+keys+3);
762
 
  if (!interval_count)
763
 
    share->intervals= 0;                        // For better debugging
764
 
  memcpy(names, strpos+(share->fields*field_pack_length),
765
 
         (uint) (n_length+int_length));
766
 
  comment_pos= names+(n_length+int_length);
767
 
  memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
768
 
 
769
 
  fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
770
 
  if (share->fieldnames.count != share->fields)
771
 
    goto err;
772
 
  fix_type_pointers(&interval_array, share->intervals, interval_count,
773
 
                    &names);
774
 
 
 
847
  else
 
848
    share->intervals= NULL;
 
849
 
 
850
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
851
                                  (share->fields+1)*sizeof(char*));
 
852
 
 
853
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
854
                                  (share->fields+1)*sizeof(unsigned int));
 
855
 
 
856
  share->fieldnames.type_names[share->fields]= NULL;
 
857
  share->fieldnames.type_lengths[share->fields]= 0;
 
858
  share->fieldnames.count= share->fields;
 
859
 
 
860
 
 
861
  /* Now fix the TYPELIBs for the intervals (enum values)
 
862
     and field names.
 
863
   */
 
864
 
 
865
  uint32_t interval_nr= 0;
 
866
 
 
867
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
775
868
  {
776
 
    /* Set ENUM and SET lengths */
777
 
    TYPELIB *interval;
778
 
    for (interval= share->intervals;
779
 
         interval < share->intervals + interval_count;
780
 
         interval++)
 
869
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
870
 
 
871
    /* field names */
 
872
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
 
873
                                                        pfield.name().c_str(),
 
874
                                                        pfield.name().length());
 
875
 
 
876
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
 
877
 
 
878
    /* enum typelibs */
 
879
    if(pfield.type() != drizzled::message::Table::Field::ENUM)
 
880
      continue;
 
881
 
 
882
    drizzled::message::Table::Field::SetFieldOptions field_options=
 
883
      pfield.set_options();
 
884
 
 
885
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
886
                                             field_options.collation_id() : 0);
 
887
 
 
888
    if (!charset)
 
889
      charset= default_charset_info;
 
890
 
 
891
    TYPELIB *t= &(share->intervals[interval_nr]);
 
892
 
 
893
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
894
                           (field_options.field_value_size()+1)*sizeof(char*));
 
895
 
 
896
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
897
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
 
898
 
 
899
    t->type_names[field_options.field_value_size()]= NULL;
 
900
    t->type_lengths[field_options.field_value_size()]= 0;
 
901
 
 
902
    t->count= field_options.field_value_size();
 
903
    t->name= NULL;
 
904
 
 
905
    for(int n=0; n < field_options.field_value_size(); n++)
781
906
    {
782
 
      uint32_t count= (uint) (interval->count + 1) * sizeof(uint);
783
 
      if (!(interval->type_lengths= (uint32_t *) alloc_root(&share->mem_root,
784
 
                                                        count)))
785
 
        goto err;
786
 
      for (count= 0; count < interval->count; count++)
787
 
      {
788
 
        char *val= (char*) interval->type_names[count];
789
 
        interval->type_lengths[count]= strlen(val);
790
 
      }
791
 
      interval->type_lengths[count]= 0;
 
907
      t->type_names[n]= strmake_root(&share->mem_root,
 
908
                                     field_options.field_value(n).c_str(),
 
909
                                     field_options.field_value(n).length());
 
910
 
 
911
      /* Go ask the charset what the length is as for "" length=1
 
912
         and there's stripping spaces or some other crack going on.
 
913
       */
 
914
      uint32_t lengthsp;
 
915
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
916
                                        field_options.field_value(n).length());
 
917
      t->type_lengths[n]= lengthsp;
792
918
    }
793
 
  }
794
 
 
795
 
  if (keynames)
796
 
    fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
797
 
 
798
 
 /* Allocate handler */
799
 
  if (!(handler_file= get_new_handler(share, thd->mem_root,
800
 
                                      share->db_type())))
801
 
    goto err;
802
 
 
803
 
  record= share->default_values-1;              /* Fieldstart = 1 */
804
 
  if (share->null_field_first)
805
 
  {
806
 
    null_flags= null_pos= (unsigned char*) record+1;
807
 
    null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
808
 
    /*
809
 
      null_bytes below is only correct under the condition that
810
 
      there are no bit fields.  Correct values is set below after the
811
 
      table struct is initialized
812
 
    */
813
 
    share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
814
 
  }
815
 
 
816
 
  use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
817
 
  if (use_hash)
 
919
    interval_nr++;
 
920
  }
 
921
 
 
922
 
 
923
  /* and read the fields */
 
924
  interval_nr= 0;
 
925
 
 
926
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
927
 
 
928
  if(use_hash)
818
929
    use_hash= !hash_init(&share->name_hash,
819
930
                         system_charset_info,
820
 
                         share->fields,0,0,
821
 
                         (hash_get_key) get_field_name,0,0);
822
 
 
823
 
  for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
 
931
                         share->fields, 0, 0,
 
932
                         (hash_get_key) get_field_name, 0, 0);
 
933
 
 
934
  unsigned char* null_pos= record;;
 
935
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
 
936
 
 
937
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
824
938
  {
825
 
    uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
826
 
    enum_field_types field_type;
 
939
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
940
 
827
941
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
828
 
    const CHARSET_INFO *charset= NULL;
 
942
 
 
943
    switch(pfield.format())
 
944
    {
 
945
    case drizzled::message::Table::Field::DefaultFormat:
 
946
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
947
      break;
 
948
    case drizzled::message::Table::Field::FixedFormat:
 
949
      column_format= COLUMN_FORMAT_TYPE_FIXED;
 
950
      break;
 
951
    case drizzled::message::Table::Field::DynamicFormat:
 
952
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
 
953
      break;
 
954
    default:
 
955
      assert(1);
 
956
    }
 
957
 
 
958
    Field::utype unireg_type= Field::NONE;
 
959
 
 
960
    if(pfield.has_numeric_options()
 
961
       && pfield.numeric_options().is_autoincrement())
 
962
    {
 
963
      unireg_type= Field::NEXT_NUMBER;
 
964
    }
 
965
 
 
966
    if(pfield.has_options()
 
967
       && pfield.options().has_default_value()
 
968
       && pfield.options().default_value().compare("NOW()")==0)
 
969
    {
 
970
      if(pfield.options().has_update_value()
 
971
         && pfield.options().update_value().compare("NOW()")==0)
 
972
      {
 
973
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
974
      }
 
975
      else if (!pfield.options().has_update_value())
 
976
      {
 
977
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
978
      }
 
979
      else
 
980
        assert(1); // Invalid update value.
 
981
    }
 
982
    else if (pfield.has_options()
 
983
             && pfield.options().has_update_value()
 
984
             && pfield.options().update_value().compare("NOW()")==0)
 
985
    {
 
986
      unireg_type= Field::TIMESTAMP_UN_FIELD;
 
987
    }
 
988
 
829
989
    LEX_STRING comment;
830
 
 
831
 
    if (field_extra_info)
832
 
    {
833
 
      char tmp= field_extra_info[i];
834
 
      column_format= (enum column_format_type)
835
 
                    ((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
836
 
    }
837
 
    if (new_frm_ver >= 3)
838
 
    {
839
 
      /* new frm file in 4.1 */
840
 
      field_length= uint2korr(strpos+3);
841
 
      recpos=       uint3korr(strpos+5);
842
 
      pack_flag=    uint2korr(strpos+8);
843
 
      unireg_type=  (uint) strpos[10];
844
 
      interval_nr=  (uint) strpos[12];
845
 
      uint32_t comment_length=uint2korr(strpos+15);
846
 
      field_type=(enum_field_types) (uint) strpos[13];
847
 
 
848
 
      {
849
 
        if (!strpos[14])
850
 
          charset= &my_charset_bin;
851
 
        else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
852
 
        {
853
 
          error= 5; // Unknown or unavailable charset
854
 
          errarg= (int) strpos[14];
855
 
          goto err;
856
 
        }
857
 
      }
858
 
      if (!comment_length)
859
 
      {
860
 
        comment.str= (char*) "";
861
 
        comment.length=0;
862
 
      }
863
 
      else
864
 
      {
865
 
        comment.str=    (char*) comment_pos;
866
 
        comment.length= comment_length;
867
 
        comment_pos+=   comment_length;
868
 
      }
 
990
    if(!pfield.has_comment())
 
991
    {
 
992
      comment.str= (char*)"";
 
993
      comment.length= 0;
869
994
    }
870
995
    else
871
996
    {
872
 
      field_length= (uint) strpos[3];
873
 
      recpos=       uint2korr(strpos+4),
874
 
      pack_flag=    uint2korr(strpos+6);
875
 
      pack_flag&=   ~FIELDFLAG_NO_DEFAULT;     // Safety for old files
876
 
      unireg_type=  (uint) strpos[8];
877
 
      interval_nr=  (uint) strpos[10];
878
 
 
879
 
      /* old frm file */
880
 
      field_type= (enum_field_types) f_packtype(pack_flag);
881
 
      if (f_is_binary(pack_flag))
882
 
      {
883
 
        /*
884
 
          Try to choose the best 4.1 type:
885
 
          - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" 
886
 
            try to find a binary collation for character set.
887
 
          - for other types (e.g. BLOB) just use my_charset_bin. 
888
 
        */
889
 
        if (!f_is_blob(pack_flag))
890
 
        {
891
 
          // 3.23 or 4.0 string
892
 
          if (!(charset= get_charset_by_csname(share->table_charset->csname,
893
 
                                               MY_CS_BINSORT, MYF(0))))
894
 
            charset= &my_charset_bin;
895
 
        }
896
 
        else
897
 
          charset= &my_charset_bin;
898
 
      }
899
 
      else
900
 
        charset= share->table_charset;
901
 
      memset(&comment, 0, sizeof(comment));
902
 
    }
903
 
 
904
 
    if (interval_nr && charset->mbminlen > 1)
905
 
    {
906
 
      /* Unescape UCS2 intervals from HEX notation */
907
 
      TYPELIB *interval= share->intervals + interval_nr - 1;
908
 
      unhex_type2(interval);
909
 
    }
910
 
 
911
 
    *field_ptr= reg_field=
912
 
      make_field(share, record+recpos,
913
 
                 (uint32_t) field_length,
914
 
                 null_pos, null_bit_pos,
915
 
                 pack_flag,
916
 
                 field_type,
917
 
                 charset,
918
 
                 (Field::utype) MTYP_TYPENR(unireg_type),
919
 
                 (interval_nr ?
920
 
                  share->intervals+interval_nr-1 :
921
 
                  (TYPELIB*) 0),
922
 
                 share->fieldnames.type_names[i]);
923
 
    if (!reg_field)                             // Not supported field type
924
 
    {
925
 
      error= 4;
926
 
      goto err;                 /* purecov: inspected */
927
 
    }
928
 
 
929
 
    reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
930
 
    reg_field->field_index= i;
931
 
    reg_field->comment=comment;
932
 
    if (!(reg_field->flags & NOT_NULL_FLAG))
933
 
    {
 
997
      size_t len= pfield.comment().length();
 
998
      const char* str= pfield.comment().c_str();
 
999
 
 
1000
      comment.str= strmake_root(&share->mem_root, str, len);
 
1001
      comment.length= len;
 
1002
    }
 
1003
 
 
1004
    enum_field_types field_type;
 
1005
    virtual_column_info *vcol_info= NULL;
 
1006
    bool field_is_stored= true;
 
1007
 
 
1008
 
 
1009
    field_type= proto_field_type_to_drizzle_type(pfield.type());
 
1010
 
 
1011
    if(field_type==DRIZZLE_TYPE_VIRTUAL)
 
1012
    {
 
1013
      drizzled::message::Table::Field::VirtualFieldOptions field_options=
 
1014
        pfield.virtual_options();
 
1015
 
 
1016
      vcol_info= new virtual_column_info();
 
1017
      field_type= proto_field_type_to_drizzle_type(field_options.type());
 
1018
      field_is_stored= field_options.physically_stored();
 
1019
 
 
1020
      size_t len= field_options.expression().length();
 
1021
      const char* str= field_options.expression().c_str();
 
1022
 
 
1023
      vcol_info->expr_str.str= strmake_root(&share->mem_root, str, len);
 
1024
      vcol_info->expr_str.length= len;
 
1025
 
 
1026
      share->vfields++;
 
1027
    }
 
1028
 
 
1029
    const CHARSET_INFO *charset= &my_charset_bin;
 
1030
 
 
1031
    if(field_type==DRIZZLE_TYPE_BLOB
 
1032
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
1033
    {
 
1034
      drizzled::message::Table::Field::StringFieldOptions field_options=
 
1035
        pfield.string_options();
 
1036
 
 
1037
      charset= get_charset(field_options.has_collation_id()?
 
1038
                           field_options.collation_id() : 0);
 
1039
 
 
1040
      if (!charset)
 
1041
        charset= default_charset_info;
 
1042
 
 
1043
    }
 
1044
 
 
1045
    if(field_type==DRIZZLE_TYPE_ENUM)
 
1046
    {
 
1047
      drizzled::message::Table::Field::SetFieldOptions field_options=
 
1048
        pfield.set_options();
 
1049
 
 
1050
      charset= get_charset(field_options.has_collation_id()?
 
1051
                           field_options.collation_id() : 0);
 
1052
 
 
1053
      if (!charset)
 
1054
        charset= default_charset_info;
 
1055
 
 
1056
    }
 
1057
 
 
1058
    Item *default_value= NULL;
 
1059
 
 
1060
    if(pfield.options().has_default_value()
 
1061
       || pfield.options().has_default_null()
 
1062
       || pfield.options().has_default_bin_value())
 
1063
    {
 
1064
      default_value= default_value_item(field_type,
 
1065
                                        charset,
 
1066
                                        pfield.options().default_null(),
 
1067
                                        &pfield.options().default_value(),
 
1068
                                        &pfield.options().default_bin_value());
 
1069
    }
 
1070
 
 
1071
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
 
1072
 
 
1073
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
1074
    memset(&temp_table, 0, sizeof(temp_table));
 
1075
    temp_table.s= share;
 
1076
    temp_table.in_use= session;
 
1077
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
 
1078
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
1079
 
 
1080
    Field* f= make_field(share, &share->mem_root,
 
1081
                         record+field_offsets[fieldnr]+data_offset,
 
1082
                         pfield.options().length(),
 
1083
                         null_pos,
 
1084
                         null_bit_pos,
 
1085
                         pack_flag,
 
1086
                         field_type,
 
1087
                         charset,
 
1088
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
1089
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
1090
                         share->intervals+(interval_nr++)
 
1091
                         : (TYPELIB*) 0),
 
1092
                        share->fieldnames.type_names[fieldnr]);
 
1093
 
 
1094
    share->field[fieldnr]= f;
 
1095
 
 
1096
    f->init(&temp_table); /* blob default values need table obj */
 
1097
 
 
1098
    if(!(f->flags & NOT_NULL_FLAG))
 
1099
    {
 
1100
      *f->null_ptr|= f->null_bit;
934
1101
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
935
 
        null_pos++;
936
 
    }
937
 
    if (f_no_default(pack_flag))
938
 
      reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
939
 
 
940
 
    if (reg_field->unireg_check == Field::NEXT_NUMBER)
941
 
      share->found_next_number_field= field_ptr;
942
 
    if (share->timestamp_field == reg_field)
943
 
      share->timestamp_field_offset= i;
944
 
 
945
 
    if (use_hash)
 
1102
        null_pos++;
 
1103
      null_count++;
 
1104
    }
 
1105
 
 
1106
    if(default_value)
 
1107
    {
 
1108
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
1109
      session->count_cuted_fields= CHECK_FIELD_WARN;
 
1110
      int res= default_value->save_in_field(f, 1);
 
1111
      session->count_cuted_fields= old_count_cuted_fields;
 
1112
      if (res != 0 && res != 3)
 
1113
      {
 
1114
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
 
1115
        error= 1;
 
1116
        goto err;
 
1117
      }
 
1118
    }
 
1119
    else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
 
1120
            (f->flags & NOT_NULL_FLAG))
 
1121
    {
 
1122
      f->set_notnull();
 
1123
      f->store((int64_t) 1, true);
 
1124
    }
 
1125
    else
 
1126
      f->reset();
 
1127
 
 
1128
    /* hack to undo f->init() */
 
1129
    f->table= NULL;
 
1130
    f->orig_table= NULL;
 
1131
 
 
1132
    f->field_index= fieldnr;
 
1133
    f->comment= comment;
 
1134
    f->vcol_info= vcol_info;
 
1135
    f->is_stored= field_is_stored;
 
1136
    if(!default_value
 
1137
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
1138
       && (f->flags & NOT_NULL_FLAG)
 
1139
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
 
1140
      f->flags|= NO_DEFAULT_VALUE_FLAG;
 
1141
 
 
1142
    if(f->unireg_check == Field::NEXT_NUMBER)
 
1143
      share->found_next_number_field= &(share->field[fieldnr]);
 
1144
 
 
1145
    if(share->timestamp_field == f)
 
1146
      share->timestamp_field_offset= fieldnr;
 
1147
 
 
1148
    if (use_hash) /* supposedly this never fails... but comments lie */
946
1149
      (void) my_hash_insert(&share->name_hash,
947
 
                            (unsigned char*) field_ptr); // never fail
948
 
  }
949
 
  *field_ptr=0;                                 // End marker
950
 
 
951
 
  /* Fix key->name and key_part->field */
952
 
  if (key_parts)
953
 
  {
954
 
    uint32_t primary_key=(uint) (find_type((char*) primary_key_name,
 
1150
                            (unsigned char*)&(share->field[fieldnr]));
 
1151
 
 
1152
    if(!f->is_stored)
 
1153
    {
 
1154
      share->stored_fields--;
 
1155
    }
 
1156
  }
 
1157
 
 
1158
  keyinfo= share->key_info;
 
1159
  for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
 
1160
  {
 
1161
    key_part= keyinfo->key_part;
 
1162
 
 
1163
    for(unsigned int partnr= 0;
 
1164
        partnr < keyinfo->key_parts;
 
1165
        partnr++, key_part++)
 
1166
    {
 
1167
      /* Fix up key_part->offset by adding data_offset.
 
1168
         We really should compute offset as well.
 
1169
         But at least this way we are a little better. */
 
1170
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
1171
    }
 
1172
  }
 
1173
 
 
1174
  /*
 
1175
    We need to set the unused bits to 1. If the number of bits is a multiple
 
1176
    of 8 there are no unused bits.
 
1177
  */
 
1178
 
 
1179
  if (null_count & 7)
 
1180
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
1181
 
 
1182
  share->null_bytes= (null_pos - (unsigned char*) record +
 
1183
                      (null_bit_pos + 7) / 8);
 
1184
 
 
1185
  share->last_null_bit_pos= null_bit_pos;
 
1186
 
 
1187
  free(field_offsets);
 
1188
  free(field_pack_length);
 
1189
 
 
1190
  if(!(handler_file= get_new_handler(share, session->mem_root,
 
1191
                                     share->db_type())))
 
1192
    abort(); // FIXME
 
1193
 
 
1194
  /* Fix key stuff */
 
1195
  if (share->key_parts)
 
1196
  {
 
1197
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
955
1198
                                       &share->keynames, 3) - 1);
 
1199
 
956
1200
    int64_t ha_option= handler_file->ha_table_flags();
 
1201
 
957
1202
    keyinfo= share->key_info;
958
1203
    key_part= keyinfo->key_part;
959
1204
 
960
1205
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
961
1206
    {
962
1207
      uint32_t usable_parts= 0;
963
 
      keyinfo->name=(char*) share->keynames.type_names[key];
964
1208
 
965
1209
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
966
1210
      {
969
1213
          declare this as a primary key.
970
1214
        */
971
1215
        primary_key=key;
972
 
        for (i=0 ; i < keyinfo->key_parts ;i++)
 
1216
        for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
973
1217
        {
974
1218
          uint32_t fieldnr= key_part[i].fieldnr;
975
1219
          if (!fieldnr ||
977
1221
              share->field[fieldnr-1]->key_length() !=
978
1222
              key_part[i].length)
979
1223
          {
980
 
            primary_key=MAX_KEY;                // Can't be used
 
1224
            primary_key=MAX_KEY;                // Can't be used
981
1225
            break;
982
1226
          }
983
1227
        }
984
1228
      }
985
1229
 
986
 
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1230
      for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
987
1231
      {
988
1232
        Field *field;
989
 
        if (new_field_pack_flag <= 1)
990
 
          key_part->fieldnr= (uint16_t) find_field(share->field,
991
 
                                                 share->default_values,
992
 
                                                 (uint) key_part->offset,
993
 
                                                 (uint) key_part->length);
994
1233
        if (!key_part->fieldnr)
995
1234
        {
996
 
          error= 4;                             // Wrong file
997
 
          goto err;
 
1235
//          error= 4;                             // Wrong file
 
1236
          abort(); // goto err;
998
1237
        }
999
1238
        field= key_part->field= share->field[key_part->fieldnr-1];
1000
1239
        key_part->type= field->key_type();
1001
1240
        if (field->null_ptr)
1002
1241
        {
1003
 
          key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
 
1242
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1004
1243
                                        share->default_values);
1005
1244
          key_part->null_bit= field->null_bit;
1006
1245
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1091
1330
                                      fieldnr);
1092
1331
        }
1093
1332
      }
 
1333
 
1094
1334
    }
1095
1335
    else
1096
1336
      share->primary_key = MAX_KEY; // we do not have a primary key
1097
1337
  }
1098
1338
  else
1099
1339
    share->primary_key= MAX_KEY;
1100
 
  if (disk_buff)
1101
 
    free(disk_buff);
1102
 
  disk_buff= NULL;
1103
 
  if (new_field_pack_flag <= 1)
1104
 
  {
1105
 
    /* Old file format with default as not null */
1106
 
    uint32_t null_length= (share->null_fields+7)/8;
1107
 
    memset(share->default_values + (null_flags - (unsigned char*) record), 
1108
 
          null_length, 255);
1109
 
  }
1110
1340
 
1111
1341
  if (share->found_next_number_field)
1112
1342
  {
1113
 
    reg_field= *share->found_next_number_field;
1114
 
    if ((int) (share->next_number_index= (uint)
 
1343
    Field *reg_field= *share->found_next_number_field;
 
1344
    if ((int) (share->next_number_index= (uint32_t)
1115
1345
               find_ref_key(share->key_info, share->keys,
1116
1346
                            share->default_values, reg_field,
1117
1347
                            &share->next_number_key_offset,
1133
1363
    /* Store offsets to blob fields to find them fast */
1134
1364
    if (!(share->blob_field= save=
1135
1365
          (uint*) alloc_root(&share->mem_root,
1136
 
                             (uint) (share->blob_fields* sizeof(uint)))))
 
1366
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1137
1367
      goto err;
1138
1368
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1139
1369
    {
1142
1372
    }
1143
1373
  }
1144
1374
 
1145
 
  /*
1146
 
    the correct null_bytes can now be set, since bitfields have been taken
1147
 
    into account
1148
 
  */
1149
 
  share->null_bytes= (null_pos - (unsigned char*) null_flags +
1150
 
                      (null_bit_pos + 7) / 8);
1151
 
  share->last_null_bit_pos= null_bit_pos;
1152
 
 
1153
1375
  share->db_low_byte_first= handler_file->low_byte_first();
1154
1376
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1155
1377
 
 
1378
  my_bitmap_map *bitmaps;
 
1379
 
1156
1380
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1157
1381
                                             share->column_bitmap_size)))
1158
1382
    goto err;
1159
 
  bitmap_init(&share->all_set, bitmaps, share->fields, false);
1160
 
  bitmap_set_all(&share->all_set);
 
1383
  share->all_set.set();
1161
1384
 
1162
 
  delete handler_file;
1163
 
  if (buff)
1164
 
    free(buff);
 
1385
  if(handler_file)
 
1386
    delete handler_file;
1165
1387
  return (0);
1166
1388
 
1167
 
 err:
1168
 
  if (buff)
1169
 
    free(buff);
 
1389
err:
1170
1390
  share->error= error;
1171
1391
  share->open_errno= my_errno;
1172
 
  share->errarg= errarg;
1173
 
  if (disk_buff)
1174
 
    free(disk_buff);
1175
 
  delete handler_file;
 
1392
  share->errarg= 0;
1176
1393
  hash_free(&share->name_hash);
1177
 
 
1178
 
  open_table_error(share, error, share->open_errno, errarg);
 
1394
  if(handler_file)
 
1395
    delete handler_file;
 
1396
  open_table_error(share, error, share->open_errno, 0);
 
1397
  return error;
 
1398
}
 
1399
 
 
1400
/*
 
1401
  Read table definition from a binary / text based .frm file
 
1402
 
 
1403
  SYNOPSIS
 
1404
  open_table_def()
 
1405
  session               Thread handler
 
1406
  share         Fill this with table definition
 
1407
  db_flags      Bit mask of the following flags: OPEN_VIEW
 
1408
 
 
1409
  NOTES
 
1410
    This function is called when the table definition is not cached in
 
1411
    table_def_cache
 
1412
    The data is returned in 'share', which is alloced by
 
1413
    alloc_table_share().. The code assumes that share is initialized.
 
1414
 
 
1415
  RETURN VALUES
 
1416
   0    ok
 
1417
   1    Error (see open_table_error)
 
1418
   2    Error (see open_table_error)
 
1419
   3    Wrong data in .frm file
 
1420
   4    Error (see open_table_error)
 
1421
   5    Error (see open_table_error: charset unavailable)
 
1422
   6    Unknown .frm version
 
1423
*/
 
1424
 
 
1425
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
 
1426
{
 
1427
  int error;
 
1428
  bool error_given;
 
1429
  string proto_path("");
 
1430
 
 
1431
  error= 1;
 
1432
  error_given= 0;
 
1433
 
 
1434
  proto_path.reserve(FN_REFLEN);
 
1435
  proto_path.append(share->normalized_path.str);
 
1436
 
 
1437
  proto_path.append(".dfe");
 
1438
 
 
1439
  drizzled::message::Table table;
 
1440
 
 
1441
  if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
 
1442
  {
 
1443
    if(error>0)
 
1444
    {
 
1445
      my_errno= error;
 
1446
      error= 1;
 
1447
    }
 
1448
    else
 
1449
    {
 
1450
      if(!table.IsInitialized())
 
1451
      {
 
1452
        error= 4;
 
1453
      }
 
1454
    }
 
1455
    goto err_not_open;
 
1456
  }
 
1457
 
 
1458
  error= parse_table_proto(session, table, share);
 
1459
 
 
1460
  share->table_category= get_table_category(& share->db, & share->table_name);
 
1461
 
 
1462
  if (!error)
 
1463
    session->status_var.opened_shares++;
 
1464
 
 
1465
err_not_open:
 
1466
  if (error && !error_given)
 
1467
  {
 
1468
    share->error= error;
 
1469
    open_table_error(share, error, (share->open_errno= my_errno), 0);
 
1470
  }
 
1471
 
1179
1472
  return(error);
1180
 
} /* open_binary_frm */
 
1473
}
 
1474
 
 
1475
/*
 
1476
  Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
 
1477
  This routine is used for error handling purposes.
 
1478
 
 
1479
  SYNOPSIS
 
1480
    clear_field_flag()
 
1481
    table                Table object for which virtual columns are set-up
 
1482
 
 
1483
  RETURN VALUE
 
1484
    NONE
 
1485
*/
 
1486
static void clear_field_flag(Table *table)
 
1487
{
 
1488
  Field **ptr;
 
1489
 
 
1490
  for (ptr= table->field; *ptr; ptr++)
 
1491
    (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
 
1492
}
 
1493
 
 
1494
/*
 
1495
  The function uses the feature in fix_fields where the flag
 
1496
  GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
 
1497
  This field must always be reset before returning from the function
 
1498
  since it is used for other purposes as well.
 
1499
 
 
1500
  SYNOPSIS
 
1501
    fix_fields_vcol_func()
 
1502
    session                  The thread object
 
1503
    func_item            The item tree reference of the virtual columnfunction
 
1504
    table                The table object
 
1505
    field_name           The name of the processed field
 
1506
 
 
1507
  RETURN VALUE
 
1508
    true                 An error occurred, something was wrong with the
 
1509
                         function.
 
1510
    false                Ok, a partition field array was created
 
1511
*/
 
1512
 
 
1513
bool fix_fields_vcol_func(Session *session,
 
1514
                          Item* func_expr,
 
1515
                          Table *table,
 
1516
                          const char *field_name)
 
1517
{
 
1518
  uint32_t dir_length, home_dir_length;
 
1519
  bool result= true;
 
1520
  TableList tables;
 
1521
  TableList *save_table_list, *save_first_table, *save_last_table;
 
1522
  int error;
 
1523
  Name_resolution_context *context;
 
1524
  const char *save_where;
 
1525
  char* db_name;
 
1526
  char db_name_string[FN_REFLEN];
 
1527
  bool save_use_only_table_context;
 
1528
  Field **ptr, *field;
 
1529
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
 
1530
  assert(func_expr);
 
1531
 
 
1532
  /*
 
1533
    Set-up the TABLE_LIST object to be a list with a single table
 
1534
    Set the object to zero to create NULL pointers and set alias
 
1535
    and real name to table name and get database name from file name.
 
1536
  */
 
1537
 
 
1538
  bzero((void*)&tables, sizeof(TableList));
 
1539
  tables.alias= tables.table_name= (char*) table->s->table_name.str;
 
1540
  tables.table= table;
 
1541
  tables.next_local= NULL;
 
1542
  tables.next_name_resolution_table= NULL;
 
1543
  memcpy(db_name_string,
 
1544
         table->s->normalized_path.str,
 
1545
         table->s->normalized_path.length);
 
1546
  db_name_string[table->s->normalized_path.length]= '\0';
 
1547
  dir_length= dirname_length(db_name_string);
 
1548
  db_name_string[dir_length - 1]= 0;
 
1549
  home_dir_length= dirname_length(db_name_string);
 
1550
  db_name= &db_name_string[home_dir_length];
 
1551
  tables.db= db_name;
 
1552
 
 
1553
  session->mark_used_columns= MARK_COLUMNS_NONE;
 
1554
 
 
1555
  context= session->lex->current_context();
 
1556
  table->map= 1; //To ensure correct calculation of const item
 
1557
  table->get_fields_in_item_tree= true;
 
1558
  save_table_list= context->table_list;
 
1559
  save_first_table= context->first_name_resolution_table;
 
1560
  save_last_table= context->last_name_resolution_table;
 
1561
  context->table_list= &tables;
 
1562
  context->first_name_resolution_table= &tables;
 
1563
  context->last_name_resolution_table= NULL;
 
1564
  func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
 
1565
  save_where= session->where;
 
1566
  session->where= "virtual column function";
 
1567
 
 
1568
  /* Save the context before fixing the fields*/
 
1569
  save_use_only_table_context= session->lex->use_only_table_context;
 
1570
  session->lex->use_only_table_context= true;
 
1571
  /* Fix fields referenced to by the virtual column function */
 
1572
  error= func_expr->fix_fields(session, (Item**)0);
 
1573
  /* Restore the original context*/
 
1574
  session->lex->use_only_table_context= save_use_only_table_context;
 
1575
  context->table_list= save_table_list;
 
1576
  context->first_name_resolution_table= save_first_table;
 
1577
  context->last_name_resolution_table= save_last_table;
 
1578
 
 
1579
  if (unlikely(error))
 
1580
  {
 
1581
    clear_field_flag(table);
 
1582
    goto end;
 
1583
  }
 
1584
  session->where= save_where;
 
1585
  /*
 
1586
    Walk through the Item tree checking if all items are valid
 
1587
   to be part of the virtual column
 
1588
 */
 
1589
  error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
 
1590
  if (error)
 
1591
  {
 
1592
    my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
 
1593
    clear_field_flag(table);
 
1594
    goto end;
 
1595
  }
 
1596
  if (unlikely(func_expr->const_item()))
 
1597
  {
 
1598
    my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
 
1599
    clear_field_flag(table);
 
1600
    goto end;
 
1601
  }
 
1602
  /* Ensure that this virtual column is not based on another virtual field. */
 
1603
  ptr= table->field;
 
1604
  while ((field= *(ptr++)))
 
1605
  {
 
1606
    if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
 
1607
        (field->vcol_info))
 
1608
    {
 
1609
      my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
 
1610
      clear_field_flag(table);
 
1611
      goto end;
 
1612
    }
 
1613
  }
 
1614
  /*
 
1615
    Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
 
1616
    when calling fix_fields.
 
1617
  */
 
1618
  clear_field_flag(table);
 
1619
  result= false;
 
1620
 
 
1621
end:
 
1622
  table->get_fields_in_item_tree= false;
 
1623
  session->mark_used_columns= save_mark_used_columns;
 
1624
  table->map= 0; //Restore old value
 
1625
  return(result);
 
1626
}
 
1627
 
 
1628
/*
 
1629
  Unpack the definition of a virtual column
 
1630
 
 
1631
  SYNOPSIS
 
1632
    unpack_vcol_info_from_frm()
 
1633
    session                  Thread handler
 
1634
    table                Table with the checked field
 
1635
    field                Pointer to Field object
 
1636
    open_mode            Open table mode needed to determine
 
1637
                         which errors need to be generated in a failure
 
1638
    error_reported       updated flag for the caller that no other error
 
1639
                         messages are to be generated.
 
1640
 
 
1641
  RETURN VALUES
 
1642
    true            Failure
 
1643
    false           Success
 
1644
*/
 
1645
bool unpack_vcol_info_from_frm(Session *session,
 
1646
                               Table *table,
 
1647
                               Field *field,
 
1648
                               LEX_STRING *vcol_expr,
 
1649
                               open_table_mode open_mode,
 
1650
                               bool *error_reported)
 
1651
{
 
1652
  assert(vcol_expr);
 
1653
 
 
1654
  /*
 
1655
    Step 1: Construct a statement for the parser.
 
1656
    The parsed string needs to take the following format:
 
1657
    "PARSE_VCOL_EXPR (<expr_string_from_frm>)"
 
1658
  */
 
1659
  char *vcol_expr_str;
 
1660
  int str_len= 0;
 
1661
 
 
1662
  if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
 
1663
                                          vcol_expr->length +
 
1664
                                            parse_vcol_keyword.length + 3)))
 
1665
  {
 
1666
    return(true);
 
1667
  }
 
1668
  memcpy(vcol_expr_str,
 
1669
         (char*) parse_vcol_keyword.str,
 
1670
         parse_vcol_keyword.length);
 
1671
  str_len= parse_vcol_keyword.length;
 
1672
  memcpy(vcol_expr_str + str_len, "(", 1);
 
1673
  str_len++;
 
1674
  memcpy(vcol_expr_str + str_len,
 
1675
         (char*) vcol_expr->str,
 
1676
         vcol_expr->length);
 
1677
  str_len+= vcol_expr->length;
 
1678
  memcpy(vcol_expr_str + str_len, ")", 1);
 
1679
  str_len++;
 
1680
  memcpy(vcol_expr_str + str_len, "\0", 1);
 
1681
  str_len++;
 
1682
  Lex_input_stream lip(session, vcol_expr_str, str_len);
 
1683
 
 
1684
  /*
 
1685
    Step 2: Setup session for parsing.
 
1686
    1) make Item objects be created in the memory allocated for the Table
 
1687
       object (not TABLE_SHARE)
 
1688
    2) ensure that created Item's are not put on to session->free_list
 
1689
       (which is associated with the parsed statement and hence cleared after
 
1690
       the parsing)
 
1691
    3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
 
1692
       to be parsed as a SQL command.
 
1693
  */
 
1694
  MEM_ROOT **root_ptr, *old_root;
 
1695
  Item *backup_free_list= session->free_list;
 
1696
  root_ptr= current_mem_root_ptr();
 
1697
  old_root= *root_ptr;
 
1698
  *root_ptr= &table->mem_root;
 
1699
  session->free_list= NULL;
 
1700
  session->lex->parse_vcol_expr= true;
 
1701
 
 
1702
  /*
 
1703
    Step 3: Use the parser to build an Item object from.
 
1704
  */
 
1705
  if (parse_sql(session, &lip))
 
1706
  {
 
1707
    goto parse_err;
 
1708
  }
 
1709
  /* From now on use vcol_info generated by the parser. */
 
1710
  field->vcol_info= session->lex->vcol_info;
 
1711
 
 
1712
  /* Validate the Item tree. */
 
1713
  if (fix_fields_vcol_func(session,
 
1714
                           field->vcol_info->expr_item,
 
1715
                           table,
 
1716
                           field->field_name))
 
1717
  {
 
1718
    if (open_mode == OTM_CREATE)
 
1719
    {
 
1720
      /*
 
1721
        During CREATE/ALTER TABLE it is ok to receive errors here.
 
1722
        It is not ok if it happens during the opening of an frm
 
1723
        file as part of a normal query.
 
1724
      */
 
1725
      *error_reported= true;
 
1726
    }
 
1727
    field->vcol_info= NULL;
 
1728
    goto parse_err;
 
1729
  }
 
1730
  field->vcol_info->item_free_list= session->free_list;
 
1731
  session->free_list= backup_free_list;
 
1732
  *root_ptr= old_root;
 
1733
 
 
1734
  return(false);
 
1735
 
 
1736
parse_err:
 
1737
  session->lex->parse_vcol_expr= false;
 
1738
  session->free_items();
 
1739
  *root_ptr= old_root;
 
1740
  session->free_list= backup_free_list;
 
1741
  return(true);
 
1742
}
1181
1743
 
1182
1744
 
1183
1745
/*
1185
1747
 
1186
1748
  SYNOPSIS
1187
1749
    open_table_from_share()
1188
 
    thd                 Thread handler
 
1750
    session                     Thread handler
1189
1751
    share               Table definition
1190
1752
    alias               Alias for table
1191
1753
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1208
1770
   7    Table definition has changed in engine
1209
1771
*/
1210
1772
 
1211
 
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
 
1773
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1212
1774
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1213
1775
                          Table *outparam, open_table_mode open_mode)
1214
1776
{
1215
1777
  int error;
1216
 
  uint32_t records, i, bitmap_size;
 
1778
  uint32_t records, i;
1217
1779
  bool error_reported= false;
1218
 
  unsigned char *record, *bitmaps;
1219
 
  Field **field_ptr;
 
1780
  unsigned char *record;
 
1781
  Field **field_ptr, **vfield_ptr;
1220
1782
 
1221
 
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
1222
 
  assert(thd->lex->is_lex_started);
 
1783
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1784
  assert(session->lex->is_lex_started);
1223
1785
 
1224
1786
  error= 1;
1225
1787
  memset(outparam, 0, sizeof(*outparam));
1226
 
  outparam->in_use= thd;
 
1788
  outparam->in_use= session;
1227
1789
  outparam->s= share;
1228
1790
  outparam->db_stat= db_stat;
1229
1791
  outparam->write_row_record= NULL;
1230
1792
 
1231
1793
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1232
1794
 
1233
 
  if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
 
1795
  if (!(outparam->alias= strdup(alias)))
1234
1796
    goto err;
1235
1797
  outparam->quick_keys.init();
1236
1798
  outparam->covering_keys.init();
1292
1854
#endif
1293
1855
 
1294
1856
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1295
 
                                          (uint) ((share->fields+1)*
 
1857
                                          (uint32_t) ((share->fields+1)*
1296
1858
                                                  sizeof(Field*)))))
1297
1859
    goto err;                                   /* purecov: inspected */
1298
1860
 
1299
1861
  outparam->field= field_ptr;
1300
1862
 
1301
1863
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
1302
 
  if (share->null_field_first)
1303
 
    outparam->null_flags= (unsigned char*) record+1;
1304
 
  else
1305
 
    outparam->null_flags= (unsigned char*) (record+ 1+ share->reclength -
1306
 
                                    share->null_bytes);
 
1864
 
 
1865
  outparam->null_flags= (unsigned char*) record+1;
1307
1866
 
1308
1867
  /* Setup copy of fields from share, but use the right alias and record */
1309
1868
  for (i=0 ; i < share->fields; i++, field_ptr++)
1315
1874
 
1316
1875
  if (share->found_next_number_field)
1317
1876
    outparam->found_next_number_field=
1318
 
      outparam->field[(uint) (share->found_next_number_field - share->field)];
 
1877
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1319
1878
  if (share->timestamp_field)
1320
1879
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1321
1880
 
1331
1890
      goto err;
1332
1891
    outparam->key_info= key_info;
1333
1892
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1334
 
    
 
1893
 
1335
1894
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1336
1895
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1337
1896
                                                   share->key_parts));
1366
1925
    }
1367
1926
  }
1368
1927
 
 
1928
  /*
 
1929
    Process virtual columns, if any.
 
1930
  */
 
1931
  if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1932
                                              (uint32_t) ((share->vfields+1)*
 
1933
                                                      sizeof(Field*)))))
 
1934
    goto err;
 
1935
 
 
1936
  outparam->vfield= vfield_ptr;
 
1937
 
 
1938
  for (field_ptr= outparam->field; *field_ptr; field_ptr++)
 
1939
  {
 
1940
    if ((*field_ptr)->vcol_info)
 
1941
    {
 
1942
      if (unpack_vcol_info_from_frm(session,
 
1943
                                    outparam,
 
1944
                                    *field_ptr,
 
1945
                                    &(*field_ptr)->vcol_info->expr_str,
 
1946
                                    open_mode,
 
1947
                                    &error_reported))
 
1948
      {
 
1949
        error= 4; // in case no error is reported
 
1950
        goto err;
 
1951
      }
 
1952
      *(vfield_ptr++)= *field_ptr;
 
1953
    }
 
1954
  }
 
1955
  *vfield_ptr= NULL;                              // End marker
 
1956
  /* Check virtual columns against table's storage engine. */
 
1957
  if ((share->vfields && outparam->file) &&
 
1958
        (not outparam->file->check_if_supported_virtual_columns()))
 
1959
  {
 
1960
    my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
1961
             MYF(0),
 
1962
             "Specified storage engine");
 
1963
    error_reported= true;
 
1964
    goto err;
 
1965
  }
 
1966
 
1369
1967
  /* Allocate bitmaps */
1370
 
 
1371
 
  bitmap_size= share->column_bitmap_size;
1372
 
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1373
 
    goto err;
1374
 
  bitmap_init(&outparam->def_read_set,
1375
 
              (my_bitmap_map*) bitmaps, share->fields, false);
1376
 
  bitmap_init(&outparam->def_write_set,
1377
 
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1378
 
  bitmap_init(&outparam->tmp_set,
1379
 
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1380
1968
  outparam->default_column_bitmaps();
1381
1969
 
1382
1970
  /* The table struct is now initialized;  Open the table */
1427
2015
    }
1428
2016
  }
1429
2017
 
1430
 
#if defined(HAVE_purify) 
 
2018
#if defined(HAVE_purify)
1431
2019
  memset(bitmaps, 0, bitmap_size*3);
1432
2020
#endif
1433
2021
 
1434
2022
  outparam->no_replicate= outparam->file;
1435
 
  thd->status_var.opened_tables++;
 
2023
  session->status_var.opened_tables++;
1436
2024
 
1437
2025
  return (0);
1438
2026
 
1447
2035
  return (error);
1448
2036
}
1449
2037
 
 
2038
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
 
2039
uint32_t  Table::tmpkeyval()
 
2040
{
 
2041
  return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
 
2042
}
1450
2043
 
1451
2044
/*
1452
2045
  Free information allocated by openfrm
1457
2050
    free_share          Is 1 if we also want to free table_share
1458
2051
*/
1459
2052
 
1460
 
int closefrm(register Table *table, bool free_share)
 
2053
int Table::closefrm(bool free_share)
1461
2054
{
1462
2055
  int error=0;
1463
2056
 
1464
 
  if (table->db_stat)
1465
 
    error=table->file->close();
1466
 
  free((char*) table->alias);
1467
 
  table->alias= 0;
1468
 
  if (table->field)
 
2057
  if (db_stat)
 
2058
    error= file->close();
 
2059
  free((char*) alias);
 
2060
  alias= NULL;
 
2061
  if (field)
1469
2062
  {
1470
 
    for (Field **ptr=table->field ; *ptr ; ptr++)
 
2063
    for (Field **ptr=field ; *ptr ; ptr++)
1471
2064
      delete *ptr;
1472
 
    table->field= 0;
 
2065
    field= 0;
1473
2066
  }
1474
 
  delete table->file;
1475
 
  table->file= 0;                               /* For easier errorchecking */
 
2067
  delete file;
 
2068
  file= 0;                              /* For easier errorchecking */
1476
2069
  if (free_share)
1477
2070
  {
1478
 
    if (table->s->tmp_table == NO_TMP_TABLE)
1479
 
      release_table_share(table->s, RELEASE_NORMAL);
 
2071
    if (s->tmp_table == NO_TMP_TABLE)
 
2072
      release_table_share(s, RELEASE_NORMAL);
1480
2073
    else
1481
 
      free_table_share(table->s);
 
2074
      free_table_share(s);
1482
2075
  }
1483
 
  free_root(&table->mem_root, MYF(0));
1484
 
  return(error);
 
2076
  free_root(&mem_root, MYF(0));
 
2077
 
 
2078
  return error;
1485
2079
}
1486
2080
 
1487
2081
 
1517
2111
  if (names)
1518
2112
  {
1519
2113
    length=uint2korr(head+4);
1520
 
    my_seek(file,64L,MY_SEEK_SET,MYF(0));
1521
 
    if (!(buf= (unsigned char*) my_malloc((size_t) length+a_length+names*4,
1522
 
                                  MYF(MY_WME))) ||
 
2114
    lseek(file,64,SEEK_SET);
 
2115
    if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
1523
2116
        my_read(file, buf+a_length, (size_t) (length+names*4),
1524
2117
                MYF(MY_NABP)))
1525
2118
    {                                           /* purecov: inspected */
1559
2152
 
1560
2153
  if (*to)
1561
2154
    free(*to);
1562
 
  if (!(*to= (unsigned char*) my_malloc(length+1,MYF(MY_WME))) ||
 
2155
  if (!(*to= (unsigned char*) malloc(length+1)) ||
1563
2156
      my_read(file, *to, length,MYF(MY_NABP)))
1564
2157
  {
1565
2158
    if (*to)
1574
2167
 
1575
2168
        /* Add a new form to a form file */
1576
2169
 
1577
 
ulong make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
 
2170
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
1578
2171
                     const char *newname)
1579
2172
{
1580
2173
  uint32_t i,bufflength,maxlength,n_length,length,names;
1581
 
  ulong endpos,newpos;
 
2174
  off_t endpos,newpos;
1582
2175
  unsigned char buff[IO_SIZE];
1583
2176
  unsigned char *pos;
1584
2177
 
1585
 
  length=(uint) strlen(newname)+1;
 
2178
  length=(uint32_t) strlen(newname)+1;
1586
2179
  n_length=uint2korr(fileinfo+4);
1587
2180
  maxlength=uint2korr(fileinfo+6);
1588
2181
  names=uint2korr(fileinfo+8);
1592
2185
  {                                             /* Expand file */
1593
2186
    newpos+=IO_SIZE;
1594
2187
    int4store(fileinfo+10,newpos);
1595
 
    endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */
1596
 
    bufflength= (uint) (endpos & (IO_SIZE-1));  /* IO_SIZE is a power of 2 */
 
2188
    endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
 
2189
    bufflength= (uint32_t) (endpos & (IO_SIZE-1));      /* IO_SIZE is a power of 2 */
1597
2190
 
1598
2191
    while (endpos > maxlength)
1599
2192
    {
1600
 
      my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0));
 
2193
      lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
1601
2194
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
1602
 
        return(0L);
1603
 
      my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1604
 
                   MYF(0));
 
2195
        return(0L);
 
2196
      lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
1605
2197
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1606
 
        return(0);
 
2198
        return(0);
1607
2199
      endpos-=bufflength; bufflength=IO_SIZE;
1608
2200
    }
1609
2201
    memset(buff, 0, IO_SIZE);                   /* Null new block */
1610
 
    my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0));
 
2202
    lseek(file,(ulong) maxlength,SEEK_SET);
1611
2203
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1612
 
        return(0L);
 
2204
      return(0L);
1613
2205
    maxlength+=IO_SIZE;                         /* Fix old ref */
1614
2206
    int2store(fileinfo+6,maxlength);
1615
 
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i-- ;
1616
 
         pos+=4)
 
2207
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
 
2208
         pos+=4)
1617
2209
    {
1618
2210
      endpos=uint4korr(pos)+IO_SIZE;
1619
2211
      int4store(pos,endpos);
1623
2215
  if (n_length == 1 )
1624
2216
  {                                             /* First name */
1625
2217
    length++;
1626
 
    strxmov((char*) buff,"/",newname,"/",NULL);
 
2218
    sprintf((char*)buff,"/%s/",newname);
1627
2219
  }
1628
2220
  else
1629
 
    strxmov((char*) buff,newname,"/",NULL); /* purecov: inspected */
1630
 
  my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0));
 
2221
    sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
 
2222
  lseek(file, 63 + n_length,SEEK_SET);
1631
2223
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1632
2224
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
1633
2225
                         names*4, MYF(MY_NABP+MY_WME))) ||
1636
2228
 
1637
2229
  int2store(fileinfo+8,names+1);
1638
2230
  int2store(fileinfo+4,n_length+length);
1639
 
  (void)ftruncate(file, newpos);/* Append file with '\0' */
 
2231
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
1640
2232
  return(newpos);
1641
2233
} /* make_new_entry */
1642
2234
 
1656
2248
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1657
2249
    else
1658
2250
    {
1659
 
      strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
2251
      sprintf(buff,"%s",share->normalized_path.str);
1660
2252
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1661
2253
               errortype, buff, db_errno);
1662
2254
    }
1665
2257
  {
1666
2258
    handler *file= 0;
1667
2259
    const char *datext= "";
1668
 
    
 
2260
 
1669
2261
    if (share->db_type() != NULL)
1670
2262
    {
1671
 
      if ((file= get_new_handler(share, current_thd->mem_root,
 
2263
      if ((file= get_new_handler(share, current_session->mem_root,
1672
2264
                                 share->db_type())))
1673
2265
      {
1674
2266
        if (!(datext= *file->bas_ext()))
1677
2269
    }
1678
2270
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1679
2271
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1680
 
    strxmov(buff, share->normalized_path.str, datext, NULL);
 
2272
    sprintf(buff,"%s%s", share->normalized_path.str,datext);
1681
2273
    my_error(err_no,errortype, buff, db_errno);
1682
2274
    delete file;
1683
2275
    break;
1684
2276
  }
1685
2277
  case 5:
1686
2278
  {
1687
 
    const char *csname= get_charset_name((uint) errarg);
 
2279
    const char *csname= get_charset_name((uint32_t) errarg);
1688
2280
    char tmp[10];
1689
2281
    if (!csname || csname[0] =='?')
1690
2282
    {
1692
2284
      csname= tmp;
1693
2285
    }
1694
2286
    my_printf_error(ER_UNKNOWN_COLLATION,
1695
 
                    _("Unknown collation '%s' in table '%-.64s' definition"), 
 
2287
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1696
2288
                    MYF(0), csname, share->table_name.str);
1697
2289
    break;
1698
2290
  }
1699
2291
  case 6:
1700
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
2292
    sprintf(buff,"%s",share->normalized_path.str);
1701
2293
    my_printf_error(ER_NOT_FORM_FILE,
1702
2294
                    _("Table '%-.64s' was created with a different version "
1703
 
                    "of MySQL and cannot be read"), 
 
2295
                    "of Drizzle and cannot be read"),
1704
2296
                    MYF(0), buff);
1705
2297
    break;
1706
2298
  case 8:
1707
2299
    break;
1708
2300
  default:                              /* Better wrong error than none */
1709
2301
  case 4:
1710
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
2302
    sprintf(buff,"%s",share->normalized_path.str);
1711
2303
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1712
2304
    break;
1713
2305
  }
1746
2338
    }
1747
2339
    else
1748
2340
      ptr++;
1749
 
    point_to_type->count= (uint) (*array - point_to_type->type_names);
 
2341
    point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
1750
2342
    point_to_type++;
1751
2343
    *((*array)++)= NULL;                /* End of type */
1752
2344
  }
1762
2354
    return 0;
1763
2355
  result->count=strings.elements;
1764
2356
  result->name="";
1765
 
  uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
 
2357
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
1766
2358
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1767
2359
    return 0;
1768
2360
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1778
2370
  return result;
1779
2371
}
1780
2372
 
1781
 
 
1782
 
/*
1783
 
 Search after a field with given start & length
1784
 
 If an exact field isn't found, return longest field with starts
1785
 
 at right position.
1786
 
 
1787
 
 NOTES
1788
 
   This is needed because in some .frm fields 'fieldnr' was saved wrong
1789
 
 
1790
 
 RETURN
1791
 
   0  error
1792
 
   #  field number +1
1793
 
*/
1794
 
 
1795
 
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length)
1796
 
{
1797
 
  Field **field;
1798
 
  uint32_t i, pos;
1799
 
 
1800
 
  pos= 0;
1801
 
  for (field= fields, i=1 ; *field ; i++,field++)
1802
 
  {
1803
 
    if ((*field)->offset(record) == start)
1804
 
    {
1805
 
      if ((*field)->key_length() == length)
1806
 
        return (i);
1807
 
      if (!pos || fields[pos-1]->pack_length() <
1808
 
          (*field)->pack_length())
1809
 
        pos= i;
1810
 
    }
1811
 
  }
1812
 
  return (pos);
1813
 
}
1814
 
 
1815
 
 
1816
2373
        /* Check that the integer is in the internal */
1817
2374
 
1818
2375
int set_zone(register int nr, int min_zone, int max_zone)
1838
2395
/*
1839
2396
  Store an SQL quoted string.
1840
2397
 
1841
 
  SYNOPSIS  
 
2398
  SYNOPSIS
1842
2399
    append_unescaped()
1843
2400
    res         result String
1844
2401
    pos         string to be quoted
1863
2420
    {
1864
2421
      res->append(pos, mblen);
1865
2422
      pos+= mblen;
 
2423
      if (pos >= end)
 
2424
        break;
1866
2425
      continue;
1867
2426
    }
1868
2427
#endif
1897
2456
}
1898
2457
 
1899
2458
 
1900
 
        /* Create a .frm file */
1901
 
 
1902
 
File create_frm(THD *thd, const char *name, const char *db,
1903
 
                const char *table, uint32_t reclength, unsigned char *fileinfo,
1904
 
                HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
1905
 
{
1906
 
  register File file;
1907
 
  ulong length;
1908
 
  unsigned char fill[IO_SIZE];
1909
 
  int create_flags= O_RDWR | O_TRUNC;
1910
 
  ulong key_comment_total_bytes= 0;
1911
 
  uint32_t i;
1912
 
 
1913
 
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1914
 
    create_flags|= O_EXCL | O_NOFOLLOW;
1915
 
 
1916
 
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
1917
 
  if (create_info->max_rows > UINT32_MAX)
1918
 
    create_info->max_rows= UINT32_MAX;
1919
 
  if (create_info->min_rows > UINT32_MAX)
1920
 
    create_info->min_rows= UINT32_MAX;
1921
 
 
1922
 
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
1923
 
  {
1924
 
    uint32_t key_length, tmp_key_length;
1925
 
    uint32_t tmp;
1926
 
    memset(fileinfo, 0, 64);
1927
 
    /* header */
1928
 
    fileinfo[0]=(unsigned char) 254;
1929
 
    fileinfo[1]= 1;
1930
 
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
1931
 
 
1932
 
    fileinfo[3]= (unsigned char) ha_legacy_type(
1933
 
          ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
1934
 
    fileinfo[4]=1;
1935
 
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
1936
 
    for (i= 0; i < keys; i++)
1937
 
    {
1938
 
      assert(test(key_info[i].flags & HA_USES_COMMENT) == 
1939
 
                 (key_info[i].comment.length > 0));
1940
 
      if (key_info[i].flags & HA_USES_COMMENT)
1941
 
        key_comment_total_bytes += 2 + key_info[i].comment.length;
1942
 
    }
1943
 
    /*
1944
 
      Keep in sync with pack_keys() in unireg.cc
1945
 
      For each key:
1946
 
      8 bytes for the key header
1947
 
      9 bytes for each key-part (MAX_REF_PARTS)
1948
 
      NAME_LEN bytes for the name
1949
 
      1 byte for the NAMES_SEP_CHAR (before the name)
1950
 
      For all keys:
1951
 
      6 bytes for the header
1952
 
      1 byte for the NAMES_SEP_CHAR (after the last name)
1953
 
      9 extra bytes (padding for safety? alignment?)
1954
 
      comments
1955
 
    */
1956
 
    key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
1957
 
                 key_comment_total_bytes);
1958
 
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
1959
 
                                  create_info->extra_size));
1960
 
    int4store(fileinfo+10,length);
1961
 
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
1962
 
    int2store(fileinfo+14,tmp_key_length);
1963
 
    int2store(fileinfo+16,reclength);
1964
 
    int4store(fileinfo+18,create_info->max_rows);
1965
 
    int4store(fileinfo+22,create_info->min_rows);
1966
 
    /* fileinfo[26] is set in mysql_create_frm() */
1967
 
    fileinfo[27]=2;                             // Use long pack-fields
1968
 
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
1969
 
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
1970
 
    int2store(fileinfo+30,create_info->table_options);
1971
 
    fileinfo[32]=0;                             // No filename anymore
1972
 
    fileinfo[33]=5;                             // Mark for 5.0 frm file
1973
 
    int4store(fileinfo+34,create_info->avg_row_length);
1974
 
    fileinfo[38]= (create_info->default_table_charset ?
1975
 
                   create_info->default_table_charset->number : 0);
1976
 
    fileinfo[39]= (unsigned char) create_info->page_checksum;
1977
 
    fileinfo[40]= (unsigned char) create_info->row_type;
1978
 
    /* Next few bytes where for RAID support */
1979
 
    fileinfo[41]= 0;
1980
 
    fileinfo[42]= 0;
1981
 
    int4store(fileinfo+43,create_info->block_size);
1982
 
 
1983
 
    fileinfo[44]= 0;
1984
 
    fileinfo[45]= 0;
1985
 
    fileinfo[46]= 0;
1986
 
    int4store(fileinfo+47, key_length);
1987
 
    tmp= DRIZZLE_VERSION_ID;          // Store to avoid warning from int4store
1988
 
    int4store(fileinfo+51, tmp);
1989
 
    int4store(fileinfo+55, create_info->extra_size);
1990
 
    /*
1991
 
      59-60 is reserved for extra_rec_buf_length,
1992
 
      61 for default_part_db_type
1993
 
    */
1994
 
    int2store(fileinfo+62, create_info->key_block_size);
1995
 
    memset(fill, 0, IO_SIZE);
1996
 
    for (; length > IO_SIZE ; length-= IO_SIZE)
1997
 
    {
1998
 
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
1999
 
      {
2000
 
        my_close(file,MYF(0));
2001
 
        my_delete(name,MYF(0));
2002
 
        return(-1);
2003
 
      }
2004
 
    }
2005
 
  }
2006
 
  else
2007
 
  {
2008
 
    if (my_errno == ENOENT)
2009
 
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
2010
 
    else
2011
 
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
2012
 
  }
2013
 
  return (file);
2014
 
} /* create_frm */
2015
 
 
2016
2459
/*
2017
2460
  Set up column usage bitmaps for a temporary table
2018
2461
 
2021
2464
    a tmp_set bitmap to be used by things like filesort.
2022
2465
*/
2023
2466
 
2024
 
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
2467
void Table::setup_tmp_table_column_bitmaps()
2025
2468
{
2026
 
  uint32_t field_count= s->fields;
2027
 
 
2028
 
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count, false);
2029
 
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count, false);
2030
 
 
2031
2469
  /* write_set and all_set are copies of read_set */
2032
2470
  def_write_set= def_read_set;
2033
2471
  s->all_set= def_read_set;
2034
 
  bitmap_set_all(&this->s->all_set);
 
2472
  this->s->all_set.set();
2035
2473
  default_column_bitmaps();
 
2474
  read_set->set();
2036
2475
}
2037
2476
 
2038
2477
 
2052
2491
  return;
2053
2492
}
2054
2493
 
2055
 
int
2056
 
rename_file_ext(const char * from,const char * to,const char * ext)
 
2494
int rename_file_ext(const char * from,const char * to,const char * ext)
2057
2495
{
2058
 
  char from_b[FN_REFLEN],to_b[FN_REFLEN];
2059
 
  strxmov(from_b,from,ext,NULL);
2060
 
  strxmov(to_b,to,ext,NULL);
2061
 
  return (my_rename(from_b,to_b,MYF(MY_WME)));
 
2496
  string from_s, to_s;
 
2497
 
 
2498
  from_s.append(from);
 
2499
  from_s.append(ext);
 
2500
  to_s.append(to);
 
2501
  to_s.append(ext);
 
2502
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
2062
2503
}
2063
2504
 
2064
2505
 
2118
2559
  length= str.length();
2119
2560
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
2120
2561
    return NULL;
2121
 
  memcpy(to,str.ptr(),(uint) length);
 
2562
  memcpy(to,str.ptr(),(uint32_t) length);
2122
2563
  to[length]=0;
2123
2564
  return to;
2124
2565
}
2129
2570
    that are present in this value, returns the length of the value
2130
2571
*/
2131
2572
uint32_t calculate_key_len(Table *table, uint32_t key,
2132
 
                       const unsigned char *buf __attribute__((unused)),
 
2573
                       const unsigned char *,
2133
2574
                       key_part_map keypart_map)
2134
2575
{
2135
2576
  /* works only with key prefixes */
2206
2647
{
2207
2648
  uint32_t name_length= 0;  // name length in symbols
2208
2649
  bool last_char_is_space= true;
2209
 
  
 
2650
 
2210
2651
  while (*name)
2211
2652
  {
2212
2653
#if defined(USE_MB) && defined(USE_MB_IDENT)
2213
2654
    last_char_is_space= my_isspace(system_charset_info, *name);
2214
2655
    if (use_mb(system_charset_info))
2215
2656
    {
2216
 
      int len=my_ismbchar(system_charset_info, name, 
 
2657
      int len=my_ismbchar(system_charset_info, name,
2217
2658
                          name+system_charset_info->mbmaxlen);
2218
2659
      if (len)
2219
2660
      {
2238
2679
    name_length++;
2239
2680
  }
2240
2681
  /* Error if empty or too long column name */
2241
 
  return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
 
2682
  return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
2242
2683
}
2243
2684
 
2244
2685
 
2274
2715
    /* previous MySQL version */
2275
2716
    if (DRIZZLE_VERSION_ID > s->mysql_version)
2276
2717
    {
2277
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
 
2718
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2278
2719
                      alias, table_f_count, s->fields,
2279
2720
                      s->mysql_version, DRIZZLE_VERSION_ID);
2280
2721
      return(true);
2281
2722
    }
2282
2723
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
2283
2724
    {
2284
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
 
2725
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2285
2726
                      table_f_count, s->fields);
2286
2727
      return(true);
2287
2728
    }
2300
2741
    sql_type.length(0);
2301
2742
    if (i < s->fields)
2302
2743
    {
2303
 
      Field *field= this->field[i];
 
2744
      Field *cur_field= this->field[i];
2304
2745
 
2305
 
      if (strncmp(field->field_name, table_def->name.str,
 
2746
      if (strncmp(cur_field->field_name, table_def->name.str,
2306
2747
                  table_def->name.length))
2307
2748
      {
2308
2749
        /*
2310
2751
          Still this can be a sign of a tampered table, output an error
2311
2752
          to the error log.
2312
2753
        */
2313
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2754
        errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2314
2755
                        "expected column '%s' at position %d, found '%s'."),
2315
2756
                        s->db.str, alias, table_def->name.str, i,
2316
 
                        field->field_name);
 
2757
                        cur_field->field_name);
2317
2758
      }
2318
 
      field->sql_type(sql_type);
 
2759
      cur_field->sql_type(sql_type);
2319
2760
      /*
2320
2761
        Generally, if column types don't match, then something is
2321
2762
        wrong.
2336
2777
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2337
2778
                  table_def->type.length - 1))
2338
2779
      {
2339
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2780
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2781
                      _("Incorrect definition of table %s.%s: "
2340
2782
                        "expected column '%s' at position %d to have type "
2341
 
                        "%s, found type %s."), s->db.str, alias,
2342
 
                        table_def->name.str, i, table_def->type.str,
2343
 
                        sql_type.c_ptr_safe());
 
2783
                        "%s, found type %s."),
 
2784
                      s->db.str, alias,
 
2785
                      table_def->name.str, i, table_def->type.str,
 
2786
                      sql_type.c_ptr_safe());
2344
2787
        error= true;
2345
2788
      }
2346
 
      else if (table_def->cset.str && !field->has_charset())
 
2789
      else if (table_def->cset.str && !cur_field->has_charset())
2347
2790
      {
2348
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2791
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2792
                      _("Incorrect definition of table %s.%s: "
2349
2793
                        "expected the type of column '%s' at position %d "
2350
2794
                        "to have character set '%s' but the type has no "
2351
 
                        "character set."), s->db.str, alias,
2352
 
                        table_def->name.str, i, table_def->cset.str);
 
2795
                        "character set."),
 
2796
                      s->db.str, alias,
 
2797
                      table_def->name.str, i, table_def->cset.str);
2353
2798
        error= true;
2354
2799
      }
2355
2800
      else if (table_def->cset.str &&
2356
 
               strcmp(field->charset()->csname, table_def->cset.str))
 
2801
               strcmp(cur_field->charset()->csname, table_def->cset.str))
2357
2802
      {
2358
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2803
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2804
                      _("Incorrect definition of table %s.%s: "
2359
2805
                        "expected the type of column '%s' at position %d "
2360
2806
                        "to have character set '%s' but found "
2361
 
                        "character set '%s'."), s->db.str, alias,
2362
 
                        table_def->name.str, i, table_def->cset.str,
2363
 
                        field->charset()->csname);
 
2807
                        "character set '%s'."),
 
2808
                      s->db.str, alias,
 
2809
                      table_def->name.str, i, table_def->cset.str,
 
2810
                      cur_field->charset()->csname);
2364
2811
        error= true;
2365
2812
      }
2366
2813
    }
2367
2814
    else
2368
2815
    {
2369
 
      sql_print_error(_("Incorrect definition of table %s.%s: "
 
2816
      errmsg_printf(ERRMSG_LVL_ERROR,
 
2817
                    _("Incorrect definition of table %s.%s: "
2370
2818
                      "expected column '%s' at position %d to have type %s "
2371
2819
                      " but the column is not found."),
2372
 
                      s->db.str, alias,
2373
 
                      table_def->name.str, i, table_def->type.str);
 
2820
                    s->db.str, alias,
 
2821
                    table_def->name.str, i, table_def->type.str);
2374
2822
      error= true;
2375
2823
    }
2376
2824
  }
2388
2836
  DESCRIPTION
2389
2837
    Create Item_field object for each column in the table and
2390
2838
    initialize it with the corresponding Field. New items are
2391
 
    created in the current THD memory root.
 
2839
    created in the current Session memory root.
2392
2840
 
2393
2841
  RETURN VALUE
2394
2842
    0                    success
2474
2922
 
2475
2923
void TableList::cleanup_items()
2476
2924
{
2477
 
  if (!field_translation)
2478
 
    return;
2479
 
 
2480
 
  for (Field_translator *transl= field_translation;
2481
 
       transl < field_translation_end;
2482
 
       transl++)
2483
 
    transl->item->walk(&Item::cleanup_processor, 0, 0);
 
2925
}
 
2926
 
 
2927
 
 
2928
bool TableList::placeholder()
 
2929
{
 
2930
  return derived || schema_table || (create && !table->getDBStat()) || !table;
2484
2931
}
2485
2932
 
2486
2933
 
2655
3102
void Table::clear_column_bitmaps()
2656
3103
{
2657
3104
  /*
2658
 
    Reset column read/write usage. It's identical to:
2659
 
    bitmap_clear_all(&table->def_read_set);
2660
 
    bitmap_clear_all(&table->def_write_set);
 
3105
    Reset column read/write usage.
2661
3106
  */
2662
 
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
 
3107
  def_read_set.reset();
 
3108
  def_write_set.reset(); /* TODO: is this needed here? */
2663
3109
  column_bitmaps_set(&def_read_set, &def_write_set);
2664
3110
}
2665
3111
 
2666
3112
 
2667
3113
/*
2668
3114
  Tell handler we are going to call position() and rnd_pos() later.
2669
 
  
 
3115
 
2670
3116
  NOTES:
2671
3117
  This is needed for handlers that uses the primary key to find the
2672
3118
  row. In this case we have to extend the read bitmap with the primary
2699
3145
 
2700
3146
void Table::mark_columns_used_by_index(uint32_t index)
2701
3147
{
2702
 
  MY_BITMAP *bitmap= &tmp_set;
 
3148
  bitset<MAX_FIELDS> *bitmap= &tmp_set;
2703
3149
 
2704
3150
  (void) file->extra(HA_EXTRA_KEYREAD);
2705
 
  bitmap_clear_all(bitmap);
 
3151
  bitmap->reset();
2706
3152
  mark_columns_used_by_index_no_reset(index, bitmap);
2707
3153
  column_bitmaps_set(bitmap, bitmap);
2708
3154
  return;
2736
3182
*/
2737
3183
 
2738
3184
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
2739
 
                                                   MY_BITMAP *bitmap)
 
3185
                                                bitset<MAX_FIELDS> *bitmap)
2740
3186
{
2741
3187
  KEY_PART_INFO *key_part= key_info[index].key_part;
2742
3188
  KEY_PART_INFO *key_part_end= (key_part +
2743
3189
                                key_info[index].key_parts);
2744
3190
  for (;key_part != key_part_end; key_part++)
2745
 
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
 
3191
  {
 
3192
    bitmap->set(key_part->fieldnr-1);
 
3193
    if (key_part->field->vcol_info &&
 
3194
        key_part->field->vcol_info->expr_item)
 
3195
      key_part->field->vcol_info->
 
3196
               expr_item->walk(&Item::register_field_in_bitmap,
 
3197
                               1, (unsigned char *) bitmap);
 
3198
  }
2746
3199
}
2747
3200
 
2748
3201
 
2761
3214
    We must set bit in read set as update_auto_increment() is using the
2762
3215
    store() to check overflow of auto_increment values
2763
3216
  */
2764
 
  bitmap_set_bit(read_set, found_next_number_field->field_index);
2765
 
  bitmap_set_bit(write_set, found_next_number_field->field_index);
 
3217
  read_set->set(found_next_number_field->field_index);
 
3218
  write_set->set(found_next_number_field->field_index);
2766
3219
  if (s->next_number_keypart)
2767
3220
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
2768
3221
  file->column_bitmaps_signal();
2795
3248
    for (reg_field= field ; *reg_field ; reg_field++)
2796
3249
    {
2797
3250
      if ((*reg_field)->flags & PART_KEY_FLAG)
2798
 
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
3251
        read_set->set((*reg_field)->field_index);
2799
3252
    }
2800
3253
    file->column_bitmaps_signal();
2801
3254
  }
2802
 
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
2803
 
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
 
3255
 
2804
3256
  {
2805
3257
    /*
2806
3258
      If the handler has no cursor capabilites, or we have row-based
2847
3299
    {
2848
3300
      /* Merge keys is all keys that had a column refered to in the query */
2849
3301
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
2850
 
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
3302
        read_set->set((*reg_field)->field_index);
2851
3303
    }
2852
3304
    file->column_bitmaps_signal();
2853
3305
  }
2854
 
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) ||
2855
 
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
 
3306
 
2856
3307
  {
2857
3308
    /*
2858
3309
      If the handler has no cursor capabilites, or we have row-based
2868
3319
      file->column_bitmaps_signal();
2869
3320
    }
2870
3321
  }
 
3322
  /* Mark all virtual columns as writable */
 
3323
  mark_virtual_columns();
2871
3324
  return;
2872
3325
}
2873
3326
 
2883
3336
{
2884
3337
  if (found_next_number_field)
2885
3338
    mark_auto_increment_column();
2886
 
}
 
3339
  /* Mark all virtual columns as writable */
 
3340
  mark_virtual_columns();
 
3341
}
 
3342
 
 
3343
/*
 
3344
  @brief Update the write and read table bitmap to allow
 
3345
         using procedure save_in_field for all virtual columns
 
3346
         in the table.
 
3347
 
 
3348
  @return       void
 
3349
 
 
3350
  @detail
 
3351
    Each virtual field is set in the write column map.
 
3352
    All fields that the virtual columns are based on are set in the
 
3353
    read bitmap.
 
3354
*/
 
3355
 
 
3356
void Table::mark_virtual_columns(void)
 
3357
{
 
3358
  Field **vfield_ptr, *tmp_vfield;
 
3359
  bool bitmap_updated= false;
 
3360
 
 
3361
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
 
3362
  {
 
3363
    tmp_vfield= *vfield_ptr;
 
3364
    assert(tmp_vfield->vcol_info && tmp_vfield->vcol_info->expr_item);
 
3365
    tmp_vfield->vcol_info->expr_item->walk(&Item::register_field_in_read_map,
 
3366
                                           1, (unsigned char *) 0);
 
3367
    read_set->set(tmp_vfield->field_index);
 
3368
    write_set->set(tmp_vfield->field_index);
 
3369
    bitmap_updated= true;
 
3370
  }
 
3371
  if (bitmap_updated)
 
3372
    file->column_bitmaps_signal();
 
3373
}
 
3374
 
2887
3375
 
2888
3376
/*
2889
3377
  Cleanup this table for re-execution.
2892
3380
    TableList::reinit_before_use()
2893
3381
*/
2894
3382
 
2895
 
void TableList::reinit_before_use(THD *thd)
 
3383
void TableList::reinit_before_use(Session *session)
2896
3384
{
2897
3385
  /*
2898
3386
    Reset old pointers to TABLEs: they are not valid since the tables
2908
3396
  {
2909
3397
    embedded= parent_embedding;
2910
3398
    if (embedded->prep_on_expr)
2911
 
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
 
3399
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
2912
3400
    parent_embedding= embedded->embedding;
2913
3401
  }
2914
3402
  while (parent_embedding &&
2920
3408
 
2921
3409
  SYNOPSIS
2922
3410
    TableList::containing_subselect()
2923
 
 
 
3411
 
2924
3412
  RETURN
2925
3413
    Subselect item for the subquery that contains the FROM list
2926
3414
    this table is taken from if there is any
2929
3417
*/
2930
3418
 
2931
3419
Item_subselect *TableList::containing_subselect()
2932
 
{    
 
3420
{
2933
3421
  return (select_lex ? select_lex->master_unit()->item : 0);
2934
3422
}
2935
3423
 
2941
3429
      table         the Table to operate on.
2942
3430
 
2943
3431
  DESCRIPTION
2944
 
    The parser collects the index hints for each table in a "tagged list" 
 
3432
    The parser collects the index hints for each table in a "tagged list"
2945
3433
    (TableList::index_hints). Using the information in this tagged list
2946
 
    this function sets the members Table::keys_in_use_for_query, 
 
3434
    this function sets the members Table::keys_in_use_for_query,
2947
3435
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
2948
3436
    Table::force_index and Table::covering_keys.
2949
3437
 
2950
3438
    Current implementation of the runtime does not allow mixing FORCE INDEX
2951
 
    and USE INDEX, so this is checked here. Then the FORCE INDEX list 
 
3439
    and USE INDEX, so this is checked here. Then the FORCE INDEX list
2952
3440
    (if non-empty) is appended to the USE INDEX list and a flag is set.
2953
3441
 
2954
 
    Multiple hints of the same kind are processed so that each clause 
 
3442
    Multiple hints of the same kind are processed so that each clause
2955
3443
    is applied to what is computed in the previous clause.
2956
3444
    For example:
2957
3445
        USE INDEX (i1) USE INDEX (i2)
2958
3446
    is equivalent to
2959
3447
        USE INDEX (i1,i2)
2960
3448
    and means "consider only i1 and i2".
2961
 
        
 
3449
 
2962
3450
    Similarly
2963
3451
        USE INDEX () USE INDEX (i1)
2964
3452
    is equivalent to
2967
3455
 
2968
3456
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
2969
3457
    not an error.
2970
 
        
 
3458
 
2971
3459
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
2972
3460
    order:
2973
3461
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
2976
3464
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
2977
3465
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
2978
3466
 
2979
 
    As an optimization if there is a covering index, and we have 
2980
 
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part, 
 
3467
    As an optimization if there is a covering index, and we have
 
3468
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
2981
3469
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
2982
3470
 
2983
3471
  RETURN VALUE
2987
3475
bool TableList::process_index_hints(Table *tbl)
2988
3476
{
2989
3477
  /* initialize the result variables */
2990
 
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
 
3478
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
2991
3479
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
2992
3480
 
2993
3481
  /* index hint list processing */
2998
3486
    key_map index_group[INDEX_HINT_FORCE + 1];
2999
3487
    Index_hint *hint;
3000
3488
    int type;
3001
 
    bool have_empty_use_join= false, have_empty_use_order= false, 
 
3489
    bool have_empty_use_join= false, have_empty_use_order= false,
3002
3490
         have_empty_use_group= false;
3003
3491
    List_iterator <Index_hint> iter(*index_hints);
3004
3492
 
3036
3524
        continue;
3037
3525
      }
3038
3526
 
3039
 
      /* 
3040
 
        Check if an index with the given name exists and get his offset in 
3041
 
        the keys bitmask for the table 
 
3527
      /*
 
3528
        Check if an index with the given name exists and get his offset in
 
3529
        the keys bitmask for the table
3042
3530
      */
3043
3531
      if (tbl->s->keynames.type_names == 0 ||
3044
3532
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
3119
3607
  return length;
3120
3608
}
3121
3609
 
3122
 
/*
3123
 
  Check type of .frm if we are not going to parse it
3124
 
 
3125
 
  SYNOPSIS
3126
 
  mysql_frm_type()
3127
 
  path        path to file
3128
 
 
3129
 
  RETURN
3130
 
  false       error
3131
 
  true       table
3132
 
*/
3133
 
 
3134
 
bool mysql_frm_type(THD *thd __attribute__((unused)),
3135
 
                    char *path, enum legacy_db_type *dbt)
3136
 
{
3137
 
  File file;
3138
 
  unsigned char header[10];     /* This should be optimized */
3139
 
  int error;
3140
 
 
3141
 
  *dbt= DB_TYPE_UNKNOWN;
3142
 
 
3143
 
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
3144
 
    return false;
3145
 
  error= my_read(file, (unsigned char*) header, sizeof(header), MYF(MY_NABP));
3146
 
  my_close(file, MYF(MY_WME));
3147
 
 
3148
 
  if (error)
3149
 
    return false;
3150
 
 
3151
 
  /*  
3152
 
    This is just a check for DB_TYPE. We'll return default unknown type
3153
 
    if the following test is true (arg #3). This should not have effect
3154
 
    on return value from this function (default FRMTYPE_TABLE)
3155
 
   */  
3156
 
  if (header[0] != (unsigned char) 254 || header[1] != 1 ||
3157
 
      (header[2] != FRM_VER && header[2] != FRM_VER+1 &&
3158
 
       (header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
3159
 
    return true;
3160
 
 
3161
 
  *dbt= (enum legacy_db_type) (uint) *(header + 3);
3162
 
  return true;                   // Is probably a .frm table
3163
 
}
3164
 
 
3165
3610
/****************************************************************************
3166
3611
 Functions for creating temporary tables.
3167
3612
****************************************************************************/
3168
3613
 
3169
3614
 
3170
3615
/* Prototypes */
3171
 
void free_tmp_table(THD *thd, Table *entry);
 
3616
void free_tmp_table(Session *session, Table *entry);
3172
3617
 
3173
3618
/**
3174
3619
  Create field for temporary table from given field.
3175
3620
 
3176
 
  @param thd           Thread handler
 
3621
  @param session               Thread handler
3177
3622
  @param org_field    field from which new field will be created
3178
3623
  @param name         New field name
3179
3624
  @param table         Temporary table
3192
3637
    new_created field
3193
3638
*/
3194
3639
 
3195
 
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
 
3640
Field *create_tmp_field_from_field(Session *session, Field *org_field,
3196
3641
                                   const char *name, Table *table,
3197
3642
                                   Item_field *item, uint32_t convert_blob_length)
3198
3643
{
3199
3644
  Field *new_field;
3200
3645
 
3201
 
  /* 
3202
 
    Make sure that the blob fits into a Field_varstring which has 
3203
 
    2-byte lenght. 
 
3646
  /*
 
3647
    Make sure that the blob fits into a Field_varstring which has
 
3648
    2-byte lenght.
3204
3649
  */
3205
3650
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
3206
3651
      (org_field->flags & BLOB_FLAG))
3209
3654
                                   org_field->field_name, table->s,
3210
3655
                                   org_field->charset());
3211
3656
  else
3212
 
    new_field= org_field->new_field(thd->mem_root, table,
 
3657
    new_field= org_field->new_field(session->mem_root, table,
3213
3658
                                    table == org_field->table);
3214
3659
  if (new_field)
3215
3660
  {
3230
3675
  return new_field;
3231
3676
}
3232
3677
 
3233
 
/**
3234
 
  Create field for temporary table using type of given item.
3235
 
 
3236
 
  @param thd                   Thread handler
3237
 
  @param item                  Item to create a field for
3238
 
  @param table                 Temporary table
3239
 
  @param copy_func             If set and item is a function, store copy of
3240
 
                               item in this array
3241
 
  @param modify_item           1 if item->result_field should point to new
3242
 
                               item. This is relevent for how fill_record()
3243
 
                               is going to work:
3244
 
                               If modify_item is 1 then fill_record() will
3245
 
                               update the record in the original table.
3246
 
                               If modify_item is 0 then fill_record() will
3247
 
                               update the temporary table
3248
 
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
3249
 
                               field instead of blob.
3250
 
 
3251
 
  @retval
3252
 
    0  on error
3253
 
  @retval
3254
 
    new_created field
3255
 
*/
3256
 
 
3257
 
static Field *create_tmp_field_from_item(THD *thd __attribute__((unused)),
3258
 
                                         Item *item, Table *table,
3259
 
                                         Item ***copy_func, bool modify_item,
3260
 
                                         uint32_t convert_blob_length)
3261
 
{
3262
 
  bool maybe_null= item->maybe_null;
3263
 
  Field *new_field;
3264
 
 
3265
 
  switch (item->result_type()) {
3266
 
  case REAL_RESULT:
3267
 
    new_field= new Field_double(item->max_length, maybe_null,
3268
 
                                item->name, item->decimals, true);
3269
 
    break;
3270
 
  case INT_RESULT:
3271
 
    /* 
3272
 
      Select an integer type with the minimal fit precision.
3273
 
      MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
3274
 
      Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into 
3275
 
      Field_long : make them Field_int64_t.  
3276
 
    */
3277
 
    if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
3278
 
      new_field=new Field_int64_t(item->max_length, maybe_null,
3279
 
                                   item->name, item->unsigned_flag);
3280
 
    else
3281
 
      new_field=new Field_long(item->max_length, maybe_null,
3282
 
                               item->name, item->unsigned_flag);
3283
 
    break;
3284
 
  case STRING_RESULT:
3285
 
    assert(item->collation.collation);
3286
 
  
3287
 
    enum enum_field_types type;
3288
 
    /*
3289
 
      DATE/TIME fields have STRING_RESULT result type. 
3290
 
      To preserve type they needed to be handled separately.
3291
 
    */
3292
 
    if ((type= item->field_type()) == DRIZZLE_TYPE_DATETIME ||
3293
 
        type == DRIZZLE_TYPE_TIME || type == DRIZZLE_TYPE_NEWDATE ||
3294
 
        type == DRIZZLE_TYPE_TIMESTAMP)
3295
 
      new_field= item->tmp_table_field_from_field_type(table, 1);
3296
 
    /* 
3297
 
      Make sure that the blob fits into a Field_varstring which has 
3298
 
      2-byte lenght. 
3299
 
    */
3300
 
    else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
3301
 
             convert_blob_length <= Field_varstring::MAX_SIZE && 
3302
 
             convert_blob_length)
3303
 
      new_field= new Field_varstring(convert_blob_length, maybe_null,
3304
 
                                     item->name, table->s,
3305
 
                                     item->collation.collation);
3306
 
    else
3307
 
      new_field= item->make_string_field(table);
3308
 
    new_field->set_derivation(item->collation.derivation);
3309
 
    break;
3310
 
  case DECIMAL_RESULT:
3311
 
  {
3312
 
    uint8_t dec= item->decimals;
3313
 
    uint8_t intg= ((Item_decimal *) item)->decimal_precision() - dec;
3314
 
    uint32_t len= item->max_length;
3315
 
 
3316
 
    /*
3317
 
      Trying to put too many digits overall in a DECIMAL(prec,dec)
3318
 
      will always throw a warning. We must limit dec to
3319
 
      DECIMAL_MAX_SCALE however to prevent an assert() later.
3320
 
    */
3321
 
 
3322
 
    if (dec > 0)
3323
 
    {
3324
 
      signed int overflow;
3325
 
 
3326
 
      dec= cmin(dec, (uint8_t)DECIMAL_MAX_SCALE);
3327
 
 
3328
 
      /*
3329
 
        If the value still overflows the field with the corrected dec,
3330
 
        we'll throw out decimals rather than integers. This is still
3331
 
        bad and of course throws a truncation warning.
3332
 
        +1: for decimal point
3333
 
      */
3334
 
 
3335
 
      overflow= my_decimal_precision_to_length(intg + dec, dec,
3336
 
                                               item->unsigned_flag) - len;
3337
 
 
3338
 
      if (overflow > 0)
3339
 
        dec= cmax(0, dec - overflow);            // too long, discard fract
3340
 
      else
3341
 
        len -= item->decimals - dec;            // corrected value fits
3342
 
    }
3343
 
 
3344
 
    new_field= new Field_new_decimal(len, maybe_null, item->name,
3345
 
                                     dec, item->unsigned_flag);
3346
 
    break;
3347
 
  }
3348
 
  case ROW_RESULT:
3349
 
  default:
3350
 
    // This case should never be choosen
3351
 
    assert(0);
3352
 
    new_field= 0;
3353
 
    break;
3354
 
  }
3355
 
  if (new_field)
3356
 
    new_field->init(table);
3357
 
    
3358
 
  if (copy_func && item->is_result_field())
3359
 
    *((*copy_func)++) = item;                   // Save for copy_funcs
3360
 
  if (modify_item)
3361
 
    item->set_result_field(new_field);
3362
 
  if (item->type() == Item::NULL_ITEM)
3363
 
    new_field->is_created_from_null_item= true;
3364
 
  return new_field;
3365
 
}
3366
 
 
3367
3678
 
3368
3679
/**
3369
3680
  Create field for information schema table.
3370
3681
 
3371
 
  @param thd            Thread handler
 
3682
  @param session                Thread handler
3372
3683
  @param table          Temporary table
3373
3684
  @param item           Item to create a field for
3374
3685
 
3378
3689
    new_created field
3379
3690
*/
3380
3691
 
3381
 
Field *create_tmp_field_for_schema(THD *thd __attribute__((unused)),
3382
 
                                   Item *item, Table *table)
 
3692
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
3383
3693
{
3384
3694
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
3385
3695
  {
3400
3710
 
3401
3711
 
3402
3712
/**
3403
 
  Create field for temporary table.
3404
 
 
3405
 
  @param thd            Thread handler
3406
 
  @param table          Temporary table
3407
 
  @param item           Item to create a field for
3408
 
  @param type           Type of item (normally item->type)
3409
 
  @param copy_func      If set and item is a function, store copy of item
3410
 
                       in this array
3411
 
  @param from_field    if field will be created using other field as example,
3412
 
                       pointer example field will be written here
3413
 
  @param default_field  If field has a default value field, store it here
3414
 
  @param group          1 if we are going to do a relative group by on result
3415
 
  @param modify_item    1 if item->result_field should point to new item.
3416
 
                       This is relevent for how fill_record() is going to
3417
 
                       work:
3418
 
                       If modify_item is 1 then fill_record() will update
3419
 
                       the record in the original table.
3420
 
                       If modify_item is 0 then fill_record() will update
3421
 
                       the temporary table
3422
 
  @param convert_blob_length If >0 create a varstring(convert_blob_length)
3423
 
                             field instead of blob.
3424
 
 
3425
 
  @retval
3426
 
    0                   on error
3427
 
  @retval
3428
 
    new_created field
3429
 
*/
3430
 
 
3431
 
Field *create_tmp_field(THD *thd, Table *table,Item *item, Item::Type type,
3432
 
                        Item ***copy_func, Field **from_field,
3433
 
                        Field **default_field,
3434
 
                        bool group, bool modify_item,
3435
 
                        bool table_cant_handle_bit_fields __attribute__((unused)),
3436
 
                        bool make_copy_field,
3437
 
                        uint32_t convert_blob_length)
3438
 
{
3439
 
  Field *result;
3440
 
  Item::Type orig_type= type;
3441
 
  Item *orig_item= 0;
3442
 
 
3443
 
  if (type != Item::FIELD_ITEM &&
3444
 
      item->real_item()->type() == Item::FIELD_ITEM)
3445
 
  {
3446
 
    orig_item= item;
3447
 
    item= item->real_item();
3448
 
    type= Item::FIELD_ITEM;
3449
 
  }
3450
 
 
3451
 
  switch (type) {
3452
 
  case Item::SUM_FUNC_ITEM:
3453
 
  {
3454
 
    Item_sum *item_sum=(Item_sum*) item;
3455
 
    result= item_sum->create_tmp_field(group, table, convert_blob_length);
3456
 
    if (!result)
3457
 
      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
3458
 
    return result;
3459
 
  }
3460
 
  case Item::FIELD_ITEM:
3461
 
  case Item::DEFAULT_VALUE_ITEM:
3462
 
  {
3463
 
    Item_field *field= (Item_field*) item;
3464
 
    bool orig_modify= modify_item;
3465
 
    if (orig_type == Item::REF_ITEM)
3466
 
      modify_item= 0;
3467
 
    /*
3468
 
      If item have to be able to store NULLs but underlaid field can't do it,
3469
 
      create_tmp_field_from_field() can't be used for tmp field creation.
3470
 
    */
3471
 
    if (field->maybe_null && !field->field->maybe_null())
3472
 
    {
3473
 
      result= create_tmp_field_from_item(thd, item, table, NULL,
3474
 
                                         modify_item, convert_blob_length);
3475
 
      *from_field= field->field;
3476
 
      if (result && modify_item)
3477
 
        field->result_field= result;
3478
 
    } 
3479
 
    else
3480
 
      result= create_tmp_field_from_field(thd, (*from_field= field->field),
3481
 
                                          orig_item ? orig_item->name :
3482
 
                                          item->name,
3483
 
                                          table,
3484
 
                                          modify_item ? field :
3485
 
                                          NULL,
3486
 
                                          convert_blob_length);
3487
 
    if (orig_type == Item::REF_ITEM && orig_modify)
3488
 
      ((Item_ref*)orig_item)->set_result_field(result);
3489
 
    if (field->field->eq_def(result))
3490
 
      *default_field= field->field;
3491
 
    return result;
3492
 
  }
3493
 
  /* Fall through */
3494
 
  case Item::FUNC_ITEM:
3495
 
    /* Fall through */
3496
 
  case Item::COND_ITEM:
3497
 
  case Item::FIELD_AVG_ITEM:
3498
 
  case Item::FIELD_STD_ITEM:
3499
 
  case Item::SUBSELECT_ITEM:
3500
 
    /* The following can only happen with 'CREATE TABLE ... SELECT' */
3501
 
  case Item::PROC_ITEM:
3502
 
  case Item::INT_ITEM:
3503
 
  case Item::REAL_ITEM:
3504
 
  case Item::DECIMAL_ITEM:
3505
 
  case Item::STRING_ITEM:
3506
 
  case Item::REF_ITEM:
3507
 
  case Item::NULL_ITEM:
3508
 
  case Item::VARBIN_ITEM:
3509
 
    if (make_copy_field)
3510
 
    {
3511
 
      assert(((Item_result_field*)item)->result_field);
3512
 
      *from_field= ((Item_result_field*)item)->result_field;
3513
 
    }
3514
 
    return create_tmp_field_from_item(thd, item, table,
3515
 
                                      (make_copy_field ? 0 : copy_func),
3516
 
                                       modify_item, convert_blob_length);
3517
 
  case Item::TYPE_HOLDER:  
3518
 
    result= ((Item_type_holder *)item)->make_field_by_type(table);
3519
 
    result->set_derivation(item->collation.derivation);
3520
 
    return result;
3521
 
  default:                                      // Dosen't have to be stored
3522
 
    return 0;
3523
 
  }
3524
 
}
3525
 
 
3526
 
/**
3527
3713
  Create a temp table according to a field list.
3528
3714
 
3529
3715
  Given field pointers are changed to point at tmp_table for
3534
3720
  corresponding Item_field items, pointing at the fields in the
3535
3721
  temporary table, unless this was prohibited by true
3536
3722
  value of argument save_sum_fields. The Item_field objects
3537
 
  are created in THD memory root.
 
3723
  are created in Session memory root.
3538
3724
 
3539
 
  @param thd                  thread handle
 
3725
  @param session                  thread handle
3540
3726
  @param param                a description used as input to create the table
3541
3727
  @param fields               list of items that will be used to define
3542
3728
                              column types of the table (also see NOTES)
3552
3738
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
3553
3739
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
3554
3740
#define RATIO_TO_PACK_ROWS             2
3555
 
#define MIN_STRING_LENGTH_TO_PACK_ROWS   10
3556
3741
 
3557
3742
Table *
3558
 
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
 
3743
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
3559
3744
                 order_st *group, bool distinct, bool save_sum_fields,
3560
3745
                 uint64_t select_options, ha_rows rows_limit,
3561
3746
                 char *table_alias)
3567
3752
  uint32_t  copy_func_count= param->func_count;
3568
3753
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
3569
3754
  uint32_t  blob_count,group_null_items, string_count;
3570
 
  uint32_t  temp_pool_slot=MY_BIT_NONE;
 
3755
  uint32_t  temp_pool_slot= MY_BIT_NONE;
3571
3756
  uint32_t fieldnr= 0;
3572
3757
  ulong reclength, string_total_length;
3573
3758
  bool  using_unique_constraint= 0;
3586
3771
  uint32_t total_uneven_bit_length= 0;
3587
3772
  bool force_copy_fields= param->force_copy_fields;
3588
3773
 
3589
 
  status_var_increment(thd->status_var.created_tmp_tables);
 
3774
  status_var_increment(session->status_var.created_tmp_tables);
3590
3775
 
3591
3776
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
3592
 
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
 
3777
    setNextBit(temp_pool);
3593
3778
 
3594
3779
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
3595
 
    sprintf(path, "%s_%lx_%i", tmp_file_prefix,
3596
 
            current_pid, temp_pool_slot);
 
3780
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
 
3781
            (unsigned long)current_pid, temp_pool_slot);
3597
3782
  else
3598
3783
  {
3599
3784
    /* if we run out of slots or we are not using tempool */
3600
 
    sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
3601
 
            thd->thread_id, thd->tmp_table++);
 
3785
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
3786
            session->thread_id, session->tmp_table++);
3602
3787
  }
3603
3788
 
3604
3789
  /*
3605
3790
    No need to change table name to lower case as we are only creating
3606
3791
    MyISAM or HEAP tables here
3607
3792
  */
3608
 
  fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3793
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
3609
3794
 
3610
3795
 
3611
3796
  if (group)
3637
3822
    When loose index scan is employed as access method, it already
3638
3823
    computes all groups and the result of all aggregate functions. We
3639
3824
    make space for the items of the aggregate function in the list of
3640
 
    functions TMP_TABLE_PARAM::items_to_copy, so that the values of
 
3825
    functions Tmp_Table_Param::items_to_copy, so that the values of
3641
3826
    these items are stored in the temporary table.
3642
3827
  */
3643
3828
  if (param->precomputed_group_by)
3644
3829
    copy_func_count+= param->sum_func_count;
3645
 
  
 
3830
 
3646
3831
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
3647
3832
 
3648
3833
  if (!multi_alloc_root(&own_root,
3650
3835
                        &share, sizeof(*share),
3651
3836
                        &reg_field, sizeof(Field*) * (field_count+1),
3652
3837
                        &default_field, sizeof(Field*) * (field_count),
3653
 
                        &blob_field, sizeof(uint)*(field_count+1),
 
3838
                        &blob_field, sizeof(uint32_t)*(field_count+1),
3654
3839
                        &from_field, sizeof(Field*)*field_count,
3655
3840
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
3656
3841
                        &param->keyinfo, sizeof(*param->keyinfo),
3658
3843
                        sizeof(*key_part_info)*(param->group_parts+1),
3659
3844
                        &param->start_recinfo,
3660
3845
                        sizeof(*param->recinfo)*(field_count*2+4),
3661
 
                        &tmpname, (uint) strlen(path)+1,
 
3846
                        &tmpname, (uint32_t) strlen(path)+1,
3662
3847
                        &group_buff, (group && ! using_unique_constraint ?
3663
3848
                                      param->group_length : 0),
3664
3849
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3665
3850
                        NULL))
3666
3851
  {
3667
3852
    if (temp_pool_slot != MY_BIT_NONE)
3668
 
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3853
      temp_pool.reset(temp_pool_slot);
3669
3854
    return(NULL);                               /* purecov: inspected */
3670
3855
  }
3671
 
  /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
3672
 
  if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
 
3856
  /* Copy_field belongs to Tmp_Table_Param, allocate it in Session mem_root */
 
3857
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
3673
3858
  {
3674
3859
    if (temp_pool_slot != MY_BIT_NONE)
3675
 
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3860
      temp_pool.reset(temp_pool_slot);
3676
3861
    free_root(&own_root, MYF(0));               /* purecov: inspected */
3677
3862
    return(NULL);                               /* purecov: inspected */
3678
3863
  }
3679
3864
  param->items_to_copy= copy_func;
3680
 
  my_stpcpy(tmpname,path);
 
3865
  strcpy(tmpname,path);
3681
3866
  /* make table according to fields */
3682
3867
 
3683
3868
  memset(table, 0, sizeof(*table));
3686
3871
  memset(from_field, 0, sizeof(Field*)*field_count);
3687
3872
 
3688
3873
  table->mem_root= own_root;
3689
 
  mem_root_save= thd->mem_root;
3690
 
  thd->mem_root= &table->mem_root;
 
3874
  mem_root_save= session->mem_root;
 
3875
  session->mem_root= &table->mem_root;
3691
3876
 
3692
3877
  table->field=reg_field;
3693
3878
  table->alias= table_alias;
3694
3879
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
3695
3880
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
3696
3881
  table->map=1;
3697
 
  table->temp_pool_slot = temp_pool_slot;
 
3882
  table->temp_pool_slot= temp_pool_slot;
3698
3883
  table->copy_blobs= 1;
3699
 
  table->in_use= thd;
 
3884
  table->in_use= session;
3700
3885
  table->quick_keys.init();
3701
3886
  table->covering_keys.init();
3702
3887
  table->keys_in_use_for_query.init();
3703
3888
 
3704
3889
  table->setShare(share);
3705
 
  init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
 
3890
  init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
3706
3891
  share->blob_field= blob_field;
3707
3892
  share->blob_ptr_size= portable_sizeof_char_ptr;
3708
3893
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
3754
3939
        if (!arg->const_item())
3755
3940
        {
3756
3941
          Field *new_field=
3757
 
            create_tmp_field(thd, table, arg, arg->type(), &copy_func,
 
3942
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
3758
3943
                             tmp_from_field, &default_field[fieldnr],
3759
3944
                             group != 0,not_all_columns,
3760
3945
                             distinct, 0,
3774
3959
            string_count++;
3775
3960
            string_total_length+= new_field->pack_length();
3776
3961
          }
3777
 
          thd->mem_root= mem_root_save;
3778
 
          thd->change_item_tree(argp, new Item_field(new_field));
3779
 
          thd->mem_root= &table->mem_root;
 
3962
          session->mem_root= mem_root_save;
 
3963
          session->change_item_tree(argp, new Item_field(new_field));
 
3964
          session->mem_root= &table->mem_root;
3780
3965
          if (!(new_field->flags & NOT_NULL_FLAG))
3781
3966
          {
3782
3967
            null_count++;
3803
3988
        that in the later case group is set to the row pointer.
3804
3989
      */
3805
3990
      Field *new_field= (param->schema_table) ?
3806
 
        create_tmp_field_for_schema(thd, item, table) :
3807
 
        create_tmp_field(thd, table, item, type, &copy_func,
 
3991
        create_tmp_field_for_schema(session, item, table) :
 
3992
        create_tmp_field(session, table, item, type, &copy_func,
3808
3993
                         tmp_from_field, &default_field[fieldnr],
3809
3994
                         group != 0,
3810
3995
                         !force_copy_fields &&
3822
4007
 
3823
4008
      if (!new_field)
3824
4009
      {
3825
 
        if (thd->is_fatal_error)
 
4010
        if (session->is_fatal_error)
3826
4011
          goto err;                             // Got OOM
3827
4012
        continue;                               // Some kindf of const item
3828
4013
      }
3860
4045
      null_count= 0;
3861
4046
    }
3862
4047
  }
3863
 
  assert(fieldnr == (uint) (reg_field - table->field));
3864
 
  assert(field_count >= (uint) (reg_field - table->field));
 
4048
  assert(fieldnr == (uint32_t) (reg_field - table->field));
 
4049
  assert(field_count >= (uint32_t) (reg_field - table->field));
3865
4050
  field_count= fieldnr;
3866
4051
  *reg_field= 0;
3867
4052
  *blob_field= 0;                               // End marker
3873
4058
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3874
4059
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
3875
4060
  {
3876
 
    share->db_plugin= ha_lock_engine(0, myisam_hton);
 
4061
    share->storage_engine= myisam_engine;
3877
4062
    table->file= get_new_handler(share, &table->mem_root,
3878
4063
                                 share->db_type());
3879
4064
    if (group &&
3883
4068
  }
3884
4069
  else
3885
4070
  {
3886
 
    share->db_plugin= ha_lock_engine(0, heap_hton);
 
4071
    share->storage_engine= heap_engine;
3887
4072
    table->file= get_new_handler(share, &table->mem_root,
3888
4073
                                 share->db_type());
3889
4074
  }
3924
4109
    share->default_values= table->record[1]+alloc_length;
3925
4110
  }
3926
4111
  copy_func[0]=0;                               // End marker
3927
 
  param->func_count= copy_func - param->items_to_copy; 
 
4112
  param->func_count= copy_func - param->items_to_copy;
3928
4113
 
3929
 
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
4114
  table->setup_tmp_table_column_bitmaps();
3930
4115
 
3931
4116
  recinfo=param->start_recinfo;
3932
4117
  null_flags=(unsigned char*) table->record[0];
3984
4169
    */
3985
4170
    if (default_field[i] && default_field[i]->ptr)
3986
4171
    {
3987
 
      /* 
 
4172
      /*
3988
4173
         default_field[i] is set only in the cases  when 'field' can
3989
4174
         inherit the default value that is defined for the field referred
3990
4175
         by the Item_field object from which 'field' has been created.
4003
4188
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
4004
4189
      }
4005
4190
      orig_field->move_field_offset(-diff);     // Back to record[0]
4006
 
    } 
 
4191
    }
4007
4192
 
4008
4193
    if (from_field[i])
4009
4194
    {                                           /* Not a table Item */
4030
4215
  param->recinfo=recinfo;
4031
4216
  store_record(table,s->default_values);        // Make empty default record
4032
4217
 
4033
 
  if (thd->variables.tmp_table_size == ~ (uint64_t) 0)          // No limit
 
4218
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
4034
4219
    share->max_rows= ~(ha_rows) 0;
4035
4220
  else
4036
 
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
4037
 
                                 cmin(thd->variables.tmp_table_size,
4038
 
                                     thd->variables.max_heap_table_size) :
4039
 
                                 thd->variables.tmp_table_size) /
 
4221
    share->max_rows= (ha_rows) (((share->db_type() == heap_engine) ?
 
4222
                                 cmin(session->variables.tmp_table_size,
 
4223
                                     session->variables.max_heap_table_size) :
 
4224
                                 session->variables.tmp_table_size) /
4040
4225
                                 share->reclength);
4041
 
  set_if_bigger(share->max_rows,1);             // For dummy start options
 
4226
  set_if_bigger(share->max_rows,(ha_rows)1);    // For dummy start options
4042
4227
  /*
4043
4228
    Push the LIMIT clause to the temporary table creation, so that we
4044
4229
    materialize only up to 'rows_limit' records instead of all result records.
4080
4265
      if (!using_unique_constraint)
4081
4266
      {
4082
4267
        cur_group->buff=(char*) group_buff;
4083
 
        if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
 
4268
        if (!(cur_group->field= field->new_key_field(session->mem_root,table,
4084
4269
                                                     group_buff +
4085
4270
                                                     test(maybe_null),
4086
4271
                                                     field->null_ptr,
4096
4281
          */
4097
4282
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
4098
4283
          key_part_info->null_bit=field->null_bit;
4099
 
          key_part_info->null_offset= (uint) (field->null_ptr -
 
4284
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
4100
4285
                                              (unsigned char*) table->record[0]);
4101
4286
          cur_group->buff++;                        // Pointer to field data
4102
4287
          group_buff++;                         // Skipp null flag
4158
4343
                                                (uint32_t) key_part_info->length,
4159
4344
                                                0,
4160
4345
                                                (unsigned char*) 0,
4161
 
                                                (uint) 0,
 
4346
                                                (uint32_t) 0,
4162
4347
                                                Field::NONE,
4163
 
                                                NULL, 
 
4348
                                                NULL,
4164
4349
                                                table->s,
4165
4350
                                                &my_charset_bin);
4166
4351
      if (!key_part_info->field)
4191
4376
 
4192
4377
      if ((*reg_field)->real_maybe_null())
4193
4378
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
4194
 
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB || 
 
4379
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB ||
4195
4380
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
4196
4381
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
4197
4382
 
4204
4389
    }
4205
4390
  }
4206
4391
 
4207
 
  if (thd->is_fatal_error)                              // If end of memory
 
4392
  if (session->is_fatal_error)                          // If end of memory
4208
4393
    goto err;                                    /* purecov: inspected */
4209
4394
  share->db_record_offset= 1;
4210
 
  if (share->db_type() == myisam_hton)
 
4395
  if (share->db_type() == myisam_engine)
4211
4396
  {
4212
4397
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
4213
4398
                                       &param->recinfo, select_options))
4216
4401
  if (table->open_tmp_table())
4217
4402
    goto err;
4218
4403
 
4219
 
  thd->mem_root= mem_root_save;
 
4404
  session->mem_root= mem_root_save;
4220
4405
 
4221
4406
  return(table);
4222
4407
 
4223
4408
err:
4224
 
  thd->mem_root= mem_root_save;
4225
 
  table->free_tmp_table(thd);                    /* purecov: inspected */
 
4409
  session->mem_root= mem_root_save;
 
4410
  table->free_tmp_table(session);                    /* purecov: inspected */
4226
4411
  if (temp_pool_slot != MY_BIT_NONE)
4227
 
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
4412
    temp_pool.reset(temp_pool_slot);
4228
4413
  return(NULL);                         /* purecov: inspected */
4229
4414
}
4230
4415
 
4239
4424
    The sole purpose of this Table object is to use the power of Field
4240
4425
    class to read/write data to/from table->record[0]. Then one can store
4241
4426
    the record in any container (RB tree, hash, etc).
4242
 
    The table is created in THD mem_root, so are the table's fields.
 
4427
    The table is created in Session mem_root, so are the table's fields.
4243
4428
    Consequently, if you don't BLOB fields, you don't need to free it.
4244
4429
 
4245
 
  @param thd         connection handle
 
4430
  @param session         connection handle
4246
4431
  @param field_list  list of column definitions
4247
4432
 
4248
4433
  @return
4249
4434
    0 if out of memory, Table object in case of success
4250
4435
*/
4251
4436
 
4252
 
Table *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
 
4437
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4253
4438
{
4254
4439
  uint32_t field_count= field_list.elements;
4255
4440
  uint32_t blob_count= 0;
4263
4448
  Table *table;
4264
4449
  TABLE_SHARE *share;
4265
4450
 
4266
 
  if (!multi_alloc_root(thd->mem_root,
 
4451
  if (!multi_alloc_root(session->mem_root,
4267
4452
                        &table, sizeof(*table),
4268
4453
                        &share, sizeof(*share),
4269
4454
                        &field, (field_count + 1) * sizeof(Field*),
4270
 
                        &blob_field, (field_count+1) *sizeof(uint),
 
4455
                        &blob_field, (field_count+1) *sizeof(uint32_t),
4271
4456
                        &bitmaps, bitmap_buffer_size(field_count)*2,
4272
4457
                        NULL))
4273
4458
    return 0;
4279
4464
  share->blob_field= blob_field;
4280
4465
  share->fields= field_count;
4281
4466
  share->blob_ptr_size= portable_sizeof_char_ptr;
4282
 
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
4467
  table->setup_tmp_table_column_bitmaps();
4283
4468
 
4284
4469
  /* Create all fields and calculate the total length of record */
4285
4470
  List_iterator_fast<Create_field> it(field_list);
4286
4471
  while ((cdef= it++))
4287
4472
  {
4288
 
    *field= make_field(share, 0, cdef->length,
 
4473
    *field= make_field(share, NULL, 0, cdef->length,
4289
4474
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4290
4475
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
4291
4476
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
4299
4484
      null_count++;
4300
4485
 
4301
4486
    if ((*field)->flags & BLOB_FLAG)
4302
 
      share->blob_field[blob_count++]= (uint) (field - table->field);
 
4487
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
4303
4488
 
4304
4489
    field++;
4305
4490
  }
4310
4495
  null_pack_length= (null_count + 7)/8;
4311
4496
  share->reclength= record_length + null_pack_length;
4312
4497
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4313
 
  table->record[0]= (unsigned char*) thd->alloc(share->rec_buff_length);
 
4498
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4314
4499
  if (!table->record[0])
4315
4500
    goto error;
4316
4501
 
4321
4506
    share->null_bytes= null_pack_length;
4322
4507
  }
4323
4508
 
4324
 
  table->in_use= thd;           /* field->reset() may access table->in_use */
 
4509
  table->in_use= session;           /* field->reset() may access table->in_use */
4325
4510
  {
4326
4511
    /* Set up field pointers */
4327
4512
    unsigned char *null_pos= table->record[0];
4380
4565
      start_recinfo   MyISAM's column descriptions
4381
4566
      recinfo INOUT   End of MyISAM's column descriptions
4382
4567
      options         Option bits
4383
 
   
 
4568
 
4384
4569
  DESCRIPTION
4385
4570
    Create a MyISAM temporary table according to passed description. The is
4386
4571
    assumed to have one unique index or constraint.
4391
4576
         when there are many nullable columns)
4392
4577
      2. Table columns
4393
4578
      3. One free MI_COLUMNDEF element (*recinfo points here)
4394
 
   
 
4579
 
4395
4580
    This function may use the free element to create hash column for unique
4396
4581
    constraint.
4397
4582
 
4400
4585
     true  - Error
4401
4586
*/
4402
4587
 
4403
 
bool Table::create_myisam_tmp_table(KEY *keyinfo, 
 
4588
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4404
4589
                                    MI_COLUMNDEF *start_recinfo,
4405
 
                                    MI_COLUMNDEF **recinfo, 
 
4590
                                    MI_COLUMNDEF **recinfo,
4406
4591
                                    uint64_t options)
4407
4592
{
4408
4593
  int error;
4449
4634
    }
4450
4635
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4451
4636
    {
4452
 
      Field *field=keyinfo->key_part[i].field;
 
4637
      Field *key_field=keyinfo->key_part[i].field;
4453
4638
      seg->flag=     0;
4454
 
      seg->language= field->charset()->number;
 
4639
      seg->language= key_field->charset()->number;
4455
4640
      seg->length=   keyinfo->key_part[i].length;
4456
4641
      seg->start=    keyinfo->key_part[i].offset;
4457
 
      if (field->flags & BLOB_FLAG)
 
4642
      if (key_field->flags & BLOB_FLAG)
4458
4643
      {
4459
4644
        seg->type=
4460
4645
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4461
4646
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4462
 
        seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
 
4647
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
4648
                                  - share->blob_ptr_size);
4463
4649
        seg->flag= HA_BLOB_PART;
4464
4650
        seg->length=0;                  // Whole blob in unique constraint
4465
4651
      }
4467
4653
      {
4468
4654
        seg->type= keyinfo->key_part[i].type;
4469
4655
      }
4470
 
      if (!(field->flags & NOT_NULL_FLAG))
 
4656
      if (!(key_field->flags & NOT_NULL_FLAG))
4471
4657
      {
4472
 
        seg->null_bit= field->null_bit;
4473
 
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) record[0]);
 
4658
        seg->null_bit= key_field->null_bit;
 
4659
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
4474
4660
        /*
4475
4661
          We are using a GROUP BY on something that contains NULL
4476
4662
          In this case we have to tell MyISAM that two NULL should
4489
4675
    create_info.data_file_length= ~(uint64_t) 0;
4490
4676
 
4491
4677
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4492
 
                       (uint) (*recinfo-start_recinfo),
 
4678
                       (uint32_t) (*recinfo-start_recinfo),
4493
4679
                       start_recinfo,
4494
4680
                       share->uniques, &uniquedef,
4495
4681
                       &create_info,
4507
4693
}
4508
4694
 
4509
4695
 
4510
 
void Table::free_tmp_table(THD *thd)
 
4696
void Table::free_tmp_table(Session *session)
4511
4697
{
4512
4698
  MEM_ROOT own_root= mem_root;
4513
4699
  const char *save_proc_info;
4514
4700
 
4515
 
  save_proc_info=thd->get_proc_info();
4516
 
  thd_proc_info(thd, "removing tmp table");
 
4701
  save_proc_info=session->get_proc_info();
 
4702
  session->set_proc_info("removing tmp table");
 
4703
 
 
4704
  // Release latches since this can take a long time
 
4705
  ha_release_temporary_latches(session);
4517
4706
 
4518
4707
  if (file)
4519
4708
  {
4530
4719
  free_io_cache(this);
4531
4720
 
4532
4721
  if (temp_pool_slot != MY_BIT_NONE)
4533
 
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4534
 
 
4535
 
  plugin_unlock(0, s->db_plugin);
 
4722
    temp_pool.reset(temp_pool_slot);
4536
4723
 
4537
4724
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4538
 
  thd_proc_info(thd, save_proc_info);
 
4725
  session->set_proc_info(save_proc_info);
4539
4726
 
4540
4727
  return;
4541
4728
}
4545
4732
  to this.
4546
4733
*/
4547
4734
 
4548
 
bool create_myisam_from_heap(THD *thd, Table *table,
 
4735
bool create_myisam_from_heap(Session *session, Table *table,
4549
4736
                             MI_COLUMNDEF *start_recinfo,
4550
 
                             MI_COLUMNDEF **recinfo, 
 
4737
                             MI_COLUMNDEF **recinfo,
4551
4738
                             int error, bool ignore_last_dupp_key_error)
4552
4739
{
4553
4740
  Table new_table;
4555
4742
  const char *save_proc_info;
4556
4743
  int write_err;
4557
4744
 
4558
 
  if (table->s->db_type() != heap_hton || 
 
4745
  if (table->s->db_type() != heap_engine ||
4559
4746
      error != HA_ERR_RECORD_FILE_FULL)
4560
4747
  {
4561
4748
    table->file->print_error(error,MYF(0));
4562
4749
    return(1);
4563
4750
  }
 
4751
 
 
4752
  // Release latches since this can take a long time
 
4753
  ha_release_temporary_latches(session);
 
4754
 
4564
4755
  new_table= *table;
4565
4756
  share= *table->s;
4566
4757
  new_table.s= &share;
4567
 
  new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
 
4758
  new_table.s->storage_engine= myisam_engine;
4568
4759
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4569
4760
                                        new_table.s->db_type())))
4570
4761
    return(1);                          // End of memory
4571
4762
 
4572
 
  save_proc_info=thd->get_proc_info();
4573
 
  thd_proc_info(thd, "converting HEAP to MyISAM");
 
4763
  save_proc_info=session->get_proc_info();
 
4764
  session->set_proc_info("converting HEAP to MyISAM");
4574
4765
 
4575
4766
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4576
 
                                        recinfo, thd->lex->select_lex.options | 
4577
 
                                        thd->options))
 
4767
                                        recinfo, session->lex->select_lex.options |
 
4768
                                        session->options))
4578
4769
    goto err2;
4579
4770
  if (new_table.open_tmp_table())
4580
4771
    goto err1;
4588
4779
    new_table.no_rows=1;
4589
4780
  }
4590
4781
 
4591
 
#ifdef TO_BE_DONE_LATER_IN_4_1
4592
 
  /*
4593
 
    To use start_bulk_insert() (which is new in 4.1) we need to find
4594
 
    all places where a corresponding end_bulk_insert() should be put.
4595
 
  */
4596
 
  table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
4597
 
  new_table.file->ha_start_bulk_insert(table->file->stats.records);
4598
 
#else
4599
4782
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4600
4783
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4601
 
#endif
4602
4784
 
4603
4785
  /*
4604
4786
    copy all old rows from heap table to MyISAM table
4624
4806
  (void) table->file->close();                  // This deletes the table !
4625
4807
  delete table->file;
4626
4808
  table->file=0;
4627
 
  plugin_unlock(0, table->s->db_plugin);
4628
 
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
4629
4809
  new_table.s= table->s;                       // Keep old share
4630
4810
  *table= new_table;
4631
4811
  *table->s= share;
4632
 
  
 
4812
 
4633
4813
  table->file->change_table_ptr(table, table->s);
4634
4814
  table->use_all_columns();
4635
4815
  if (save_proc_info)
4637
4817
    const char *new_proc_info=
4638
4818
      (!strcmp(save_proc_info,"Copying to tmp table") ?
4639
4819
      "Copying to tmp table on disk" : save_proc_info);
4640
 
    thd_proc_info(thd, new_proc_info);
 
4820
    session->set_proc_info(new_proc_info);
4641
4821
  }
4642
4822
  return(0);
4643
4823
 
4649
4829
  new_table.file->ha_delete_table(new_table.s->table_name.str);
4650
4830
 err2:
4651
4831
  delete new_table.file;
4652
 
  thd_proc_info(thd, save_proc_info);
 
4832
  session->set_proc_info(save_proc_info);
4653
4833
  table->mem_root= new_table.mem_root;
4654
4834
  return(1);
4655
4835
}
4656
4836
 
4657
 
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
 
4837
bitset<MAX_FIELDS> *Table::use_all_columns(bitset<MAX_FIELDS> *bitmap)
4658
4838
{
4659
 
  my_bitmap_map *old= bitmap->bitmap;
4660
 
  bitmap->bitmap= s->all_set.bitmap;
 
4839
  bitset<MAX_FIELDS> *old= bitmap;
 
4840
  bitmap= &s->all_set;
4661
4841
  return old;
4662
4842
}
4663
4843
 
4664
 
void Table::restore_column_map(my_bitmap_map *old)
 
4844
void Table::restore_column_map(bitset<MAX_FIELDS> *old)
4665
4845
{
4666
 
  read_set->bitmap= old;
 
4846
  read_set= old;
4667
4847
}
4668
4848
 
4669
4849
uint32_t Table::find_shortest_key(const key_map *usable_keys)
4719
4899
  /* Compare updated fields */
4720
4900
  for (Field **ptr= field ; *ptr ; ptr++)
4721
4901
  {
4722
 
    if (bitmap_is_set(write_set, (*ptr)->field_index) &&
 
4902
    if (write_set->test((*ptr)->field_index) &&
4723
4903
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
4724
4904
      return true;
4725
4905
  }
4749
4929
    print them to the .err log
4750
4930
  */
4751
4931
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
4752
 
    sql_print_error(_("Got error %d when reading table '%s'"),
 
4932
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
4753
4933
                    error, s->path.str);
4754
4934
  file->print_error(error,MYF(0));
4755
4935
 
4757
4937
}
4758
4938
 
4759
4939
 
 
4940
/*
 
4941
  Calculate data for each virtual field marked for write in the
 
4942
  corresponding column map.
 
4943
 
 
4944
  SYNOPSIS
 
4945
    update_virtual_fields_marked_for_write()
 
4946
    table                  The Table object
 
4947
    ignore_stored          Indication whether physically stored virtual
 
4948
                           fields do not need updating.
 
4949
                           This value is false when during INSERT and UPDATE
 
4950
                           and true in all other cases.
 
4951
 
 
4952
  RETURN
 
4953
    0  - Success
 
4954
    >0 - Error occurred during the generation/calculation of a virtual field value
 
4955
 
 
4956
*/
 
4957
 
 
4958
int update_virtual_fields_marked_for_write(Table *table,
 
4959
                                           bool ignore_stored)
 
4960
{
 
4961
  Field **vfield_ptr, *vfield;
 
4962
  int error= 0;
 
4963
  if ((not table) or (not table->vfield))
 
4964
    return(0);
 
4965
 
 
4966
  /* Iterate over virtual fields in the table */
 
4967
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
 
4968
  {
 
4969
    vfield= (*vfield_ptr);
 
4970
    assert(vfield->vcol_info && vfield->vcol_info->expr_item);
 
4971
    /*
 
4972
      Only update those fields that are marked in the write_set bitmap
 
4973
      and not _already_ physically stored in the database.
 
4974
    */
 
4975
    if (table->write_set->test(vfield->field_index) &&
 
4976
        (not (ignore_stored && vfield->is_stored))
 
4977
       )
 
4978
    {
 
4979
      /* Generate the actual value of the virtual fields */
 
4980
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
 
4981
    }
 
4982
  }
 
4983
  return(0);
 
4984
}
 
4985
 
 
4986
 
 
4987
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
 
4988
{
 
4989
  used_fields= 0;
 
4990
  const_table= 0;
 
4991
  null_row= 0;
 
4992
  status= STATUS_NO_RECORD;
 
4993
  maybe_null= table_list->outer_join;
 
4994
  TableList *embedding= table_list->embedding;
 
4995
  while (!maybe_null && embedding)
 
4996
  {
 
4997
    maybe_null= embedding->outer_join;
 
4998
    embedding= embedding->embedding;
 
4999
  }
 
5000
  tablenr= table_number;
 
5001
  map= (table_map) 1 << table_number;
 
5002
  force_index= table_list->force_index;
 
5003
  covering_keys= s->keys_for_keyread;
 
5004
  merge_keys.clear_all();
 
5005
}
 
5006
 
 
5007
 
4760
5008
/*****************************************************************************
4761
5009
** Instansiate templates
4762
5010
*****************************************************************************/