~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Monty Taylor
  • Date: 2009-03-04 02:16:28 UTC
  • mto: (917.1.2 mordred)
  • mto: This revision was merged to the branch mainline in revision 912.
  • Revision ID: mordred@inaugust.com-20090304021628-rfq0b16uoi09g8tx
Fix to make VPATH builds work again.

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
 
 
37
#include <drizzled/unireg.h>
 
38
#include <drizzled/serialize/table.pb.h>
 
39
 
 
40
#include <drizzled/item/string.h>
 
41
#include <drizzled/item/int.h>
 
42
#include <drizzled/item/decimal.h>
 
43
#include <drizzled/item/float.h>
 
44
#include <drizzled/item/null.h>
 
45
 
 
46
 
 
47
using namespace std;
 
48
 
 
49
/* Keyword for parsing virtual column functions */
 
50
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
27
51
 
28
52
/* Functions defined in this file */
29
53
 
30
54
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
31
55
                      myf errortype, int errarg);
32
 
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
33
 
                           unsigned char *head, File file);
34
56
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);
 
57
                              uint32_t types, char **names);
37
58
 
38
59
/*************************************************************************/
39
60
 
40
61
/* Get column name from column hash */
41
62
 
42
 
static unsigned char *get_field_name(Field **buff, size_t *length,
43
 
                             bool not_used __attribute__((unused)))
 
63
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
44
64
{
45
 
  *length= (uint) strlen((*buff)->field_name);
 
65
  *length= (uint32_t) strlen((*buff)->field_name);
46
66
  return (unsigned char*) (*buff)->field_name;
47
67
}
48
68
 
56
76
 
57
77
  DESCRIPTION
58
78
    Checks file name part starting with the rightmost '.' character,
59
 
    and returns it if it is equal to '.frm'. 
 
79
    and returns it if it is equal to '.frm'.
60
80
 
61
81
  TODO
62
82
    It is a good idea to get rid of this function modifying the code
81
101
  assert(db != NULL);
82
102
  assert(name != NULL);
83
103
 
84
 
  if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
 
104
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
85
105
      (my_strcasecmp(system_charset_info,
86
 
                    INFORMATION_SCHEMA_NAME.str,
 
106
                    INFORMATION_SCHEMA_NAME.c_str(),
87
107
                    db->str) == 0))
88
108
  {
89
109
    return TABLE_CATEGORY_INFORMATION;
132
152
 
133
153
    share->path.str= path_buff;
134
154
    share->path.length= path_length;
135
 
    my_stpcpy(share->path.str, path);
 
155
    strcpy(share->path.str, path);
136
156
    share->normalized_path.str=    share->path.str;
137
157
    share->normalized_path.length= path_length;
138
158
 
168
188
 
169
189
  SYNOPSIS
170
190
    init_tmp_table_share()
171
 
    thd         thread handle
 
191
    session         thread handle
172
192
    share       Share to fill
173
193
    key         Table_cache_key, as generated from create_table_def_key.
174
 
                must start with db name.    
 
194
                must start with db name.
175
195
    key_length  Length of key
176
196
    table_name  Table name
177
197
    path        Path to file (possible in lower case) without .frm
181
201
    don't have to be shared between threads or put into the table def
182
202
    cache, so we can do some things notable simpler and faster
183
203
 
184
 
    If table is not put in thd->temporary_tables (happens only when
 
204
    If table is not put in session->temporary_tables (happens only when
185
205
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
186
206
    use key_length= 0 as neither table_cache_key or key_length will be used).
187
207
*/
188
208
 
189
 
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
 
209
void init_tmp_table_share(Session *session, TABLE_SHARE *share, const char *key,
190
210
                          uint32_t key_length, const char *table_name,
191
211
                          const char *path)
192
212
{
204
224
  share->path.str=               (char*) path;
205
225
  share->normalized_path.str=    (char*) path;
206
226
  share->path.length= share->normalized_path.length= strlen(path);
207
 
  share->frm_version=            FRM_VER_TRUE_VARCHAR;
 
227
 
208
228
  /*
209
229
    Temporary tables are not replicated, but we set up these fields
210
230
    anyway to be able to catch errors.
216
236
    table_map_id is also used for MERGE tables to suppress repeated
217
237
    compatibility checks.
218
238
  */
219
 
  share->table_map_id= (ulong) thd->query_id;
 
239
  share->table_map_id= (ulong) session->query_id;
220
240
 
221
241
  return;
222
242
}
256
276
    pthread_cond_destroy(&share->cond);
257
277
  }
258
278
  hash_free(&share->name_hash);
259
 
  
 
279
 
260
280
  plugin_unlock(NULL, share->db_plugin);
261
281
  share->db_plugin= NULL;
262
282
 
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 drizzle::Table::Field::TINYINT:
 
296
    field_type= DRIZZLE_TYPE_TINY;
 
297
    break;
 
298
  case drizzle::Table::Field::INTEGER:
 
299
    field_type= DRIZZLE_TYPE_LONG;
 
300
    break;
 
301
  case drizzle::Table::Field::DOUBLE:
 
302
    field_type= DRIZZLE_TYPE_DOUBLE;
 
303
    break;
 
304
  case drizzle::Table::Field::TIMESTAMP:
 
305
    field_type= DRIZZLE_TYPE_TIMESTAMP;
 
306
    break;
 
307
  case drizzle::Table::Field::BIGINT:
 
308
    field_type= DRIZZLE_TYPE_LONGLONG;
 
309
    break;
 
310
  case drizzle::Table::Field::DATETIME:
 
311
    field_type= DRIZZLE_TYPE_DATETIME;
 
312
    break;
 
313
  case drizzle::Table::Field::DATE:
 
314
    field_type= DRIZZLE_TYPE_DATE;
 
315
    break;
 
316
  case drizzle::Table::Field::VARCHAR:
 
317
    field_type= DRIZZLE_TYPE_VARCHAR;
 
318
    break;
 
319
  case drizzle::Table::Field::DECIMAL:
 
320
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
321
    break;
 
322
  case drizzle::Table::Field::ENUM:
 
323
    field_type= DRIZZLE_TYPE_ENUM;
 
324
    break;
 
325
  case drizzle::Table::Field::BLOB:
 
326
    field_type= DRIZZLE_TYPE_BLOB;
 
327
    break;
 
328
  case drizzle::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, string default_value,
 
342
                          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(), default_value.length());
 
365
    break;
 
366
  case DRIZZLE_TYPE_NULL:
 
367
    return new Item_null();
 
368
  case DRIZZLE_TYPE_TIMESTAMP:
 
369
  case DRIZZLE_TYPE_DATETIME:
 
370
  case DRIZZLE_TYPE_DATE:
 
371
    if(default_value.compare("NOW()")==0)
 
372
      break;
 
373
  case DRIZZLE_TYPE_ENUM:
 
374
    default_item= new Item_string(default_value.c_str(),
 
375
                                  default_value.length(),
 
376
                                  system_charset_info);
 
377
    break;
 
378
  case DRIZZLE_TYPE_VARCHAR:
 
379
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
 
380
    if(charset==&my_charset_bin)
 
381
    {
 
382
      default_item= new Item_string(default_bin_value.c_str(),
 
383
                                    default_bin_value.length(),
 
384
                                    &my_charset_bin);
 
385
    }
 
386
    else
 
387
    {
 
388
      default_item= new Item_string(default_value.c_str(),
 
389
                                    default_value.length(),
 
390
                                    system_charset_info);
 
391
    }
 
392
    break;
 
393
  case DRIZZLE_TYPE_VIRTUAL:
 
394
    break;
 
395
  case DRIZZLE_TYPE_NEWDECIMAL:
 
396
    default_item= new Item_decimal(default_value.c_str(),
 
397
                                   default_value.length(),
 
398
                                   system_charset_info);
 
399
    break;
 
400
  }
 
401
 
 
402
  return default_item;
 
403
}
 
404
 
 
405
int parse_table_proto(Session *session, drizzle::Table &table, TABLE_SHARE *share)
 
406
{
 
407
  int error= 0;
 
408
 
 
409
  {
 
410
    LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
 
411
                              strlen(table.engine().name().c_str()) };
 
412
    share->db_plugin= ha_resolve_by_name(session, &engine_name);
 
413
  }
 
414
 
 
415
  share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
 
416
 
 
417
  drizzle::Table::TableOptions table_options;
 
418
 
 
419
  if(table.has_options())
 
420
    table_options= table.options();
 
421
 
 
422
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
 
423
 
 
424
  if(table_options.has_pack_keys())
 
425
  {
 
426
    if(table_options.pack_keys())
 
427
      db_create_options|= HA_OPTION_PACK_KEYS;
 
428
    else
 
429
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
 
430
  }
 
431
 
 
432
  if(table_options.pack_record())
 
433
    db_create_options|= HA_OPTION_PACK_RECORD;
 
434
 
 
435
  if(table_options.has_checksum())
 
436
  {
 
437
    if(table_options.checksum())
 
438
      db_create_options|= HA_OPTION_CHECKSUM;
 
439
    else
 
440
      db_create_options|= HA_OPTION_NO_CHECKSUM;
 
441
  }
 
442
 
 
443
  if(table_options.has_delay_key_write())
 
444
  {
 
445
    if(table_options.delay_key_write())
 
446
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
 
447
    else
 
448
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
 
449
  }
 
450
 
 
451
  /* db_create_options was stored as 2 bytes in FRM
 
452
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
 
453
   */
 
454
  share->db_create_options= (db_create_options & 0x0000FFFF);
469
455
  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
 
  }
 
456
 
 
457
 
 
458
  share->avg_row_length= table_options.has_avg_row_length() ?
 
459
    table_options.avg_row_length() : 0;
 
460
 
 
461
  share->page_checksum= table_options.has_page_checksum() ?
 
462
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
463
    : HA_CHOICE_UNDEF;
 
464
 
 
465
  share->row_type= table_options.has_row_type() ?
 
466
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
467
 
 
468
  share->block_size= table_options.has_block_size() ?
 
469
    table_options.block_size() : 0;
 
470
 
 
471
  share->table_charset= get_charset(table_options.has_collation_id()?
 
472
                                    table_options.collation_id() : 0);
 
473
 
482
474
  if (!share->table_charset)
483
475
  {
484
476
    /* unknown charset in head[38] or pre-3.23 frm */
485
477
    if (use_mb(default_charset_info))
486
478
    {
487
479
      /* 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);
 
480
      errmsg_printf(ERRMSG_LVL_WARN,
 
481
                    _("'%s' had no or invalid character set, "
 
482
                      "and default character set is multi-byte, "
 
483
                      "so character column sizes may have changed"),
 
484
                    share->path.str);
492
485
    }
493
486
    share->table_charset= default_charset_info;
494
487
  }
 
488
 
495
489
  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 */
 
490
 
 
491
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
492
 
499
493
  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;
 
494
 
 
495
  share->max_rows= table_options.has_max_rows() ?
 
496
    table_options.max_rows() : 0;
 
497
 
 
498
  share->min_rows= table_options.has_min_rows() ?
 
499
    table_options.min_rows() : 0;
 
500
 
 
501
  share->keys= table.indexes_size();
 
502
 
 
503
  share->key_parts= 0;
 
504
  for(int indx= 0; indx < table.indexes_size(); indx++)
 
505
    share->key_parts+= table.indexes(indx).index_part_size();
 
506
 
 
507
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
508
                                     table.indexes_size() * sizeof(KEY)
 
509
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
510
 
 
511
  KEY_PART_INFO *key_part;
 
512
 
 
513
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
514
    (share->key_info+table.indexes_size());
 
515
 
 
516
 
 
517
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
518
                                            sizeof(ulong*)*share->key_parts);
 
519
 
 
520
  share->keynames.count= table.indexes_size();
 
521
  share->keynames.name= NULL;
 
522
  share->keynames.type_names= (const char**)
 
523
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
524
 
 
525
  share->keynames.type_lengths= (unsigned int*)
 
526
    alloc_root(&share->mem_root,
 
527
               sizeof(unsigned int) * (table.indexes_size()+1));
 
528
 
 
529
  share->keynames.type_names[share->keynames.count]= NULL;
 
530
  share->keynames.type_lengths[share->keynames.count]= 0;
 
531
 
 
532
  KEY* keyinfo= share->key_info;
 
533
  for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
534
  {
 
535
    drizzle::Table::Index indx= table.indexes(keynr);
 
536
 
 
537
    keyinfo->table= 0;
 
538
    keyinfo->flags= 0;
 
539
 
 
540
    if(indx.is_unique())
 
541
      keyinfo->flags|= HA_NOSAME;
 
542
 
 
543
    if(indx.has_options())
 
544
    {
 
545
      drizzle::Table::Index::IndexOptions indx_options= indx.options();
 
546
      if(indx_options.pack_key())
 
547
        keyinfo->flags|= HA_PACK_KEY;
 
548
 
 
549
      if(indx_options.var_length_key())
 
550
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
551
 
 
552
      if(indx_options.null_part_key())
 
553
        keyinfo->flags|= HA_NULL_PART_KEY;
 
554
 
 
555
      if(indx_options.binary_pack_key())
 
556
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
557
 
 
558
      if(indx_options.has_partial_segments())
 
559
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
560
 
 
561
      if(indx_options.auto_generated_key())
 
562
        keyinfo->flags|= HA_GENERATED_KEY;
 
563
 
 
564
      if(indx_options.has_key_block_size())
 
565
      {
 
566
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
567
        keyinfo->block_size= indx_options.key_block_size();
 
568
      }
 
569
      else
 
570
      {
 
571
        keyinfo->block_size= 0;
 
572
      }
 
573
 
 
574
    }
 
575
 
 
576
    switch(indx.type())
 
577
    {
 
578
    case drizzle::Table::Index::UNKNOWN_INDEX:
 
579
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
580
      break;
 
581
    case drizzle::Table::Index::BTREE:
 
582
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
583
      break;
 
584
    case drizzle::Table::Index::RTREE:
 
585
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
586
      break;
 
587
    case drizzle::Table::Index::HASH:
 
588
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
589
      break;
 
590
    case drizzle::Table::Index::FULLTEXT:
 
591
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
592
 
 
593
    default:
 
594
      /* TODO: suitable warning ? */
 
595
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
596
      break;
 
597
    }
 
598
 
 
599
    keyinfo->key_length= indx.key_length();
 
600
 
 
601
    keyinfo->key_parts= indx.index_part_size();
 
602
 
 
603
    keyinfo->key_part= key_part;
549
604
    keyinfo->rec_per_key= rec_per_key;
550
 
    for (j=keyinfo->key_parts ; j-- ; key_part++)
 
605
 
 
606
    for(unsigned int partnr= 0;
 
607
        partnr < keyinfo->key_parts;
 
608
        partnr++, key_part++)
551
609
    {
 
610
      drizzle::Table::Index::IndexPart part;
 
611
      part= indx.index_part(partnr);
 
612
 
552
613
      *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);
 
614
 
 
615
      key_part->field= NULL;
 
616
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
 
617
      key_part->null_bit= 0;
 
618
      /* key_part->null_offset is only set if null_bit (see later) */
 
619
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
620
      /* key_part->type ???? */
 
621
      key_part->key_part_flag= 0;
 
622
      if(part.has_in_reverse_order())
 
623
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
624
 
 
625
      key_part->length= part.compare_length();
 
626
 
 
627
      key_part->store_length= key_part->length;
 
628
 
 
629
      /* key_part->offset is set later */
 
630
      key_part->key_type= part.key_type();
 
631
 
 
632
    }
 
633
 
 
634
    if(!indx.has_comment())
 
635
    {
 
636
      keyinfo->comment.length= 0;
 
637
      keyinfo->comment.str= NULL;
 
638
    }
 
639
    else
 
640
    {
 
641
      keyinfo->flags|= HA_USES_COMMENT;
 
642
      keyinfo->comment.length= indx.comment().length();
 
643
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
644
                                         indx.comment().c_str(),
 
645
                                         keyinfo->comment.length);
 
646
    }
 
647
 
 
648
    keyinfo->name= strmake_root(&share->mem_root,
 
649
                                indx.name().c_str(),
 
650
                                indx.name().length());
 
651
 
 
652
    share->keynames.type_names[keynr]= keyinfo->name;
 
653
    share->keynames.type_lengths[keynr]= indx.name().length();
 
654
  }
 
655
 
 
656
  share->keys_for_keyread.init(0);
 
657
  share->keys_in_use.init(share->keys);
 
658
 
 
659
  if(table_options.has_connect_string())
 
660
  {
 
661
    size_t len= table_options.connect_string().length();
 
662
    const char* str= table_options.connect_string().c_str();
 
663
 
 
664
    share->connect_string.length= len;
 
665
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
666
  }
 
667
 
 
668
  if(table_options.has_comment())
 
669
  {
 
670
    size_t len= table_options.comment().length();
 
671
    const char* str= table_options.comment().c_str();
 
672
 
 
673
    share->comment.length= len;
 
674
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
675
  }
 
676
 
 
677
  share->key_block_size= table_options.has_key_block_size() ?
 
678
    table_options.key_block_size() : 0;
 
679
 
 
680
  share->fields= table.field_size();
 
681
  share->vfields= 0;
 
682
  share->stored_fields= share->fields;
 
683
 
 
684
  share->field= (Field**) alloc_root(&share->mem_root,
 
685
                                     ((share->fields+1) * sizeof(Field*)));
 
686
  share->field[share->fields]= NULL;
 
687
 
 
688
  uint32_t null_fields= 0;
 
689
  share->reclength= 0;
 
690
 
 
691
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
 
692
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
 
693
 
 
694
  assert(field_offsets && field_pack_length); // TODO: fixme
 
695
 
 
696
  uint32_t interval_count= 0;
 
697
  uint32_t interval_parts= 0;
 
698
 
 
699
  uint32_t stored_columns_reclength= 0;
 
700
 
 
701
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
702
  {
 
703
    drizzle::Table::Field pfield= table.field(fieldnr);
 
704
    if(pfield.has_constraints() && pfield.constraints().is_nullable())
 
705
      null_fields++;
 
706
 
 
707
    bool field_is_stored= true;
 
708
 
 
709
    enum_field_types drizzle_field_type=
 
710
      proto_field_type_to_drizzle_type(pfield.type());
 
711
 
 
712
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
713
    {
 
714
      drizzle::Table::Field::VirtualFieldOptions field_options=
 
715
        pfield.virtual_options();
 
716
 
 
717
      drizzle_field_type=proto_field_type_to_drizzle_type(field_options.type());
 
718
 
 
719
      field_is_stored= field_options.physically_stored();
 
720
    }
 
721
 
 
722
    field_offsets[fieldnr]= stored_columns_reclength;
 
723
 
 
724
    /* the below switch is very similar to
 
725
       Create_field::create_length_to_internal_length in field.cc
 
726
       (which should one day be replace by just this code)
 
727
    */
 
728
    switch(drizzle_field_type)
 
729
    {
 
730
    case DRIZZLE_TYPE_BLOB:
 
731
    case DRIZZLE_TYPE_VARCHAR:
 
732
      {
 
733
        drizzle::Table::Field::StringFieldOptions field_options=
 
734
          pfield.string_options();
 
735
 
 
736
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
737
                                            field_options.collation_id() : 0);
 
738
 
 
739
        if (!cs)
 
740
          cs= default_charset_info;
 
741
 
 
742
        field_pack_length[fieldnr]=
 
743
          calc_pack_length(drizzle_field_type,
 
744
                           field_options.length() * cs->mbmaxlen);
 
745
 
 
746
      }
 
747
      break;
 
748
    case DRIZZLE_TYPE_ENUM:
 
749
      {
 
750
        drizzle::Table::Field::SetFieldOptions field_options=
 
751
          pfield.set_options();
 
752
 
 
753
        field_pack_length[fieldnr]=
 
754
          get_enum_pack_length(field_options.field_value_size());
 
755
 
 
756
        interval_count++;
 
757
        interval_parts+= field_options.field_value_size();
 
758
      }
 
759
      break;
 
760
    case DRIZZLE_TYPE_NEWDECIMAL:
 
761
      {
 
762
        drizzle::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
763
 
 
764
        field_pack_length[fieldnr]=
 
765
          my_decimal_get_binary_size(fo.precision(), fo.scale());
 
766
      }
 
767
      break;
 
768
    default:
 
769
      /* Zero is okay here as length is fixed for other types. */
 
770
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
 
771
    }
 
772
 
 
773
    share->reclength+= field_pack_length[fieldnr];
 
774
 
 
775
    if(field_is_stored)
 
776
      stored_columns_reclength+= field_pack_length[fieldnr];
 
777
  }
 
778
 
 
779
  /* data_offset added to stored_rec_length later */
 
780
  share->stored_rec_length= stored_columns_reclength;
 
781
 
 
782
  /* fix up offsets for non-stored fields (at end of record) */
 
783
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
784
  {
 
785
    drizzle::Table::Field pfield= table.field(fieldnr);
 
786
 
 
787
    bool field_is_stored= true;
 
788
 
 
789
    enum_field_types drizzle_field_type=
 
790
      proto_field_type_to_drizzle_type(pfield.type());
 
791
 
 
792
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
793
    {
 
794
      drizzle::Table::Field::VirtualFieldOptions field_options=
 
795
        pfield.virtual_options();
 
796
 
 
797
      field_is_stored= field_options.physically_stored();
 
798
    }
 
799
 
 
800
    if(!field_is_stored)
 
801
    {
 
802
      field_offsets[fieldnr]= stored_columns_reclength;
 
803
      stored_columns_reclength+= field_pack_length[fieldnr];
 
804
    }
 
805
  }
 
806
  share->null_fields= null_fields;
 
807
 
 
808
  ulong null_bits= null_fields;
 
809
  if(!table_options.pack_record())
 
810
    null_bits++;
 
811
  ulong data_offset= (null_bits + 7)/8;
 
812
 
 
813
 
 
814
  share->reclength+= data_offset;
 
815
  share->stored_rec_length+= data_offset;
 
816
 
 
817
  ulong rec_buff_length;
 
818
 
 
819
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
717
820
  share->rec_buff_length= rec_buff_length;
 
821
 
 
822
  unsigned char* record= NULL;
 
823
 
718
824
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
719
825
                                     rec_buff_length)))
720
 
    goto err;                                   /* purecov: inspected */
 
826
    abort();
 
827
 
 
828
  memset(record, 0, rec_buff_length);
 
829
 
 
830
  int null_count= 0;
 
831
 
 
832
  if(!table_options.pack_record())
 
833
  {
 
834
    null_count++; // one bit for delete mark.
 
835
    *record|= 1;
 
836
  }
 
837
 
721
838
  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)
 
839
 
 
840
  if(interval_count)
736
841
  {
737
 
    share->comment.length=  (int) (forminfo[46]);
738
 
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
739
 
                                     share->comment.length);
 
842
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
843
                                           interval_count*sizeof(TYPELIB));
740
844
  }
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
 
 
 
845
  else
 
846
    share->intervals= NULL;
 
847
 
 
848
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
849
                                  (share->fields+1)*sizeof(char*));
 
850
 
 
851
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
852
                                  (share->fields+1)*sizeof(unsigned int));
 
853
 
 
854
  share->fieldnames.type_names[share->fields]= NULL;
 
855
  share->fieldnames.type_lengths[share->fields]= 0;
 
856
  share->fieldnames.count= share->fields;
 
857
 
 
858
 
 
859
  /* Now fix the TYPELIBs for the intervals (enum values)
 
860
     and field names.
 
861
   */
 
862
 
 
863
  uint32_t interval_nr= 0;
 
864
 
 
865
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
775
866
  {
776
 
    /* Set ENUM and SET lengths */
777
 
    TYPELIB *interval;
778
 
    for (interval= share->intervals;
779
 
         interval < share->intervals + interval_count;
780
 
         interval++)
 
867
    drizzle::Table::Field pfield= table.field(fieldnr);
 
868
 
 
869
    /* field names */
 
870
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
 
871
                                                        pfield.name().c_str(),
 
872
                                                        pfield.name().length());
 
873
 
 
874
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
 
875
 
 
876
    /* enum typelibs */
 
877
    if(pfield.type() != drizzle::Table::Field::ENUM)
 
878
      continue;
 
879
 
 
880
    drizzle::Table::Field::SetFieldOptions field_options=
 
881
      pfield.set_options();
 
882
 
 
883
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
884
                                             field_options.collation_id() : 0);
 
885
 
 
886
    if (!charset)
 
887
      charset= default_charset_info;
 
888
 
 
889
    TYPELIB *t= &(share->intervals[interval_nr]);
 
890
 
 
891
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
892
                           (field_options.field_value_size()+1)*sizeof(char*));
 
893
 
 
894
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
895
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
 
896
 
 
897
    t->type_names[field_options.field_value_size()]= NULL;
 
898
    t->type_lengths[field_options.field_value_size()]= 0;
 
899
 
 
900
    t->count= field_options.field_value_size();
 
901
    t->name= NULL;
 
902
 
 
903
    for(int n=0; n < field_options.field_value_size(); n++)
781
904
    {
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;
 
905
      t->type_names[n]= strmake_root(&share->mem_root,
 
906
                                     field_options.field_value(n).c_str(),
 
907
                                     field_options.field_value(n).length());
 
908
 
 
909
      /* Go ask the charset what the length is as for "" length=1
 
910
         and there's stripping spaces or some other crack going on.
 
911
       */
 
912
      uint32_t lengthsp;
 
913
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
914
                                        field_options.field_value(n).length());
 
915
      t->type_lengths[n]= lengthsp;
792
916
    }
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)
 
917
    interval_nr++;
 
918
  }
 
919
 
 
920
 
 
921
  /* and read the fields */
 
922
  interval_nr= 0;
 
923
 
 
924
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
925
 
 
926
  if(use_hash)
818
927
    use_hash= !hash_init(&share->name_hash,
819
928
                         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++)
 
929
                         share->fields, 0, 0,
 
930
                         (hash_get_key) get_field_name, 0, 0);
 
931
 
 
932
  unsigned char* null_pos= record;;
 
933
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
 
934
 
 
935
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
824
936
  {
825
 
    uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
826
 
    enum_field_types field_type;
 
937
    drizzle::Table::Field pfield= table.field(fieldnr);
 
938
 
827
939
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
828
 
    const CHARSET_INFO *charset= NULL;
 
940
 
 
941
    switch(pfield.format())
 
942
    {
 
943
    case drizzle::Table::Field::DefaultFormat:
 
944
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
945
      break;
 
946
    case drizzle::Table::Field::FixedFormat:
 
947
      column_format= COLUMN_FORMAT_TYPE_FIXED;
 
948
      break;
 
949
    case drizzle::Table::Field::DynamicFormat:
 
950
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
 
951
      break;
 
952
    default:
 
953
      assert(1);
 
954
    }
 
955
 
 
956
    Field::utype unireg_type= Field::NONE;
 
957
 
 
958
    if(pfield.has_numeric_options()
 
959
       && pfield.numeric_options().is_autoincrement())
 
960
    {
 
961
      unireg_type= Field::NEXT_NUMBER;
 
962
    }
 
963
 
 
964
    if(pfield.has_options()
 
965
       && pfield.options().has_default_value()
 
966
       && pfield.options().default_value().compare("NOW()")==0)
 
967
    {
 
968
      if(pfield.options().has_update_value()
 
969
         && pfield.options().update_value().compare("NOW()")==0)
 
970
      {
 
971
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
972
      }
 
973
      else if (!pfield.options().has_update_value())
 
974
      {
 
975
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
976
      }
 
977
      else
 
978
        assert(1); // Invalid update value.
 
979
    }
 
980
    else if (pfield.has_options()
 
981
             && pfield.options().has_update_value()
 
982
             && pfield.options().update_value().compare("NOW()")==0)
 
983
    {
 
984
      unireg_type= Field::TIMESTAMP_UN_FIELD;
 
985
    }
 
986
 
829
987
    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
 
      }
 
988
    if(!pfield.has_comment())
 
989
    {
 
990
      comment.str= (char*)"";
 
991
      comment.length= 0;
869
992
    }
870
993
    else
871
994
    {
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
 
    {
 
995
      size_t len= pfield.comment().length();
 
996
      const char* str= pfield.comment().c_str();
 
997
 
 
998
      comment.str= strmake_root(&share->mem_root, str, len);
 
999
      comment.length= len;
 
1000
    }
 
1001
 
 
1002
    enum_field_types field_type;
 
1003
    virtual_column_info *vcol_info= NULL;
 
1004
    bool field_is_stored= true;
 
1005
 
 
1006
 
 
1007
    field_type= proto_field_type_to_drizzle_type(pfield.type());
 
1008
 
 
1009
    if(field_type==DRIZZLE_TYPE_VIRTUAL)
 
1010
    {
 
1011
      drizzle::Table::Field::VirtualFieldOptions field_options=
 
1012
        pfield.virtual_options();
 
1013
 
 
1014
      vcol_info= new virtual_column_info();
 
1015
      field_type= proto_field_type_to_drizzle_type(field_options.type());
 
1016
      field_is_stored= field_options.physically_stored();
 
1017
 
 
1018
      size_t len= field_options.expression().length();
 
1019
      const char* str= field_options.expression().c_str();
 
1020
 
 
1021
      vcol_info->expr_str.str= strmake_root(&share->mem_root, str, len);
 
1022
      vcol_info->expr_str.length= len;
 
1023
 
 
1024
      share->vfields++;
 
1025
    }
 
1026
 
 
1027
    const CHARSET_INFO *charset= &my_charset_bin;
 
1028
 
 
1029
    if(field_type==DRIZZLE_TYPE_BLOB
 
1030
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
1031
    {
 
1032
      drizzle::Table::Field::StringFieldOptions field_options=
 
1033
        pfield.string_options();
 
1034
 
 
1035
      charset= get_charset(field_options.has_collation_id()?
 
1036
                           field_options.collation_id() : 0);
 
1037
 
 
1038
      if (!charset)
 
1039
        charset= default_charset_info;
 
1040
 
 
1041
    }
 
1042
 
 
1043
    if(field_type==DRIZZLE_TYPE_ENUM)
 
1044
    {
 
1045
      drizzle::Table::Field::SetFieldOptions field_options=
 
1046
        pfield.set_options();
 
1047
 
 
1048
      charset= get_charset(field_options.has_collation_id()?
 
1049
                           field_options.collation_id() : 0);
 
1050
 
 
1051
      if (!charset)
 
1052
        charset= default_charset_info;
 
1053
 
 
1054
    }
 
1055
 
 
1056
    Item *default_value= NULL;
 
1057
 
 
1058
    if(pfield.options().has_default_value()
 
1059
       || pfield.options().has_default_null()
 
1060
       || pfield.options().has_default_bin_value())
 
1061
    {
 
1062
      default_value= default_value_item(field_type,
 
1063
                                        charset,
 
1064
                                        pfield.options().default_null(),
 
1065
                                        pfield.options().default_value(),
 
1066
                                        pfield.options().default_bin_value());
 
1067
    }
 
1068
 
 
1069
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
 
1070
 
 
1071
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
1072
    memset(&temp_table, 0, sizeof(temp_table));
 
1073
    temp_table.s= share;
 
1074
    temp_table.in_use= session;
 
1075
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
 
1076
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
1077
 
 
1078
    Field* f= make_field(share, &share->mem_root,
 
1079
                         record+field_offsets[fieldnr]+data_offset,
 
1080
                         pfield.options().length(),
 
1081
                         null_pos,
 
1082
                         null_bit_pos,
 
1083
                         pack_flag,
 
1084
                         field_type,
 
1085
                         charset,
 
1086
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
1087
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
1088
                         share->intervals+(interval_nr++)
 
1089
                         : (TYPELIB*) 0),
 
1090
                        share->fieldnames.type_names[fieldnr]);
 
1091
 
 
1092
    share->field[fieldnr]= f;
 
1093
 
 
1094
    f->init(&temp_table); /* blob default values need table obj */
 
1095
 
 
1096
    if(!(f->flags & NOT_NULL_FLAG))
 
1097
    {
 
1098
      *f->null_ptr|= f->null_bit;
934
1099
      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)
 
1100
        null_pos++;
 
1101
      null_count++;
 
1102
    }
 
1103
 
 
1104
    if(default_value)
 
1105
    {
 
1106
      int res= default_value->save_in_field(f, 1);
 
1107
      (void)res; // TODO error handle;
 
1108
    }
 
1109
    else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
 
1110
            (f->flags & NOT_NULL_FLAG))
 
1111
    {
 
1112
      f->set_notnull();
 
1113
      f->store((int64_t) 1, true);
 
1114
    }
 
1115
    else
 
1116
      f->reset();
 
1117
 
 
1118
    /* hack to undo f->init() */
 
1119
    f->table= NULL;
 
1120
    f->orig_table= NULL;
 
1121
 
 
1122
    f->field_index= fieldnr;
 
1123
    f->comment= comment;
 
1124
    f->vcol_info= vcol_info;
 
1125
    f->is_stored= field_is_stored;
 
1126
    if(!default_value
 
1127
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
1128
       && (f->flags & NOT_NULL_FLAG)
 
1129
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
 
1130
      f->flags|= NO_DEFAULT_VALUE_FLAG;
 
1131
 
 
1132
    if(f->unireg_check == Field::NEXT_NUMBER)
 
1133
      share->found_next_number_field= &(share->field[fieldnr]);
 
1134
 
 
1135
    if(share->timestamp_field == f)
 
1136
      share->timestamp_field_offset= fieldnr;
 
1137
 
 
1138
    if (use_hash) /* supposedly this never fails... but comments lie */
946
1139
      (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,
 
1140
                            (unsigned char*)&(share->field[fieldnr]));
 
1141
 
 
1142
    if(!f->is_stored)
 
1143
    {
 
1144
      share->stored_fields--;
 
1145
    }
 
1146
  }
 
1147
 
 
1148
  keyinfo= share->key_info;
 
1149
  for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
 
1150
  {
 
1151
    key_part= keyinfo->key_part;
 
1152
 
 
1153
    for(unsigned int partnr= 0;
 
1154
        partnr < keyinfo->key_parts;
 
1155
        partnr++, key_part++)
 
1156
    {
 
1157
      /* Fix up key_part->offset by adding data_offset.
 
1158
         We really should compute offset as well.
 
1159
         But at least this way we are a little better. */
 
1160
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
1161
    }
 
1162
  }
 
1163
 
 
1164
  /*
 
1165
    We need to set the unused bits to 1. If the number of bits is a multiple
 
1166
    of 8 there are no unused bits.
 
1167
  */
 
1168
 
 
1169
  if (null_count & 7)
 
1170
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
1171
 
 
1172
  share->null_bytes= (null_pos - (unsigned char*) record +
 
1173
                      (null_bit_pos + 7) / 8);
 
1174
 
 
1175
  share->last_null_bit_pos= null_bit_pos;
 
1176
 
 
1177
  free(field_offsets);
 
1178
  free(field_pack_length);
 
1179
 
 
1180
  handler *handler_file;
 
1181
 
 
1182
  if(!(handler_file= get_new_handler(share, session->mem_root,
 
1183
                                     share->db_type())))
 
1184
    abort(); // FIXME
 
1185
 
 
1186
  /* Fix key stuff */
 
1187
  if (share->key_parts)
 
1188
  {
 
1189
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
955
1190
                                       &share->keynames, 3) - 1);
 
1191
 
956
1192
    int64_t ha_option= handler_file->ha_table_flags();
 
1193
 
957
1194
    keyinfo= share->key_info;
958
1195
    key_part= keyinfo->key_part;
959
1196
 
960
1197
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
961
1198
    {
962
1199
      uint32_t usable_parts= 0;
963
 
      keyinfo->name=(char*) share->keynames.type_names[key];
964
1200
 
965
1201
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
966
1202
      {
969
1205
          declare this as a primary key.
970
1206
        */
971
1207
        primary_key=key;
972
 
        for (i=0 ; i < keyinfo->key_parts ;i++)
 
1208
        for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
973
1209
        {
974
1210
          uint32_t fieldnr= key_part[i].fieldnr;
975
1211
          if (!fieldnr ||
977
1213
              share->field[fieldnr-1]->key_length() !=
978
1214
              key_part[i].length)
979
1215
          {
980
 
            primary_key=MAX_KEY;                // Can't be used
 
1216
            primary_key=MAX_KEY;                // Can't be used
981
1217
            break;
982
1218
          }
983
1219
        }
984
1220
      }
985
1221
 
986
 
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1222
      for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
987
1223
      {
988
1224
        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
1225
        if (!key_part->fieldnr)
995
1226
        {
996
 
          error= 4;                             // Wrong file
997
 
          goto err;
 
1227
//          error= 4;                             // Wrong file
 
1228
          abort(); // goto err;
998
1229
        }
999
1230
        field= key_part->field= share->field[key_part->fieldnr-1];
1000
1231
        key_part->type= field->key_type();
1001
1232
        if (field->null_ptr)
1002
1233
        {
1003
 
          key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
 
1234
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1004
1235
                                        share->default_values);
1005
1236
          key_part->null_bit= field->null_bit;
1006
1237
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1091
1322
                                      fieldnr);
1092
1323
        }
1093
1324
      }
 
1325
 
1094
1326
    }
1095
1327
    else
1096
1328
      share->primary_key = MAX_KEY; // we do not have a primary key
1097
1329
  }
1098
1330
  else
1099
1331
    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
1332
 
1111
1333
  if (share->found_next_number_field)
1112
1334
  {
1113
 
    reg_field= *share->found_next_number_field;
1114
 
    if ((int) (share->next_number_index= (uint)
 
1335
    Field *reg_field= *share->found_next_number_field;
 
1336
    if ((int) (share->next_number_index= (uint32_t)
1115
1337
               find_ref_key(share->key_info, share->keys,
1116
1338
                            share->default_values, reg_field,
1117
1339
                            &share->next_number_key_offset,
1133
1355
    /* Store offsets to blob fields to find them fast */
1134
1356
    if (!(share->blob_field= save=
1135
1357
          (uint*) alloc_root(&share->mem_root,
1136
 
                             (uint) (share->blob_fields* sizeof(uint)))))
 
1358
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1137
1359
      goto err;
1138
1360
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1139
1361
    {
1142
1364
    }
1143
1365
  }
1144
1366
 
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
1367
  share->db_low_byte_first= handler_file->low_byte_first();
1154
1368
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1155
1369
 
 
1370
  my_bitmap_map *bitmaps;
 
1371
 
1156
1372
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1157
1373
                                             share->column_bitmap_size)))
1158
1374
    goto err;
1160
1376
  bitmap_set_all(&share->all_set);
1161
1377
 
1162
1378
  delete handler_file;
1163
 
  if (buff)
1164
 
    free(buff);
1165
1379
  return (0);
1166
1380
 
1167
 
 err:
1168
 
  if (buff)
1169
 
    free(buff);
 
1381
err:
1170
1382
  share->error= error;
1171
1383
  share->open_errno= my_errno;
1172
 
  share->errarg= errarg;
1173
 
  if (disk_buff)
1174
 
    free(disk_buff);
 
1384
  share->errarg= 0;
 
1385
  hash_free(&share->name_hash);
1175
1386
  delete handler_file;
1176
 
  hash_free(&share->name_hash);
1177
 
 
1178
 
  open_table_error(share, error, share->open_errno, errarg);
 
1387
  open_table_error(share, error, share->open_errno, 0);
 
1388
  return error;
 
1389
}
 
1390
 
 
1391
/*
 
1392
  Read table definition from a binary / text based .frm file
 
1393
 
 
1394
  SYNOPSIS
 
1395
  open_table_def()
 
1396
  session               Thread handler
 
1397
  share         Fill this with table definition
 
1398
  db_flags      Bit mask of the following flags: OPEN_VIEW
 
1399
 
 
1400
  NOTES
 
1401
    This function is called when the table definition is not cached in
 
1402
    table_def_cache
 
1403
    The data is returned in 'share', which is alloced by
 
1404
    alloc_table_share().. The code assumes that share is initialized.
 
1405
 
 
1406
  RETURN VALUES
 
1407
   0    ok
 
1408
   1    Error (see open_table_error)
 
1409
   2    Error (see open_table_error)
 
1410
   3    Wrong data in .frm file
 
1411
   4    Error (see open_table_error)
 
1412
   5    Error (see open_table_error: charset unavailable)
 
1413
   6    Unknown .frm version
 
1414
*/
 
1415
 
 
1416
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
 
1417
{
 
1418
  int error;
 
1419
  bool error_given;
 
1420
  string        path("");
 
1421
 
 
1422
  error= 1;
 
1423
  error_given= 0;
 
1424
 
 
1425
  path.reserve(FN_REFLEN);
 
1426
  path.append(share->normalized_path.str);
 
1427
  string proto_path= path;
 
1428
 
 
1429
  path.append(reg_ext);
 
1430
 
 
1431
  proto_path.append(".dfe");
 
1432
 
 
1433
  drizzle::Table table;
 
1434
 
 
1435
  if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
 
1436
  {
 
1437
    if(error>0)
 
1438
    {
 
1439
      my_errno= error;
 
1440
      error= 1;
 
1441
    }
 
1442
    else
 
1443
    {
 
1444
      if(!table.IsInitialized())
 
1445
      {
 
1446
        error= 4;
 
1447
      }
 
1448
    }
 
1449
    goto err_not_open;
 
1450
  }
 
1451
 
 
1452
  parse_table_proto(session, table, share);
 
1453
 
 
1454
  share->table_category= get_table_category(& share->db, & share->table_name);
 
1455
 
 
1456
  if (!error)
 
1457
    session->status_var.opened_shares++;
 
1458
 
 
1459
err_not_open:
 
1460
  if (error && !error_given)
 
1461
  {
 
1462
    share->error= error;
 
1463
    open_table_error(share, error, (share->open_errno= my_errno), 0);
 
1464
  }
 
1465
 
1179
1466
  return(error);
1180
 
} /* open_binary_frm */
 
1467
}
 
1468
 
 
1469
/*
 
1470
  Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
 
1471
  This routine is used for error handling purposes.
 
1472
 
 
1473
  SYNOPSIS
 
1474
    clear_field_flag()
 
1475
    table                Table object for which virtual columns are set-up
 
1476
 
 
1477
  RETURN VALUE
 
1478
    NONE
 
1479
*/
 
1480
static void clear_field_flag(Table *table)
 
1481
{
 
1482
  Field **ptr;
 
1483
 
 
1484
  for (ptr= table->field; *ptr; ptr++)
 
1485
    (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
 
1486
}
 
1487
 
 
1488
/*
 
1489
  The function uses the feature in fix_fields where the flag
 
1490
  GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
 
1491
  This field must always be reset before returning from the function
 
1492
  since it is used for other purposes as well.
 
1493
 
 
1494
  SYNOPSIS
 
1495
    fix_fields_vcol_func()
 
1496
    session                  The thread object
 
1497
    func_item            The item tree reference of the virtual columnfunction
 
1498
    table                The table object
 
1499
    field_name           The name of the processed field
 
1500
 
 
1501
  RETURN VALUE
 
1502
    true                 An error occurred, something was wrong with the
 
1503
                         function.
 
1504
    false                Ok, a partition field array was created
 
1505
*/
 
1506
 
 
1507
bool fix_fields_vcol_func(Session *session,
 
1508
                          Item* func_expr,
 
1509
                          Table *table,
 
1510
                          const char *field_name)
 
1511
{
 
1512
  uint32_t dir_length, home_dir_length;
 
1513
  bool result= true;
 
1514
  TableList tables;
 
1515
  TableList *save_table_list, *save_first_table, *save_last_table;
 
1516
  int error;
 
1517
  Name_resolution_context *context;
 
1518
  const char *save_where;
 
1519
  char* db_name;
 
1520
  char db_name_string[FN_REFLEN];
 
1521
  bool save_use_only_table_context;
 
1522
  Field **ptr, *field;
 
1523
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
 
1524
  assert(func_expr);
 
1525
 
 
1526
  /*
 
1527
    Set-up the TABLE_LIST object to be a list with a single table
 
1528
    Set the object to zero to create NULL pointers and set alias
 
1529
    and real name to table name and get database name from file name.
 
1530
  */
 
1531
 
 
1532
  bzero((void*)&tables, sizeof(TableList));
 
1533
  tables.alias= tables.table_name= (char*) table->s->table_name.str;
 
1534
  tables.table= table;
 
1535
  tables.next_local= NULL;
 
1536
  tables.next_name_resolution_table= NULL;
 
1537
  memcpy(db_name_string,
 
1538
         table->s->normalized_path.str,
 
1539
         table->s->normalized_path.length);
 
1540
  db_name_string[table->s->normalized_path.length]= '\0';
 
1541
  dir_length= dirname_length(db_name_string);
 
1542
  db_name_string[dir_length - 1]= 0;
 
1543
  home_dir_length= dirname_length(db_name_string);
 
1544
  db_name= &db_name_string[home_dir_length];
 
1545
  tables.db= db_name;
 
1546
 
 
1547
  session->mark_used_columns= MARK_COLUMNS_NONE;
 
1548
 
 
1549
  context= session->lex->current_context();
 
1550
  table->map= 1; //To ensure correct calculation of const item
 
1551
  table->get_fields_in_item_tree= true;
 
1552
  save_table_list= context->table_list;
 
1553
  save_first_table= context->first_name_resolution_table;
 
1554
  save_last_table= context->last_name_resolution_table;
 
1555
  context->table_list= &tables;
 
1556
  context->first_name_resolution_table= &tables;
 
1557
  context->last_name_resolution_table= NULL;
 
1558
  func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
 
1559
  save_where= session->where;
 
1560
  session->where= "virtual column function";
 
1561
 
 
1562
  /* Save the context before fixing the fields*/
 
1563
  save_use_only_table_context= session->lex->use_only_table_context;
 
1564
  session->lex->use_only_table_context= true;
 
1565
  /* Fix fields referenced to by the virtual column function */
 
1566
  error= func_expr->fix_fields(session, (Item**)0);
 
1567
  /* Restore the original context*/
 
1568
  session->lex->use_only_table_context= save_use_only_table_context;
 
1569
  context->table_list= save_table_list;
 
1570
  context->first_name_resolution_table= save_first_table;
 
1571
  context->last_name_resolution_table= save_last_table;
 
1572
 
 
1573
  if (unlikely(error))
 
1574
  {
 
1575
    clear_field_flag(table);
 
1576
    goto end;
 
1577
  }
 
1578
  session->where= save_where;
 
1579
  /*
 
1580
    Walk through the Item tree checking if all items are valid
 
1581
   to be part of the virtual column
 
1582
 */
 
1583
  error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
 
1584
  if (error)
 
1585
  {
 
1586
    my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
 
1587
    clear_field_flag(table);
 
1588
    goto end;
 
1589
  }
 
1590
  if (unlikely(func_expr->const_item()))
 
1591
  {
 
1592
    my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
 
1593
    clear_field_flag(table);
 
1594
    goto end;
 
1595
  }
 
1596
  /* Ensure that this virtual column is not based on another virtual field. */
 
1597
  ptr= table->field;
 
1598
  while ((field= *(ptr++)))
 
1599
  {
 
1600
    if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
 
1601
        (field->vcol_info))
 
1602
    {
 
1603
      my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
 
1604
      clear_field_flag(table);
 
1605
      goto end;
 
1606
    }
 
1607
  }
 
1608
  /*
 
1609
    Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
 
1610
    when calling fix_fields.
 
1611
  */
 
1612
  clear_field_flag(table);
 
1613
  result= false;
 
1614
 
 
1615
end:
 
1616
  table->get_fields_in_item_tree= false;
 
1617
  session->mark_used_columns= save_mark_used_columns;
 
1618
  table->map= 0; //Restore old value
 
1619
  return(result);
 
1620
}
 
1621
 
 
1622
/*
 
1623
  Unpack the definition of a virtual column
 
1624
 
 
1625
  SYNOPSIS
 
1626
    unpack_vcol_info_from_frm()
 
1627
    session                  Thread handler
 
1628
    table                Table with the checked field
 
1629
    field                Pointer to Field object
 
1630
    open_mode            Open table mode needed to determine
 
1631
                         which errors need to be generated in a failure
 
1632
    error_reported       updated flag for the caller that no other error
 
1633
                         messages are to be generated.
 
1634
 
 
1635
  RETURN VALUES
 
1636
    true            Failure
 
1637
    false           Success
 
1638
*/
 
1639
bool unpack_vcol_info_from_frm(Session *session,
 
1640
                               Table *table,
 
1641
                               Field *field,
 
1642
                               LEX_STRING *vcol_expr,
 
1643
                               open_table_mode open_mode,
 
1644
                               bool *error_reported)
 
1645
{
 
1646
  assert(vcol_expr);
 
1647
 
 
1648
  /*
 
1649
    Step 1: Construct a statement for the parser.
 
1650
    The parsed string needs to take the following format:
 
1651
    "PARSE_VCOL_EXPR (<expr_string_from_frm>)"
 
1652
  */
 
1653
  char *vcol_expr_str;
 
1654
  int str_len= 0;
 
1655
 
 
1656
  if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
 
1657
                                          vcol_expr->length +
 
1658
                                            parse_vcol_keyword.length + 3)))
 
1659
  {
 
1660
    return(true);
 
1661
  }
 
1662
  memcpy(vcol_expr_str,
 
1663
         (char*) parse_vcol_keyword.str,
 
1664
         parse_vcol_keyword.length);
 
1665
  str_len= parse_vcol_keyword.length;
 
1666
  memcpy(vcol_expr_str + str_len, "(", 1);
 
1667
  str_len++;
 
1668
  memcpy(vcol_expr_str + str_len,
 
1669
         (char*) vcol_expr->str,
 
1670
         vcol_expr->length);
 
1671
  str_len+= vcol_expr->length;
 
1672
  memcpy(vcol_expr_str + str_len, ")", 1);
 
1673
  str_len++;
 
1674
  memcpy(vcol_expr_str + str_len, "\0", 1);
 
1675
  str_len++;
 
1676
  Lex_input_stream lip(session, vcol_expr_str, str_len);
 
1677
 
 
1678
  /*
 
1679
    Step 2: Setup session for parsing.
 
1680
    1) make Item objects be created in the memory allocated for the Table
 
1681
       object (not TABLE_SHARE)
 
1682
    2) ensure that created Item's are not put on to session->free_list
 
1683
       (which is associated with the parsed statement and hence cleared after
 
1684
       the parsing)
 
1685
    3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
 
1686
       to be parsed as a SQL command.
 
1687
  */
 
1688
  MEM_ROOT **root_ptr, *old_root;
 
1689
  Item *backup_free_list= session->free_list;
 
1690
  root_ptr= current_mem_root_ptr();
 
1691
  old_root= *root_ptr;
 
1692
  *root_ptr= &table->mem_root;
 
1693
  session->free_list= NULL;
 
1694
  session->lex->parse_vcol_expr= true;
 
1695
 
 
1696
  /*
 
1697
    Step 3: Use the parser to build an Item object from.
 
1698
  */
 
1699
  if (parse_sql(session, &lip))
 
1700
  {
 
1701
    goto parse_err;
 
1702
  }
 
1703
  /* From now on use vcol_info generated by the parser. */
 
1704
  field->vcol_info= session->lex->vcol_info;
 
1705
 
 
1706
  /* Validate the Item tree. */
 
1707
  if (fix_fields_vcol_func(session,
 
1708
                           field->vcol_info->expr_item,
 
1709
                           table,
 
1710
                           field->field_name))
 
1711
  {
 
1712
    if (open_mode == OTM_CREATE)
 
1713
    {
 
1714
      /*
 
1715
        During CREATE/ALTER TABLE it is ok to receive errors here.
 
1716
        It is not ok if it happens during the opening of an frm
 
1717
        file as part of a normal query.
 
1718
      */
 
1719
      *error_reported= true;
 
1720
    }
 
1721
    field->vcol_info= NULL;
 
1722
    goto parse_err;
 
1723
  }
 
1724
  field->vcol_info->item_free_list= session->free_list;
 
1725
  session->free_list= backup_free_list;
 
1726
  *root_ptr= old_root;
 
1727
 
 
1728
  return(false);
 
1729
 
 
1730
parse_err:
 
1731
  session->lex->parse_vcol_expr= false;
 
1732
  session->free_items();
 
1733
  *root_ptr= old_root;
 
1734
  session->free_list= backup_free_list;
 
1735
  return(true);
 
1736
}
1181
1737
 
1182
1738
 
1183
1739
/*
1185
1741
 
1186
1742
  SYNOPSIS
1187
1743
    open_table_from_share()
1188
 
    thd                 Thread handler
 
1744
    session                     Thread handler
1189
1745
    share               Table definition
1190
1746
    alias               Alias for table
1191
1747
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1208
1764
   7    Table definition has changed in engine
1209
1765
*/
1210
1766
 
1211
 
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
 
1767
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1212
1768
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1213
1769
                          Table *outparam, open_table_mode open_mode)
1214
1770
{
1216
1772
  uint32_t records, i, bitmap_size;
1217
1773
  bool error_reported= false;
1218
1774
  unsigned char *record, *bitmaps;
1219
 
  Field **field_ptr;
 
1775
  Field **field_ptr, **vfield_ptr;
1220
1776
 
1221
 
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
1222
 
  assert(thd->lex->is_lex_started);
 
1777
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1778
  assert(session->lex->is_lex_started);
1223
1779
 
1224
1780
  error= 1;
1225
1781
  memset(outparam, 0, sizeof(*outparam));
1226
 
  outparam->in_use= thd;
 
1782
  outparam->in_use= session;
1227
1783
  outparam->s= share;
1228
1784
  outparam->db_stat= db_stat;
1229
1785
  outparam->write_row_record= NULL;
1230
1786
 
1231
1787
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1232
1788
 
1233
 
  if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
 
1789
  if (!(outparam->alias= strdup(alias)))
1234
1790
    goto err;
1235
1791
  outparam->quick_keys.init();
1236
1792
  outparam->covering_keys.init();
1292
1848
#endif
1293
1849
 
1294
1850
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1295
 
                                          (uint) ((share->fields+1)*
 
1851
                                          (uint32_t) ((share->fields+1)*
1296
1852
                                                  sizeof(Field*)))))
1297
1853
    goto err;                                   /* purecov: inspected */
1298
1854
 
1299
1855
  outparam->field= field_ptr;
1300
1856
 
1301
1857
  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);
 
1858
 
 
1859
  outparam->null_flags= (unsigned char*) record+1;
1307
1860
 
1308
1861
  /* Setup copy of fields from share, but use the right alias and record */
1309
1862
  for (i=0 ; i < share->fields; i++, field_ptr++)
1315
1868
 
1316
1869
  if (share->found_next_number_field)
1317
1870
    outparam->found_next_number_field=
1318
 
      outparam->field[(uint) (share->found_next_number_field - share->field)];
 
1871
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1319
1872
  if (share->timestamp_field)
1320
1873
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1321
1874
 
1331
1884
      goto err;
1332
1885
    outparam->key_info= key_info;
1333
1886
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1334
 
    
 
1887
 
1335
1888
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1336
1889
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1337
1890
                                                   share->key_parts));
1366
1919
    }
1367
1920
  }
1368
1921
 
 
1922
  /*
 
1923
    Process virtual columns, if any.
 
1924
  */
 
1925
  if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1926
                                              (uint32_t) ((share->vfields+1)*
 
1927
                                                      sizeof(Field*)))))
 
1928
    goto err;
 
1929
 
 
1930
  outparam->vfield= vfield_ptr;
 
1931
 
 
1932
  for (field_ptr= outparam->field; *field_ptr; field_ptr++)
 
1933
  {
 
1934
    if ((*field_ptr)->vcol_info)
 
1935
    {
 
1936
      if (unpack_vcol_info_from_frm(session,
 
1937
                                    outparam,
 
1938
                                    *field_ptr,
 
1939
                                    &(*field_ptr)->vcol_info->expr_str,
 
1940
                                    open_mode,
 
1941
                                    &error_reported))
 
1942
      {
 
1943
        error= 4; // in case no error is reported
 
1944
        goto err;
 
1945
      }
 
1946
      *(vfield_ptr++)= *field_ptr;
 
1947
    }
 
1948
  }
 
1949
  *vfield_ptr= NULL;                              // End marker
 
1950
  /* Check virtual columns against table's storage engine. */
 
1951
  if ((share->vfields && outparam->file) &&
 
1952
        (not outparam->file->check_if_supported_virtual_columns()))
 
1953
  {
 
1954
    my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
1955
             MYF(0),
 
1956
             "Specified storage engine");
 
1957
    error_reported= true;
 
1958
    goto err;
 
1959
  }
 
1960
 
1369
1961
  /* Allocate bitmaps */
1370
1962
 
1371
1963
  bitmap_size= share->column_bitmap_size;
1427
2019
    }
1428
2020
  }
1429
2021
 
1430
 
#if defined(HAVE_purify) 
 
2022
#if defined(HAVE_purify)
1431
2023
  memset(bitmaps, 0, bitmap_size*3);
1432
2024
#endif
1433
2025
 
1434
2026
  outparam->no_replicate= outparam->file;
1435
 
  thd->status_var.opened_tables++;
 
2027
  session->status_var.opened_tables++;
1436
2028
 
1437
2029
  return (0);
1438
2030
 
1447
2039
  return (error);
1448
2040
}
1449
2041
 
 
2042
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
 
2043
uint32_t  Table::tmpkeyval()
 
2044
{
 
2045
  return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
 
2046
}
1450
2047
 
1451
2048
/*
1452
2049
  Free information allocated by openfrm
1457
2054
    free_share          Is 1 if we also want to free table_share
1458
2055
*/
1459
2056
 
1460
 
int closefrm(register Table *table, bool free_share)
 
2057
int Table::closefrm(bool free_share)
1461
2058
{
1462
2059
  int error=0;
1463
2060
 
1464
 
  if (table->db_stat)
1465
 
    error=table->file->close();
1466
 
  free((char*) table->alias);
1467
 
  table->alias= 0;
1468
 
  if (table->field)
 
2061
  if (db_stat)
 
2062
    error= file->close();
 
2063
  free((char*) alias);
 
2064
  alias= NULL;
 
2065
  if (field)
1469
2066
  {
1470
 
    for (Field **ptr=table->field ; *ptr ; ptr++)
 
2067
    for (Field **ptr=field ; *ptr ; ptr++)
1471
2068
      delete *ptr;
1472
 
    table->field= 0;
 
2069
    field= 0;
1473
2070
  }
1474
 
  delete table->file;
1475
 
  table->file= 0;                               /* For easier errorchecking */
 
2071
  delete file;
 
2072
  file= 0;                              /* For easier errorchecking */
1476
2073
  if (free_share)
1477
2074
  {
1478
 
    if (table->s->tmp_table == NO_TMP_TABLE)
1479
 
      release_table_share(table->s, RELEASE_NORMAL);
 
2075
    if (s->tmp_table == NO_TMP_TABLE)
 
2076
      release_table_share(s, RELEASE_NORMAL);
1480
2077
    else
1481
 
      free_table_share(table->s);
 
2078
      free_table_share(s);
1482
2079
  }
1483
 
  free_root(&table->mem_root, MYF(0));
1484
 
  return(error);
 
2080
  free_root(&mem_root, MYF(0));
 
2081
 
 
2082
  return error;
1485
2083
}
1486
2084
 
1487
2085
 
1517
2115
  if (names)
1518
2116
  {
1519
2117
    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))) ||
 
2118
    lseek(file,64,SEEK_SET);
 
2119
    if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
1523
2120
        my_read(file, buf+a_length, (size_t) (length+names*4),
1524
2121
                MYF(MY_NABP)))
1525
2122
    {                                           /* purecov: inspected */
1559
2156
 
1560
2157
  if (*to)
1561
2158
    free(*to);
1562
 
  if (!(*to= (unsigned char*) my_malloc(length+1,MYF(MY_WME))) ||
 
2159
  if (!(*to= (unsigned char*) malloc(length+1)) ||
1563
2160
      my_read(file, *to, length,MYF(MY_NABP)))
1564
2161
  {
1565
2162
    if (*to)
1574
2171
 
1575
2172
        /* Add a new form to a form file */
1576
2173
 
1577
 
ulong make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
 
2174
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
1578
2175
                     const char *newname)
1579
2176
{
1580
2177
  uint32_t i,bufflength,maxlength,n_length,length,names;
1581
 
  ulong endpos,newpos;
 
2178
  off_t endpos,newpos;
1582
2179
  unsigned char buff[IO_SIZE];
1583
2180
  unsigned char *pos;
1584
2181
 
1585
 
  length=(uint) strlen(newname)+1;
 
2182
  length=(uint32_t) strlen(newname)+1;
1586
2183
  n_length=uint2korr(fileinfo+4);
1587
2184
  maxlength=uint2korr(fileinfo+6);
1588
2185
  names=uint2korr(fileinfo+8);
1592
2189
  {                                             /* Expand file */
1593
2190
    newpos+=IO_SIZE;
1594
2191
    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 */
 
2192
    endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
 
2193
    bufflength= (uint32_t) (endpos & (IO_SIZE-1));      /* IO_SIZE is a power of 2 */
1597
2194
 
1598
2195
    while (endpos > maxlength)
1599
2196
    {
1600
 
      my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0));
 
2197
      lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
1601
2198
      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));
 
2199
        return(0L);
 
2200
      lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
1605
2201
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1606
 
        return(0);
 
2202
        return(0);
1607
2203
      endpos-=bufflength; bufflength=IO_SIZE;
1608
2204
    }
1609
2205
    memset(buff, 0, IO_SIZE);                   /* Null new block */
1610
 
    my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0));
 
2206
    lseek(file,(ulong) maxlength,SEEK_SET);
1611
2207
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1612
 
        return(0L);
 
2208
      return(0L);
1613
2209
    maxlength+=IO_SIZE;                         /* Fix old ref */
1614
2210
    int2store(fileinfo+6,maxlength);
1615
 
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i-- ;
1616
 
         pos+=4)
 
2211
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
 
2212
         pos+=4)
1617
2213
    {
1618
2214
      endpos=uint4korr(pos)+IO_SIZE;
1619
2215
      int4store(pos,endpos);
1623
2219
  if (n_length == 1 )
1624
2220
  {                                             /* First name */
1625
2221
    length++;
1626
 
    strxmov((char*) buff,"/",newname,"/",NULL);
 
2222
    sprintf((char*)buff,"/%s/",newname);
1627
2223
  }
1628
2224
  else
1629
 
    strxmov((char*) buff,newname,"/",NULL); /* purecov: inspected */
1630
 
  my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0));
 
2225
    sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
 
2226
  lseek(file, 63 + n_length,SEEK_SET);
1631
2227
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1632
2228
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
1633
2229
                         names*4, MYF(MY_NABP+MY_WME))) ||
1636
2232
 
1637
2233
  int2store(fileinfo+8,names+1);
1638
2234
  int2store(fileinfo+4,n_length+length);
1639
 
  (void)ftruncate(file, newpos);/* Append file with '\0' */
 
2235
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
1640
2236
  return(newpos);
1641
2237
} /* make_new_entry */
1642
2238
 
1656
2252
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1657
2253
    else
1658
2254
    {
1659
 
      strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
2255
      sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
1660
2256
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1661
2257
               errortype, buff, db_errno);
1662
2258
    }
1665
2261
  {
1666
2262
    handler *file= 0;
1667
2263
    const char *datext= "";
1668
 
    
 
2264
 
1669
2265
    if (share->db_type() != NULL)
1670
2266
    {
1671
 
      if ((file= get_new_handler(share, current_thd->mem_root,
 
2267
      if ((file= get_new_handler(share, current_session->mem_root,
1672
2268
                                 share->db_type())))
1673
2269
      {
1674
2270
        if (!(datext= *file->bas_ext()))
1677
2273
    }
1678
2274
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1679
2275
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1680
 
    strxmov(buff, share->normalized_path.str, datext, NULL);
 
2276
    sprintf(buff,"%s%s", share->normalized_path.str,datext);
1681
2277
    my_error(err_no,errortype, buff, db_errno);
1682
2278
    delete file;
1683
2279
    break;
1684
2280
  }
1685
2281
  case 5:
1686
2282
  {
1687
 
    const char *csname= get_charset_name((uint) errarg);
 
2283
    const char *csname= get_charset_name((uint32_t) errarg);
1688
2284
    char tmp[10];
1689
2285
    if (!csname || csname[0] =='?')
1690
2286
    {
1692
2288
      csname= tmp;
1693
2289
    }
1694
2290
    my_printf_error(ER_UNKNOWN_COLLATION,
1695
 
                    _("Unknown collation '%s' in table '%-.64s' definition"), 
 
2291
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1696
2292
                    MYF(0), csname, share->table_name.str);
1697
2293
    break;
1698
2294
  }
1699
2295
  case 6:
1700
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
2296
    sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
1701
2297
    my_printf_error(ER_NOT_FORM_FILE,
1702
2298
                    _("Table '%-.64s' was created with a different version "
1703
 
                    "of MySQL and cannot be read"), 
 
2299
                    "of Drizzle and cannot be read"),
1704
2300
                    MYF(0), buff);
1705
2301
    break;
1706
2302
  case 8:
1707
2303
    break;
1708
2304
  default:                              /* Better wrong error than none */
1709
2305
  case 4:
1710
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
2306
    sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
1711
2307
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1712
2308
    break;
1713
2309
  }
1746
2342
    }
1747
2343
    else
1748
2344
      ptr++;
1749
 
    point_to_type->count= (uint) (*array - point_to_type->type_names);
 
2345
    point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
1750
2346
    point_to_type++;
1751
2347
    *((*array)++)= NULL;                /* End of type */
1752
2348
  }
1762
2358
    return 0;
1763
2359
  result->count=strings.elements;
1764
2360
  result->name="";
1765
 
  uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
 
2361
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
1766
2362
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1767
2363
    return 0;
1768
2364
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1778
2374
  return result;
1779
2375
}
1780
2376
 
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
2377
        /* Check that the integer is in the internal */
1817
2378
 
1818
2379
int set_zone(register int nr, int min_zone, int max_zone)
1838
2399
/*
1839
2400
  Store an SQL quoted string.
1840
2401
 
1841
 
  SYNOPSIS  
 
2402
  SYNOPSIS
1842
2403
    append_unescaped()
1843
2404
    res         result String
1844
2405
    pos         string to be quoted
1863
2424
    {
1864
2425
      res->append(pos, mblen);
1865
2426
      pos+= mblen;
 
2427
      if (pos >= end)
 
2428
        break;
1866
2429
      continue;
1867
2430
    }
1868
2431
#endif
1899
2462
 
1900
2463
        /* Create a .frm file */
1901
2464
 
1902
 
File create_frm(THD *thd, const char *name, const char *db,
 
2465
File create_frm(Session *session, const char *name, const char *db,
1903
2466
                const char *table, uint32_t reclength, unsigned char *fileinfo,
1904
2467
                HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
1905
2468
{
1911
2474
  uint32_t i;
1912
2475
 
1913
2476
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1914
 
    create_flags|= O_EXCL | O_NOFOLLOW;
 
2477
    create_flags|= O_EXCL;
1915
2478
 
1916
2479
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
1917
2480
  if (create_info->max_rows > UINT32_MAX)
1930
2493
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
1931
2494
 
1932
2495
    fileinfo[3]= (unsigned char) ha_legacy_type(
1933
 
          ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
 
2496
          ha_checktype(session,ha_legacy_type(create_info->db_type),0,0));
1934
2497
    fileinfo[4]=1;
1935
2498
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
1936
2499
    for (i= 0; i < keys; i++)
1937
2500
    {
1938
 
      assert(test(key_info[i].flags & HA_USES_COMMENT) == 
 
2501
      assert(test(key_info[i].flags & HA_USES_COMMENT) ==
1939
2502
                 (key_info[i].comment.length > 0));
1940
2503
      if (key_info[i].flags & HA_USES_COMMENT)
1941
2504
        key_comment_total_bytes += 2 + key_info[i].comment.length;
1975
2538
                   create_info->default_table_charset->number : 0);
1976
2539
    fileinfo[39]= (unsigned char) create_info->page_checksum;
1977
2540
    fileinfo[40]= (unsigned char) create_info->row_type;
1978
 
    /* Next few bytes where for RAID support */
 
2541
    /* Next few bytes were for RAID support */
1979
2542
    fileinfo[41]= 0;
1980
2543
    fileinfo[42]= 0;
1981
2544
    int4store(fileinfo+43,create_info->block_size);
1982
 
 
 
2545
 
1983
2546
    fileinfo[44]= 0;
1984
2547
    fileinfo[45]= 0;
1985
2548
    fileinfo[46]= 0;
1988
2551
    int4store(fileinfo+51, tmp);
1989
2552
    int4store(fileinfo+55, create_info->extra_size);
1990
2553
    /*
1991
 
      59-60 is reserved for extra_rec_buf_length,
 
2554
      59-60 is reserved for extra_rec_buf_length (always 0),
1992
2555
      61 for default_part_db_type
1993
2556
    */
1994
2557
    int2store(fileinfo+62, create_info->key_block_size);
2052
2615
  return;
2053
2616
}
2054
2617
 
2055
 
int
2056
 
rename_file_ext(const char * from,const char * to,const char * ext)
 
2618
int rename_file_ext(const char * from,const char * to,const char * ext)
2057
2619
{
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)));
 
2620
  string from_s, to_s;
 
2621
 
 
2622
  from_s.append(from);
 
2623
  from_s.append(ext);
 
2624
  to_s.append(to);
 
2625
  to_s.append(ext);
 
2626
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
2062
2627
}
2063
2628
 
2064
2629
 
2118
2683
  length= str.length();
2119
2684
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
2120
2685
    return NULL;
2121
 
  memcpy(to,str.ptr(),(uint) length);
 
2686
  memcpy(to,str.ptr(),(uint32_t) length);
2122
2687
  to[length]=0;
2123
2688
  return to;
2124
2689
}
2129
2694
    that are present in this value, returns the length of the value
2130
2695
*/
2131
2696
uint32_t calculate_key_len(Table *table, uint32_t key,
2132
 
                       const unsigned char *buf __attribute__((unused)),
 
2697
                       const unsigned char *,
2133
2698
                       key_part_map keypart_map)
2134
2699
{
2135
2700
  /* works only with key prefixes */
2206
2771
{
2207
2772
  uint32_t name_length= 0;  // name length in symbols
2208
2773
  bool last_char_is_space= true;
2209
 
  
 
2774
 
2210
2775
  while (*name)
2211
2776
  {
2212
2777
#if defined(USE_MB) && defined(USE_MB_IDENT)
2213
2778
    last_char_is_space= my_isspace(system_charset_info, *name);
2214
2779
    if (use_mb(system_charset_info))
2215
2780
    {
2216
 
      int len=my_ismbchar(system_charset_info, name, 
 
2781
      int len=my_ismbchar(system_charset_info, name,
2217
2782
                          name+system_charset_info->mbmaxlen);
2218
2783
      if (len)
2219
2784
      {
2238
2803
    name_length++;
2239
2804
  }
2240
2805
  /* Error if empty or too long column name */
2241
 
  return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
 
2806
  return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
2242
2807
}
2243
2808
 
2244
2809
 
2274
2839
    /* previous MySQL version */
2275
2840
    if (DRIZZLE_VERSION_ID > s->mysql_version)
2276
2841
    {
2277
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
 
2842
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2278
2843
                      alias, table_f_count, s->fields,
2279
2844
                      s->mysql_version, DRIZZLE_VERSION_ID);
2280
2845
      return(true);
2281
2846
    }
2282
2847
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
2283
2848
    {
2284
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
 
2849
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2285
2850
                      table_f_count, s->fields);
2286
2851
      return(true);
2287
2852
    }
2300
2865
    sql_type.length(0);
2301
2866
    if (i < s->fields)
2302
2867
    {
2303
 
      Field *field= this->field[i];
 
2868
      Field *cur_field= this->field[i];
2304
2869
 
2305
 
      if (strncmp(field->field_name, table_def->name.str,
 
2870
      if (strncmp(cur_field->field_name, table_def->name.str,
2306
2871
                  table_def->name.length))
2307
2872
      {
2308
2873
        /*
2310
2875
          Still this can be a sign of a tampered table, output an error
2311
2876
          to the error log.
2312
2877
        */
2313
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2878
        errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2314
2879
                        "expected column '%s' at position %d, found '%s'."),
2315
2880
                        s->db.str, alias, table_def->name.str, i,
2316
 
                        field->field_name);
 
2881
                        cur_field->field_name);
2317
2882
      }
2318
 
      field->sql_type(sql_type);
 
2883
      cur_field->sql_type(sql_type);
2319
2884
      /*
2320
2885
        Generally, if column types don't match, then something is
2321
2886
        wrong.
2336
2901
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2337
2902
                  table_def->type.length - 1))
2338
2903
      {
2339
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2904
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2905
                      _("Incorrect definition of table %s.%s: "
2340
2906
                        "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());
 
2907
                        "%s, found type %s."),
 
2908
                      s->db.str, alias,
 
2909
                      table_def->name.str, i, table_def->type.str,
 
2910
                      sql_type.c_ptr_safe());
2344
2911
        error= true;
2345
2912
      }
2346
 
      else if (table_def->cset.str && !field->has_charset())
 
2913
      else if (table_def->cset.str && !cur_field->has_charset())
2347
2914
      {
2348
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2915
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2916
                      _("Incorrect definition of table %s.%s: "
2349
2917
                        "expected the type of column '%s' at position %d "
2350
2918
                        "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);
 
2919
                        "character set."),
 
2920
                      s->db.str, alias,
 
2921
                      table_def->name.str, i, table_def->cset.str);
2353
2922
        error= true;
2354
2923
      }
2355
2924
      else if (table_def->cset.str &&
2356
 
               strcmp(field->charset()->csname, table_def->cset.str))
 
2925
               strcmp(cur_field->charset()->csname, table_def->cset.str))
2357
2926
      {
2358
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2927
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2928
                      _("Incorrect definition of table %s.%s: "
2359
2929
                        "expected the type of column '%s' at position %d "
2360
2930
                        "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);
 
2931
                        "character set '%s'."),
 
2932
                      s->db.str, alias,
 
2933
                      table_def->name.str, i, table_def->cset.str,
 
2934
                      cur_field->charset()->csname);
2364
2935
        error= true;
2365
2936
      }
2366
2937
    }
2367
2938
    else
2368
2939
    {
2369
 
      sql_print_error(_("Incorrect definition of table %s.%s: "
 
2940
      errmsg_printf(ERRMSG_LVL_ERROR,
 
2941
                    _("Incorrect definition of table %s.%s: "
2370
2942
                      "expected column '%s' at position %d to have type %s "
2371
2943
                      " but the column is not found."),
2372
 
                      s->db.str, alias,
2373
 
                      table_def->name.str, i, table_def->type.str);
 
2944
                    s->db.str, alias,
 
2945
                    table_def->name.str, i, table_def->type.str);
2374
2946
      error= true;
2375
2947
    }
2376
2948
  }
2388
2960
  DESCRIPTION
2389
2961
    Create Item_field object for each column in the table and
2390
2962
    initialize it with the corresponding Field. New items are
2391
 
    created in the current THD memory root.
 
2963
    created in the current Session memory root.
2392
2964
 
2393
2965
  RETURN VALUE
2394
2966
    0                    success
2474
3046
 
2475
3047
void TableList::cleanup_items()
2476
3048
{
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);
 
3049
}
 
3050
 
 
3051
 
 
3052
bool TableList::placeholder()
 
3053
{
 
3054
  return derived || schema_table || (create && !table->getDBStat()) || !table;
2484
3055
}
2485
3056
 
2486
3057
 
2666
3237
 
2667
3238
/*
2668
3239
  Tell handler we are going to call position() and rnd_pos() later.
2669
 
  
 
3240
 
2670
3241
  NOTES:
2671
3242
  This is needed for handlers that uses the primary key to find the
2672
3243
  row. In this case we have to extend the read bitmap with the primary
2742
3313
  KEY_PART_INFO *key_part_end= (key_part +
2743
3314
                                key_info[index].key_parts);
2744
3315
  for (;key_part != key_part_end; key_part++)
 
3316
  {
2745
3317
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
 
3318
    if (key_part->field->vcol_info &&
 
3319
        key_part->field->vcol_info->expr_item)
 
3320
      key_part->field->vcol_info->
 
3321
               expr_item->walk(&Item::register_field_in_bitmap,
 
3322
                               1, (unsigned char *) bitmap);
 
3323
  }
2746
3324
}
2747
3325
 
2748
3326
 
2799
3377
    }
2800
3378
    file->column_bitmaps_signal();
2801
3379
  }
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))
 
3380
 
2804
3381
  {
2805
3382
    /*
2806
3383
      If the handler has no cursor capabilites, or we have row-based
2851
3428
    }
2852
3429
    file->column_bitmaps_signal();
2853
3430
  }
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))
 
3431
 
2856
3432
  {
2857
3433
    /*
2858
3434
      If the handler has no cursor capabilites, or we have row-based
2868
3444
      file->column_bitmaps_signal();
2869
3445
    }
2870
3446
  }
 
3447
  /* Mark all virtual columns as writable */
 
3448
  mark_virtual_columns();
2871
3449
  return;
2872
3450
}
2873
3451
 
2883
3461
{
2884
3462
  if (found_next_number_field)
2885
3463
    mark_auto_increment_column();
2886
 
}
 
3464
  /* Mark all virtual columns as writable */
 
3465
  mark_virtual_columns();
 
3466
}
 
3467
 
 
3468
/*
 
3469
  @brief Update the write and read table bitmap to allow
 
3470
         using procedure save_in_field for all virtual columns
 
3471
         in the table.
 
3472
 
 
3473
  @return       void
 
3474
 
 
3475
  @detail
 
3476
    Each virtual field is set in the write column map.
 
3477
    All fields that the virtual columns are based on are set in the
 
3478
    read bitmap.
 
3479
*/
 
3480
 
 
3481
void Table::mark_virtual_columns(void)
 
3482
{
 
3483
  Field **vfield_ptr, *tmp_vfield;
 
3484
  bool bitmap_updated= false;
 
3485
 
 
3486
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
 
3487
  {
 
3488
    tmp_vfield= *vfield_ptr;
 
3489
    assert(tmp_vfield->vcol_info && tmp_vfield->vcol_info->expr_item);
 
3490
    tmp_vfield->vcol_info->expr_item->walk(&Item::register_field_in_read_map,
 
3491
                                           1, (unsigned char *) 0);
 
3492
    bitmap_set_bit(read_set, tmp_vfield->field_index);
 
3493
    bitmap_set_bit(write_set, tmp_vfield->field_index);
 
3494
    bitmap_updated= true;
 
3495
  }
 
3496
  if (bitmap_updated)
 
3497
    file->column_bitmaps_signal();
 
3498
}
 
3499
 
2887
3500
 
2888
3501
/*
2889
3502
  Cleanup this table for re-execution.
2892
3505
    TableList::reinit_before_use()
2893
3506
*/
2894
3507
 
2895
 
void TableList::reinit_before_use(THD *thd)
 
3508
void TableList::reinit_before_use(Session *session)
2896
3509
{
2897
3510
  /*
2898
3511
    Reset old pointers to TABLEs: they are not valid since the tables
2908
3521
  {
2909
3522
    embedded= parent_embedding;
2910
3523
    if (embedded->prep_on_expr)
2911
 
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
 
3524
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
2912
3525
    parent_embedding= embedded->embedding;
2913
3526
  }
2914
3527
  while (parent_embedding &&
2920
3533
 
2921
3534
  SYNOPSIS
2922
3535
    TableList::containing_subselect()
2923
 
 
 
3536
 
2924
3537
  RETURN
2925
3538
    Subselect item for the subquery that contains the FROM list
2926
3539
    this table is taken from if there is any
2929
3542
*/
2930
3543
 
2931
3544
Item_subselect *TableList::containing_subselect()
2932
 
{    
 
3545
{
2933
3546
  return (select_lex ? select_lex->master_unit()->item : 0);
2934
3547
}
2935
3548
 
2941
3554
      table         the Table to operate on.
2942
3555
 
2943
3556
  DESCRIPTION
2944
 
    The parser collects the index hints for each table in a "tagged list" 
 
3557
    The parser collects the index hints for each table in a "tagged list"
2945
3558
    (TableList::index_hints). Using the information in this tagged list
2946
 
    this function sets the members Table::keys_in_use_for_query, 
 
3559
    this function sets the members Table::keys_in_use_for_query,
2947
3560
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
2948
3561
    Table::force_index and Table::covering_keys.
2949
3562
 
2950
3563
    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 
 
3564
    and USE INDEX, so this is checked here. Then the FORCE INDEX list
2952
3565
    (if non-empty) is appended to the USE INDEX list and a flag is set.
2953
3566
 
2954
 
    Multiple hints of the same kind are processed so that each clause 
 
3567
    Multiple hints of the same kind are processed so that each clause
2955
3568
    is applied to what is computed in the previous clause.
2956
3569
    For example:
2957
3570
        USE INDEX (i1) USE INDEX (i2)
2958
3571
    is equivalent to
2959
3572
        USE INDEX (i1,i2)
2960
3573
    and means "consider only i1 and i2".
2961
 
        
 
3574
 
2962
3575
    Similarly
2963
3576
        USE INDEX () USE INDEX (i1)
2964
3577
    is equivalent to
2967
3580
 
2968
3581
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
2969
3582
    not an error.
2970
 
        
 
3583
 
2971
3584
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
2972
3585
    order:
2973
3586
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
2976
3589
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
2977
3590
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
2978
3591
 
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, 
 
3592
    As an optimization if there is a covering index, and we have
 
3593
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
2981
3594
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
2982
3595
 
2983
3596
  RETURN VALUE
2987
3600
bool TableList::process_index_hints(Table *tbl)
2988
3601
{
2989
3602
  /* initialize the result variables */
2990
 
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
 
3603
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
2991
3604
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
2992
3605
 
2993
3606
  /* index hint list processing */
2998
3611
    key_map index_group[INDEX_HINT_FORCE + 1];
2999
3612
    Index_hint *hint;
3000
3613
    int type;
3001
 
    bool have_empty_use_join= false, have_empty_use_order= false, 
 
3614
    bool have_empty_use_join= false, have_empty_use_order= false,
3002
3615
         have_empty_use_group= false;
3003
3616
    List_iterator <Index_hint> iter(*index_hints);
3004
3617
 
3036
3649
        continue;
3037
3650
      }
3038
3651
 
3039
 
      /* 
3040
 
        Check if an index with the given name exists and get his offset in 
3041
 
        the keys bitmask for the table 
 
3652
      /*
 
3653
        Check if an index with the given name exists and get his offset in
 
3654
        the keys bitmask for the table
3042
3655
      */
3043
3656
      if (tbl->s->keynames.type_names == 0 ||
3044
3657
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
3119
3732
  return length;
3120
3733
}
3121
3734
 
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
3735
/****************************************************************************
3166
3736
 Functions for creating temporary tables.
3167
3737
****************************************************************************/
3168
3738
 
3169
3739
 
3170
3740
/* Prototypes */
3171
 
void free_tmp_table(THD *thd, Table *entry);
 
3741
void free_tmp_table(Session *session, Table *entry);
3172
3742
 
3173
3743
/**
3174
3744
  Create field for temporary table from given field.
3175
3745
 
3176
 
  @param thd           Thread handler
 
3746
  @param session               Thread handler
3177
3747
  @param org_field    field from which new field will be created
3178
3748
  @param name         New field name
3179
3749
  @param table         Temporary table
3192
3762
    new_created field
3193
3763
*/
3194
3764
 
3195
 
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
 
3765
Field *create_tmp_field_from_field(Session *session, Field *org_field,
3196
3766
                                   const char *name, Table *table,
3197
3767
                                   Item_field *item, uint32_t convert_blob_length)
3198
3768
{
3199
3769
  Field *new_field;
3200
3770
 
3201
 
  /* 
3202
 
    Make sure that the blob fits into a Field_varstring which has 
3203
 
    2-byte lenght. 
 
3771
  /*
 
3772
    Make sure that the blob fits into a Field_varstring which has
 
3773
    2-byte lenght.
3204
3774
  */
3205
3775
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
3206
3776
      (org_field->flags & BLOB_FLAG))
3209
3779
                                   org_field->field_name, table->s,
3210
3780
                                   org_field->charset());
3211
3781
  else
3212
 
    new_field= org_field->new_field(thd->mem_root, table,
 
3782
    new_field= org_field->new_field(session->mem_root, table,
3213
3783
                                    table == org_field->table);
3214
3784
  if (new_field)
3215
3785
  {
3230
3800
  return new_field;
3231
3801
}
3232
3802
 
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
3803
 
3368
3804
/**
3369
3805
  Create field for information schema table.
3370
3806
 
3371
 
  @param thd            Thread handler
 
3807
  @param session                Thread handler
3372
3808
  @param table          Temporary table
3373
3809
  @param item           Item to create a field for
3374
3810
 
3378
3814
    new_created field
3379
3815
*/
3380
3816
 
3381
 
Field *create_tmp_field_for_schema(THD *thd __attribute__((unused)),
3382
 
                                   Item *item, Table *table)
 
3817
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
3383
3818
{
3384
3819
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
3385
3820
  {
3400
3835
 
3401
3836
 
3402
3837
/**
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
3838
  Create a temp table according to a field list.
3528
3839
 
3529
3840
  Given field pointers are changed to point at tmp_table for
3534
3845
  corresponding Item_field items, pointing at the fields in the
3535
3846
  temporary table, unless this was prohibited by true
3536
3847
  value of argument save_sum_fields. The Item_field objects
3537
 
  are created in THD memory root.
 
3848
  are created in Session memory root.
3538
3849
 
3539
 
  @param thd                  thread handle
 
3850
  @param session                  thread handle
3540
3851
  @param param                a description used as input to create the table
3541
3852
  @param fields               list of items that will be used to define
3542
3853
                              column types of the table (also see NOTES)
3552
3863
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
3553
3864
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
3554
3865
#define RATIO_TO_PACK_ROWS             2
3555
 
#define MIN_STRING_LENGTH_TO_PACK_ROWS   10
3556
3866
 
3557
3867
Table *
3558
 
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
 
3868
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
3559
3869
                 order_st *group, bool distinct, bool save_sum_fields,
3560
3870
                 uint64_t select_options, ha_rows rows_limit,
3561
3871
                 char *table_alias)
3586
3896
  uint32_t total_uneven_bit_length= 0;
3587
3897
  bool force_copy_fields= param->force_copy_fields;
3588
3898
 
3589
 
  status_var_increment(thd->status_var.created_tmp_tables);
 
3899
  status_var_increment(session->status_var.created_tmp_tables);
3590
3900
 
3591
3901
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
3592
3902
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
3593
3903
 
3594
3904
  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);
 
3905
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
 
3906
            (unsigned long)current_pid, temp_pool_slot);
3597
3907
  else
3598
3908
  {
3599
3909
    /* 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++);
 
3910
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
3911
            session->thread_id, session->tmp_table++);
3602
3912
  }
3603
3913
 
3604
3914
  /*
3605
3915
    No need to change table name to lower case as we are only creating
3606
3916
    MyISAM or HEAP tables here
3607
3917
  */
3608
 
  fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3918
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
3609
3919
 
3610
3920
 
3611
3921
  if (group)
3637
3947
    When loose index scan is employed as access method, it already
3638
3948
    computes all groups and the result of all aggregate functions. We
3639
3949
    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
 
3950
    functions Tmp_Table_Param::items_to_copy, so that the values of
3641
3951
    these items are stored in the temporary table.
3642
3952
  */
3643
3953
  if (param->precomputed_group_by)
3644
3954
    copy_func_count+= param->sum_func_count;
3645
 
  
 
3955
 
3646
3956
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
3647
3957
 
3648
3958
  if (!multi_alloc_root(&own_root,
3650
3960
                        &share, sizeof(*share),
3651
3961
                        &reg_field, sizeof(Field*) * (field_count+1),
3652
3962
                        &default_field, sizeof(Field*) * (field_count),
3653
 
                        &blob_field, sizeof(uint)*(field_count+1),
 
3963
                        &blob_field, sizeof(uint32_t)*(field_count+1),
3654
3964
                        &from_field, sizeof(Field*)*field_count,
3655
3965
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
3656
3966
                        &param->keyinfo, sizeof(*param->keyinfo),
3658
3968
                        sizeof(*key_part_info)*(param->group_parts+1),
3659
3969
                        &param->start_recinfo,
3660
3970
                        sizeof(*param->recinfo)*(field_count*2+4),
3661
 
                        &tmpname, (uint) strlen(path)+1,
 
3971
                        &tmpname, (uint32_t) strlen(path)+1,
3662
3972
                        &group_buff, (group && ! using_unique_constraint ?
3663
3973
                                      param->group_length : 0),
3664
3974
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3668
3978
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3669
3979
    return(NULL);                               /* purecov: inspected */
3670
3980
  }
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]))
 
3981
  /* Copy_field belongs to Tmp_Table_Param, allocate it in Session mem_root */
 
3982
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
3673
3983
  {
3674
3984
    if (temp_pool_slot != MY_BIT_NONE)
3675
3985
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3677
3987
    return(NULL);                               /* purecov: inspected */
3678
3988
  }
3679
3989
  param->items_to_copy= copy_func;
3680
 
  my_stpcpy(tmpname,path);
 
3990
  strcpy(tmpname,path);
3681
3991
  /* make table according to fields */
3682
3992
 
3683
3993
  memset(table, 0, sizeof(*table));
3686
3996
  memset(from_field, 0, sizeof(Field*)*field_count);
3687
3997
 
3688
3998
  table->mem_root= own_root;
3689
 
  mem_root_save= thd->mem_root;
3690
 
  thd->mem_root= &table->mem_root;
 
3999
  mem_root_save= session->mem_root;
 
4000
  session->mem_root= &table->mem_root;
3691
4001
 
3692
4002
  table->field=reg_field;
3693
4003
  table->alias= table_alias;
3696
4006
  table->map=1;
3697
4007
  table->temp_pool_slot = temp_pool_slot;
3698
4008
  table->copy_blobs= 1;
3699
 
  table->in_use= thd;
 
4009
  table->in_use= session;
3700
4010
  table->quick_keys.init();
3701
4011
  table->covering_keys.init();
3702
4012
  table->keys_in_use_for_query.init();
3703
4013
 
3704
4014
  table->setShare(share);
3705
 
  init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
 
4015
  init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
3706
4016
  share->blob_field= blob_field;
3707
4017
  share->blob_ptr_size= portable_sizeof_char_ptr;
3708
4018
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
3754
4064
        if (!arg->const_item())
3755
4065
        {
3756
4066
          Field *new_field=
3757
 
            create_tmp_field(thd, table, arg, arg->type(), &copy_func,
 
4067
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
3758
4068
                             tmp_from_field, &default_field[fieldnr],
3759
4069
                             group != 0,not_all_columns,
3760
4070
                             distinct, 0,
3774
4084
            string_count++;
3775
4085
            string_total_length+= new_field->pack_length();
3776
4086
          }
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;
 
4087
          session->mem_root= mem_root_save;
 
4088
          session->change_item_tree(argp, new Item_field(new_field));
 
4089
          session->mem_root= &table->mem_root;
3780
4090
          if (!(new_field->flags & NOT_NULL_FLAG))
3781
4091
          {
3782
4092
            null_count++;
3803
4113
        that in the later case group is set to the row pointer.
3804
4114
      */
3805
4115
      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,
 
4116
        create_tmp_field_for_schema(session, item, table) :
 
4117
        create_tmp_field(session, table, item, type, &copy_func,
3808
4118
                         tmp_from_field, &default_field[fieldnr],
3809
4119
                         group != 0,
3810
4120
                         !force_copy_fields &&
3822
4132
 
3823
4133
      if (!new_field)
3824
4134
      {
3825
 
        if (thd->is_fatal_error)
 
4135
        if (session->is_fatal_error)
3826
4136
          goto err;                             // Got OOM
3827
4137
        continue;                               // Some kindf of const item
3828
4138
      }
3860
4170
      null_count= 0;
3861
4171
    }
3862
4172
  }
3863
 
  assert(fieldnr == (uint) (reg_field - table->field));
3864
 
  assert(field_count >= (uint) (reg_field - table->field));
 
4173
  assert(fieldnr == (uint32_t) (reg_field - table->field));
 
4174
  assert(field_count >= (uint32_t) (reg_field - table->field));
3865
4175
  field_count= fieldnr;
3866
4176
  *reg_field= 0;
3867
4177
  *blob_field= 0;                               // End marker
3924
4234
    share->default_values= table->record[1]+alloc_length;
3925
4235
  }
3926
4236
  copy_func[0]=0;                               // End marker
3927
 
  param->func_count= copy_func - param->items_to_copy; 
 
4237
  param->func_count= copy_func - param->items_to_copy;
3928
4238
 
3929
4239
  table->setup_tmp_table_column_bitmaps(bitmaps);
3930
4240
 
3984
4294
    */
3985
4295
    if (default_field[i] && default_field[i]->ptr)
3986
4296
    {
3987
 
      /* 
 
4297
      /*
3988
4298
         default_field[i] is set only in the cases  when 'field' can
3989
4299
         inherit the default value that is defined for the field referred
3990
4300
         by the Item_field object from which 'field' has been created.
4003
4313
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
4004
4314
      }
4005
4315
      orig_field->move_field_offset(-diff);     // Back to record[0]
4006
 
    } 
 
4316
    }
4007
4317
 
4008
4318
    if (from_field[i])
4009
4319
    {                                           /* Not a table Item */
4030
4340
  param->recinfo=recinfo;
4031
4341
  store_record(table,s->default_values);        // Make empty default record
4032
4342
 
4033
 
  if (thd->variables.tmp_table_size == ~ (uint64_t) 0)          // No limit
 
4343
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
4034
4344
    share->max_rows= ~(ha_rows) 0;
4035
4345
  else
4036
4346
    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) /
 
4347
                                 cmin(session->variables.tmp_table_size,
 
4348
                                     session->variables.max_heap_table_size) :
 
4349
                                 session->variables.tmp_table_size) /
4040
4350
                                 share->reclength);
4041
4351
  set_if_bigger(share->max_rows,1);             // For dummy start options
4042
4352
  /*
4080
4390
      if (!using_unique_constraint)
4081
4391
      {
4082
4392
        cur_group->buff=(char*) group_buff;
4083
 
        if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
 
4393
        if (!(cur_group->field= field->new_key_field(session->mem_root,table,
4084
4394
                                                     group_buff +
4085
4395
                                                     test(maybe_null),
4086
4396
                                                     field->null_ptr,
4096
4406
          */
4097
4407
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
4098
4408
          key_part_info->null_bit=field->null_bit;
4099
 
          key_part_info->null_offset= (uint) (field->null_ptr -
 
4409
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
4100
4410
                                              (unsigned char*) table->record[0]);
4101
4411
          cur_group->buff++;                        // Pointer to field data
4102
4412
          group_buff++;                         // Skipp null flag
4158
4468
                                                (uint32_t) key_part_info->length,
4159
4469
                                                0,
4160
4470
                                                (unsigned char*) 0,
4161
 
                                                (uint) 0,
 
4471
                                                (uint32_t) 0,
4162
4472
                                                Field::NONE,
4163
 
                                                NULL, 
 
4473
                                                NULL,
4164
4474
                                                table->s,
4165
4475
                                                &my_charset_bin);
4166
4476
      if (!key_part_info->field)
4191
4501
 
4192
4502
      if ((*reg_field)->real_maybe_null())
4193
4503
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
4194
 
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB || 
 
4504
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB ||
4195
4505
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
4196
4506
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
4197
4507
 
4204
4514
    }
4205
4515
  }
4206
4516
 
4207
 
  if (thd->is_fatal_error)                              // If end of memory
 
4517
  if (session->is_fatal_error)                          // If end of memory
4208
4518
    goto err;                                    /* purecov: inspected */
4209
4519
  share->db_record_offset= 1;
4210
4520
  if (share->db_type() == myisam_hton)
4216
4526
  if (table->open_tmp_table())
4217
4527
    goto err;
4218
4528
 
4219
 
  thd->mem_root= mem_root_save;
 
4529
  session->mem_root= mem_root_save;
4220
4530
 
4221
4531
  return(table);
4222
4532
 
4223
4533
err:
4224
 
  thd->mem_root= mem_root_save;
4225
 
  table->free_tmp_table(thd);                    /* purecov: inspected */
 
4534
  session->mem_root= mem_root_save;
 
4535
  table->free_tmp_table(session);                    /* purecov: inspected */
4226
4536
  if (temp_pool_slot != MY_BIT_NONE)
4227
4537
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4228
4538
  return(NULL);                         /* purecov: inspected */
4239
4549
    The sole purpose of this Table object is to use the power of Field
4240
4550
    class to read/write data to/from table->record[0]. Then one can store
4241
4551
    the record in any container (RB tree, hash, etc).
4242
 
    The table is created in THD mem_root, so are the table's fields.
 
4552
    The table is created in Session mem_root, so are the table's fields.
4243
4553
    Consequently, if you don't BLOB fields, you don't need to free it.
4244
4554
 
4245
 
  @param thd         connection handle
 
4555
  @param session         connection handle
4246
4556
  @param field_list  list of column definitions
4247
4557
 
4248
4558
  @return
4249
4559
    0 if out of memory, Table object in case of success
4250
4560
*/
4251
4561
 
4252
 
Table *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
 
4562
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4253
4563
{
4254
4564
  uint32_t field_count= field_list.elements;
4255
4565
  uint32_t blob_count= 0;
4263
4573
  Table *table;
4264
4574
  TABLE_SHARE *share;
4265
4575
 
4266
 
  if (!multi_alloc_root(thd->mem_root,
 
4576
  if (!multi_alloc_root(session->mem_root,
4267
4577
                        &table, sizeof(*table),
4268
4578
                        &share, sizeof(*share),
4269
4579
                        &field, (field_count + 1) * sizeof(Field*),
4270
 
                        &blob_field, (field_count+1) *sizeof(uint),
 
4580
                        &blob_field, (field_count+1) *sizeof(uint32_t),
4271
4581
                        &bitmaps, bitmap_buffer_size(field_count)*2,
4272
4582
                        NULL))
4273
4583
    return 0;
4285
4595
  List_iterator_fast<Create_field> it(field_list);
4286
4596
  while ((cdef= it++))
4287
4597
  {
4288
 
    *field= make_field(share, 0, cdef->length,
 
4598
    *field= make_field(share, NULL, 0, cdef->length,
4289
4599
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4290
4600
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
4291
4601
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
4299
4609
      null_count++;
4300
4610
 
4301
4611
    if ((*field)->flags & BLOB_FLAG)
4302
 
      share->blob_field[blob_count++]= (uint) (field - table->field);
 
4612
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
4303
4613
 
4304
4614
    field++;
4305
4615
  }
4310
4620
  null_pack_length= (null_count + 7)/8;
4311
4621
  share->reclength= record_length + null_pack_length;
4312
4622
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4313
 
  table->record[0]= (unsigned char*) thd->alloc(share->rec_buff_length);
 
4623
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4314
4624
  if (!table->record[0])
4315
4625
    goto error;
4316
4626
 
4321
4631
    share->null_bytes= null_pack_length;
4322
4632
  }
4323
4633
 
4324
 
  table->in_use= thd;           /* field->reset() may access table->in_use */
 
4634
  table->in_use= session;           /* field->reset() may access table->in_use */
4325
4635
  {
4326
4636
    /* Set up field pointers */
4327
4637
    unsigned char *null_pos= table->record[0];
4380
4690
      start_recinfo   MyISAM's column descriptions
4381
4691
      recinfo INOUT   End of MyISAM's column descriptions
4382
4692
      options         Option bits
4383
 
   
 
4693
 
4384
4694
  DESCRIPTION
4385
4695
    Create a MyISAM temporary table according to passed description. The is
4386
4696
    assumed to have one unique index or constraint.
4391
4701
         when there are many nullable columns)
4392
4702
      2. Table columns
4393
4703
      3. One free MI_COLUMNDEF element (*recinfo points here)
4394
 
   
 
4704
 
4395
4705
    This function may use the free element to create hash column for unique
4396
4706
    constraint.
4397
4707
 
4400
4710
     true  - Error
4401
4711
*/
4402
4712
 
4403
 
bool Table::create_myisam_tmp_table(KEY *keyinfo, 
 
4713
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4404
4714
                                    MI_COLUMNDEF *start_recinfo,
4405
 
                                    MI_COLUMNDEF **recinfo, 
 
4715
                                    MI_COLUMNDEF **recinfo,
4406
4716
                                    uint64_t options)
4407
4717
{
4408
4718
  int error;
4449
4759
    }
4450
4760
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4451
4761
    {
4452
 
      Field *field=keyinfo->key_part[i].field;
 
4762
      Field *key_field=keyinfo->key_part[i].field;
4453
4763
      seg->flag=     0;
4454
 
      seg->language= field->charset()->number;
 
4764
      seg->language= key_field->charset()->number;
4455
4765
      seg->length=   keyinfo->key_part[i].length;
4456
4766
      seg->start=    keyinfo->key_part[i].offset;
4457
 
      if (field->flags & BLOB_FLAG)
 
4767
      if (key_field->flags & BLOB_FLAG)
4458
4768
      {
4459
4769
        seg->type=
4460
4770
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4461
4771
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4462
 
        seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
 
4772
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
4773
                                  - share->blob_ptr_size);
4463
4774
        seg->flag= HA_BLOB_PART;
4464
4775
        seg->length=0;                  // Whole blob in unique constraint
4465
4776
      }
4467
4778
      {
4468
4779
        seg->type= keyinfo->key_part[i].type;
4469
4780
      }
4470
 
      if (!(field->flags & NOT_NULL_FLAG))
 
4781
      if (!(key_field->flags & NOT_NULL_FLAG))
4471
4782
      {
4472
 
        seg->null_bit= field->null_bit;
4473
 
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) record[0]);
 
4783
        seg->null_bit= key_field->null_bit;
 
4784
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
4474
4785
        /*
4475
4786
          We are using a GROUP BY on something that contains NULL
4476
4787
          In this case we have to tell MyISAM that two NULL should
4489
4800
    create_info.data_file_length= ~(uint64_t) 0;
4490
4801
 
4491
4802
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4492
 
                       (uint) (*recinfo-start_recinfo),
 
4803
                       (uint32_t) (*recinfo-start_recinfo),
4493
4804
                       start_recinfo,
4494
4805
                       share->uniques, &uniquedef,
4495
4806
                       &create_info,
4507
4818
}
4508
4819
 
4509
4820
 
4510
 
void Table::free_tmp_table(THD *thd)
 
4821
void Table::free_tmp_table(Session *session)
4511
4822
{
4512
4823
  MEM_ROOT own_root= mem_root;
4513
4824
  const char *save_proc_info;
4514
4825
 
4515
 
  save_proc_info=thd->get_proc_info();
4516
 
  thd_proc_info(thd, "removing tmp table");
 
4826
  save_proc_info=session->get_proc_info();
 
4827
  session->set_proc_info("removing tmp table");
 
4828
 
 
4829
  // Release latches since this can take a long time
 
4830
  ha_release_temporary_latches(session);
4517
4831
 
4518
4832
  if (file)
4519
4833
  {
4535
4849
  plugin_unlock(0, s->db_plugin);
4536
4850
 
4537
4851
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4538
 
  thd_proc_info(thd, save_proc_info);
 
4852
  session->set_proc_info(save_proc_info);
4539
4853
 
4540
4854
  return;
4541
4855
}
4545
4859
  to this.
4546
4860
*/
4547
4861
 
4548
 
bool create_myisam_from_heap(THD *thd, Table *table,
 
4862
bool create_myisam_from_heap(Session *session, Table *table,
4549
4863
                             MI_COLUMNDEF *start_recinfo,
4550
 
                             MI_COLUMNDEF **recinfo, 
 
4864
                             MI_COLUMNDEF **recinfo,
4551
4865
                             int error, bool ignore_last_dupp_key_error)
4552
4866
{
4553
4867
  Table new_table;
4555
4869
  const char *save_proc_info;
4556
4870
  int write_err;
4557
4871
 
4558
 
  if (table->s->db_type() != heap_hton || 
 
4872
  if (table->s->db_type() != heap_hton ||
4559
4873
      error != HA_ERR_RECORD_FILE_FULL)
4560
4874
  {
4561
4875
    table->file->print_error(error,MYF(0));
4562
4876
    return(1);
4563
4877
  }
 
4878
 
 
4879
  // Release latches since this can take a long time
 
4880
  ha_release_temporary_latches(session);
 
4881
 
4564
4882
  new_table= *table;
4565
4883
  share= *table->s;
4566
4884
  new_table.s= &share;
4567
 
  new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
 
4885
  new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
4568
4886
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4569
4887
                                        new_table.s->db_type())))
4570
4888
    return(1);                          // End of memory
4571
4889
 
4572
 
  save_proc_info=thd->get_proc_info();
4573
 
  thd_proc_info(thd, "converting HEAP to MyISAM");
 
4890
  save_proc_info=session->get_proc_info();
 
4891
  session->set_proc_info("converting HEAP to MyISAM");
4574
4892
 
4575
4893
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4576
 
                                        recinfo, thd->lex->select_lex.options | 
4577
 
                                        thd->options))
 
4894
                                        recinfo, session->lex->select_lex.options |
 
4895
                                        session->options))
4578
4896
    goto err2;
4579
4897
  if (new_table.open_tmp_table())
4580
4898
    goto err1;
4588
4906
    new_table.no_rows=1;
4589
4907
  }
4590
4908
 
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
4909
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4600
4910
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4601
 
#endif
4602
4911
 
4603
4912
  /*
4604
4913
    copy all old rows from heap table to MyISAM table
4629
4938
  new_table.s= table->s;                       // Keep old share
4630
4939
  *table= new_table;
4631
4940
  *table->s= share;
4632
 
  
 
4941
 
4633
4942
  table->file->change_table_ptr(table, table->s);
4634
4943
  table->use_all_columns();
4635
4944
  if (save_proc_info)
4637
4946
    const char *new_proc_info=
4638
4947
      (!strcmp(save_proc_info,"Copying to tmp table") ?
4639
4948
      "Copying to tmp table on disk" : save_proc_info);
4640
 
    thd_proc_info(thd, new_proc_info);
 
4949
    session->set_proc_info(new_proc_info);
4641
4950
  }
4642
4951
  return(0);
4643
4952
 
4649
4958
  new_table.file->ha_delete_table(new_table.s->table_name.str);
4650
4959
 err2:
4651
4960
  delete new_table.file;
4652
 
  thd_proc_info(thd, save_proc_info);
 
4961
  session->set_proc_info(save_proc_info);
4653
4962
  table->mem_root= new_table.mem_root;
4654
4963
  return(1);
4655
4964
}
4749
5058
    print them to the .err log
4750
5059
  */
4751
5060
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
4752
 
    sql_print_error(_("Got error %d when reading table '%s'"),
 
5061
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
4753
5062
                    error, s->path.str);
4754
5063
  file->print_error(error,MYF(0));
4755
5064
 
4757
5066
}
4758
5067
 
4759
5068
 
 
5069
/*
 
5070
  Calculate data for each virtual field marked for write in the
 
5071
  corresponding column map.
 
5072
 
 
5073
  SYNOPSIS
 
5074
    update_virtual_fields_marked_for_write()
 
5075
    table                  The Table object
 
5076
    ignore_stored          Indication whether physically stored virtual
 
5077
                           fields do not need updating.
 
5078
                           This value is false when during INSERT and UPDATE
 
5079
                           and true in all other cases.
 
5080
 
 
5081
  RETURN
 
5082
    0  - Success
 
5083
    >0 - Error occurred during the generation/calculation of a virtual field value
 
5084
 
 
5085
*/
 
5086
 
 
5087
int update_virtual_fields_marked_for_write(Table *table,
 
5088
                                           bool ignore_stored)
 
5089
{
 
5090
  Field **vfield_ptr, *vfield;
 
5091
  int error= 0;
 
5092
  if ((not table) or (not table->vfield))
 
5093
    return(0);
 
5094
 
 
5095
  /* Iterate over virtual fields in the table */
 
5096
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
 
5097
  {
 
5098
    vfield= (*vfield_ptr);
 
5099
    assert(vfield->vcol_info && vfield->vcol_info->expr_item);
 
5100
    /*
 
5101
      Only update those fields that are marked in the write_set bitmap
 
5102
      and not _already_ physically stored in the database.
 
5103
    */
 
5104
    if (bitmap_is_set(table->write_set, vfield->field_index) &&
 
5105
        (not (ignore_stored && vfield->is_stored))
 
5106
       )
 
5107
    {
 
5108
      /* Generate the actual value of the virtual fields */
 
5109
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
 
5110
    }
 
5111
  }
 
5112
  return(0);
 
5113
}
 
5114
 
 
5115
 
 
5116
void setup_table_map(Table *table, TableList *table_list, uint32_t tablenr)
 
5117
{
 
5118
  table->used_fields= 0;
 
5119
  table->const_table= 0;
 
5120
  table->null_row= 0;
 
5121
  table->status= STATUS_NO_RECORD;
 
5122
  table->maybe_null= table_list->outer_join;
 
5123
  TableList *embedding= table_list->embedding;
 
5124
  while (!table->maybe_null && embedding)
 
5125
  {
 
5126
    table->maybe_null= embedding->outer_join;
 
5127
    embedding= embedding->embedding;
 
5128
  }
 
5129
  table->tablenr= tablenr;
 
5130
  table->map= (table_map) 1 << tablenr;
 
5131
  table->force_index= table_list->force_index;
 
5132
  table->covering_keys= table->s->keys_for_keyread;
 
5133
  table->merge_keys.clear_all();
 
5134
}
 
5135
 
 
5136
 
4760
5137
/*****************************************************************************
4761
5138
** Instansiate templates
4762
5139
*****************************************************************************/