~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-03-27 22:55:28 UTC
  • mto: This revision was merged to the branch mainline in revision 968.
  • Revision ID: brian@tangent.org-20090327225528-8y76cfx8a4oemqv9
Remove ref_count

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
71
91
char *fn_rext(char *name)
72
92
{
73
93
  char *res= strrchr(name, '.');
74
 
  if (res && !strcmp(res, reg_ext))
 
94
  if (res && !strcmp(res, ".dfe"))
75
95
    return res;
76
96
  return name + strlen(name);
77
97
}
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
 
  
260
 
  plugin_unlock(NULL, share->db_plugin);
 
279
 
261
280
  share->db_plugin= NULL;
262
281
 
263
282
  /* We must copy mem_root from share because share is allocated through it */
266
285
  return;
267
286
}
268
287
 
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)))
 
288
enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
295
289
{
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
 
290
  enum_field_types field_type;
 
291
 
 
292
  switch(proto_field_type)
 
293
  {
 
294
  case drizzle::Table::Field::TINYINT:
 
295
    field_type= DRIZZLE_TYPE_TINY;
 
296
    break;
 
297
  case drizzle::Table::Field::INTEGER:
 
298
    field_type= DRIZZLE_TYPE_LONG;
 
299
    break;
 
300
  case drizzle::Table::Field::DOUBLE:
 
301
    field_type= DRIZZLE_TYPE_DOUBLE;
 
302
    break;
 
303
  case drizzle::Table::Field::TIMESTAMP:
 
304
    field_type= DRIZZLE_TYPE_TIMESTAMP;
 
305
    break;
 
306
  case drizzle::Table::Field::BIGINT:
 
307
    field_type= DRIZZLE_TYPE_LONGLONG;
 
308
    break;
 
309
  case drizzle::Table::Field::DATETIME:
 
310
    field_type= DRIZZLE_TYPE_DATETIME;
 
311
    break;
 
312
  case drizzle::Table::Field::DATE:
 
313
    field_type= DRIZZLE_TYPE_DATE;
 
314
    break;
 
315
  case drizzle::Table::Field::VARCHAR:
 
316
    field_type= DRIZZLE_TYPE_VARCHAR;
 
317
    break;
 
318
  case drizzle::Table::Field::DECIMAL:
 
319
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
320
    break;
 
321
  case drizzle::Table::Field::ENUM:
 
322
    field_type= DRIZZLE_TYPE_ENUM;
 
323
    break;
 
324
  case drizzle::Table::Field::BLOB:
 
325
    field_type= DRIZZLE_TYPE_BLOB;
 
326
    break;
 
327
  case drizzle::Table::Field::VIRTUAL:
 
328
    field_type= DRIZZLE_TYPE_VIRTUAL;
 
329
    break;
 
330
  default:
 
331
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
385
332
    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);
 
333
  }
 
334
 
 
335
  return field_type;
 
336
}
 
337
 
 
338
Item * default_value_item(enum_field_types field_type,
 
339
                          const CHARSET_INFO *charset,
 
340
                          bool default_null, const string *default_value,
 
341
                          const string *default_bin_value)
 
342
{
 
343
  Item *default_item= NULL;
 
344
  int error= 0;
 
345
 
 
346
  if(default_null)
 
347
  {
 
348
    return new Item_null();
 
349
  }
 
350
 
 
351
  switch(field_type)
 
352
  {
 
353
  case DRIZZLE_TYPE_TINY:
 
354
  case DRIZZLE_TYPE_LONG:
 
355
  case DRIZZLE_TYPE_LONGLONG:
 
356
    default_item= new Item_int(default_value->c_str(),
 
357
                               (int64_t) my_strtoll10(default_value->c_str(),
 
358
                                                      NULL,
 
359
                                                      &error),
 
360
                               default_value->length());
 
361
    break;
 
362
  case DRIZZLE_TYPE_DOUBLE:
 
363
    default_item= new Item_float(default_value->c_str(),
 
364
                                 default_value->length());
 
365
    break;
 
366
  case DRIZZLE_TYPE_NULL:
 
367
    assert(false);
 
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
  handler *handler_file= NULL;
 
409
 
 
410
  {
 
411
    LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
 
412
                              strlen(table.engine().name().c_str()) };
 
413
    share->db_plugin= ha_resolve_by_name(session, &engine_name);
 
414
  }
 
415
 
 
416
  share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
 
417
 
 
418
  drizzle::Table::TableOptions table_options;
 
419
 
 
420
  if(table.has_options())
 
421
    table_options= table.options();
 
422
 
 
423
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
 
424
 
 
425
  if(table_options.has_pack_keys())
 
426
  {
 
427
    if(table_options.pack_keys())
 
428
      db_create_options|= HA_OPTION_PACK_KEYS;
 
429
    else
 
430
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
 
431
  }
 
432
 
 
433
  if(table_options.pack_record())
 
434
    db_create_options|= HA_OPTION_PACK_RECORD;
 
435
 
 
436
  if(table_options.has_checksum())
 
437
  {
 
438
    if(table_options.checksum())
 
439
      db_create_options|= HA_OPTION_CHECKSUM;
 
440
    else
 
441
      db_create_options|= HA_OPTION_NO_CHECKSUM;
 
442
  }
 
443
 
 
444
  if(table_options.has_delay_key_write())
 
445
  {
 
446
    if(table_options.delay_key_write())
 
447
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
 
448
    else
 
449
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
 
450
  }
 
451
 
 
452
  /* db_create_options was stored as 2 bytes in FRM
 
453
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
 
454
   */
 
455
  share->db_create_options= (db_create_options & 0x0000FFFF);
469
456
  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
 
  }
 
457
 
 
458
 
 
459
  share->avg_row_length= table_options.has_avg_row_length() ?
 
460
    table_options.avg_row_length() : 0;
 
461
 
 
462
  share->page_checksum= table_options.has_page_checksum() ?
 
463
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
464
    : HA_CHOICE_UNDEF;
 
465
 
 
466
  share->row_type= table_options.has_row_type() ?
 
467
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
468
 
 
469
  share->block_size= table_options.has_block_size() ?
 
470
    table_options.block_size() : 0;
 
471
 
 
472
  share->table_charset= get_charset(table_options.has_collation_id()?
 
473
                                    table_options.collation_id() : 0);
 
474
 
482
475
  if (!share->table_charset)
483
476
  {
484
477
    /* unknown charset in head[38] or pre-3.23 frm */
485
478
    if (use_mb(default_charset_info))
486
479
    {
487
480
      /* 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);
 
481
      errmsg_printf(ERRMSG_LVL_WARN,
 
482
                    _("'%s' had no or invalid character set, "
 
483
                      "and default character set is multi-byte, "
 
484
                      "so character column sizes may have changed"),
 
485
                    share->path.str);
492
486
    }
493
487
    share->table_charset= default_charset_info;
494
488
  }
 
489
 
495
490
  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 */
 
491
 
 
492
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
493
 
499
494
  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;
 
495
 
 
496
  share->max_rows= table_options.has_max_rows() ?
 
497
    table_options.max_rows() : 0;
 
498
 
 
499
  share->min_rows= table_options.has_min_rows() ?
 
500
    table_options.min_rows() : 0;
 
501
 
 
502
  share->keys= table.indexes_size();
 
503
 
 
504
  share->key_parts= 0;
 
505
  for(int indx= 0; indx < table.indexes_size(); indx++)
 
506
    share->key_parts+= table.indexes(indx).index_part_size();
 
507
 
 
508
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
509
                                     table.indexes_size() * sizeof(KEY)
 
510
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
511
 
 
512
  KEY_PART_INFO *key_part;
 
513
 
 
514
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
515
    (share->key_info+table.indexes_size());
 
516
 
 
517
 
 
518
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
519
                                            sizeof(ulong*)*share->key_parts);
 
520
 
 
521
  share->keynames.count= table.indexes_size();
 
522
  share->keynames.name= NULL;
 
523
  share->keynames.type_names= (const char**)
 
524
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
525
 
 
526
  share->keynames.type_lengths= (unsigned int*)
 
527
    alloc_root(&share->mem_root,
 
528
               sizeof(unsigned int) * (table.indexes_size()+1));
 
529
 
 
530
  share->keynames.type_names[share->keynames.count]= NULL;
 
531
  share->keynames.type_lengths[share->keynames.count]= 0;
 
532
 
 
533
  KEY* keyinfo= share->key_info;
 
534
  for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
535
  {
 
536
    drizzle::Table::Index indx= table.indexes(keynr);
 
537
 
 
538
    keyinfo->table= 0;
 
539
    keyinfo->flags= 0;
 
540
 
 
541
    if(indx.is_unique())
 
542
      keyinfo->flags|= HA_NOSAME;
 
543
 
 
544
    if(indx.has_options())
 
545
    {
 
546
      drizzle::Table::Index::IndexOptions indx_options= indx.options();
 
547
      if(indx_options.pack_key())
 
548
        keyinfo->flags|= HA_PACK_KEY;
 
549
 
 
550
      if(indx_options.var_length_key())
 
551
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
552
 
 
553
      if(indx_options.null_part_key())
 
554
        keyinfo->flags|= HA_NULL_PART_KEY;
 
555
 
 
556
      if(indx_options.binary_pack_key())
 
557
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
558
 
 
559
      if(indx_options.has_partial_segments())
 
560
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
561
 
 
562
      if(indx_options.auto_generated_key())
 
563
        keyinfo->flags|= HA_GENERATED_KEY;
 
564
 
 
565
      if(indx_options.has_key_block_size())
 
566
      {
 
567
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
568
        keyinfo->block_size= indx_options.key_block_size();
 
569
      }
 
570
      else
 
571
      {
 
572
        keyinfo->block_size= 0;
 
573
      }
 
574
 
 
575
    }
 
576
 
 
577
    switch(indx.type())
 
578
    {
 
579
    case drizzle::Table::Index::UNKNOWN_INDEX:
 
580
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
581
      break;
 
582
    case drizzle::Table::Index::BTREE:
 
583
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
584
      break;
 
585
    case drizzle::Table::Index::RTREE:
 
586
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
587
      break;
 
588
    case drizzle::Table::Index::HASH:
 
589
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
590
      break;
 
591
    case drizzle::Table::Index::FULLTEXT:
 
592
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
593
 
 
594
    default:
 
595
      /* TODO: suitable warning ? */
 
596
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
597
      break;
 
598
    }
 
599
 
 
600
    keyinfo->key_length= indx.key_length();
 
601
 
 
602
    keyinfo->key_parts= indx.index_part_size();
 
603
 
 
604
    keyinfo->key_part= key_part;
549
605
    keyinfo->rec_per_key= rec_per_key;
550
 
    for (j=keyinfo->key_parts ; j-- ; key_part++)
 
606
 
 
607
    for(unsigned int partnr= 0;
 
608
        partnr < keyinfo->key_parts;
 
609
        partnr++, key_part++)
551
610
    {
 
611
      drizzle::Table::Index::IndexPart part;
 
612
      part= indx.index_part(partnr);
 
613
 
552
614
      *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);
 
615
 
 
616
      key_part->field= NULL;
 
617
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
 
618
      key_part->null_bit= 0;
 
619
      /* key_part->null_offset is only set if null_bit (see later) */
 
620
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
621
      /* key_part->type ???? */
 
622
      key_part->key_part_flag= 0;
 
623
      if(part.has_in_reverse_order())
 
624
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
625
 
 
626
      key_part->length= part.compare_length();
 
627
 
 
628
      key_part->store_length= key_part->length;
 
629
 
 
630
      /* key_part->offset is set later */
 
631
      key_part->key_type= part.key_type();
 
632
 
 
633
    }
 
634
 
 
635
    if(!indx.has_comment())
 
636
    {
 
637
      keyinfo->comment.length= 0;
 
638
      keyinfo->comment.str= NULL;
 
639
    }
 
640
    else
 
641
    {
 
642
      keyinfo->flags|= HA_USES_COMMENT;
 
643
      keyinfo->comment.length= indx.comment().length();
 
644
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
645
                                         indx.comment().c_str(),
 
646
                                         keyinfo->comment.length);
 
647
    }
 
648
 
 
649
    keyinfo->name= strmake_root(&share->mem_root,
 
650
                                indx.name().c_str(),
 
651
                                indx.name().length());
 
652
 
 
653
    share->keynames.type_names[keynr]= keyinfo->name;
 
654
    share->keynames.type_lengths[keynr]= indx.name().length();
 
655
  }
 
656
 
 
657
  share->keys_for_keyread.init(0);
 
658
  share->keys_in_use.init(share->keys);
 
659
 
 
660
  if(table_options.has_connect_string())
 
661
  {
 
662
    size_t len= table_options.connect_string().length();
 
663
    const char* str= table_options.connect_string().c_str();
 
664
 
 
665
    share->connect_string.length= len;
 
666
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
667
  }
 
668
 
 
669
  if(table_options.has_comment())
 
670
  {
 
671
    size_t len= table_options.comment().length();
 
672
    const char* str= table_options.comment().c_str();
 
673
 
 
674
    share->comment.length= len;
 
675
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
676
  }
 
677
 
 
678
  share->key_block_size= table_options.has_key_block_size() ?
 
679
    table_options.key_block_size() : 0;
 
680
 
 
681
  share->fields= table.field_size();
 
682
  share->vfields= 0;
 
683
  share->stored_fields= share->fields;
 
684
 
 
685
  share->field= (Field**) alloc_root(&share->mem_root,
 
686
                                     ((share->fields+1) * sizeof(Field*)));
 
687
  share->field[share->fields]= NULL;
 
688
 
 
689
  uint32_t null_fields= 0;
 
690
  share->reclength= 0;
 
691
 
 
692
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
 
693
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
 
694
 
 
695
  assert(field_offsets && field_pack_length); // TODO: fixme
 
696
 
 
697
  uint32_t interval_count= 0;
 
698
  uint32_t interval_parts= 0;
 
699
 
 
700
  uint32_t stored_columns_reclength= 0;
 
701
 
 
702
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
703
  {
 
704
    drizzle::Table::Field pfield= table.field(fieldnr);
 
705
    if(pfield.has_constraints() && pfield.constraints().is_nullable())
 
706
      null_fields++;
 
707
 
 
708
    bool field_is_stored= true;
 
709
 
 
710
    enum_field_types drizzle_field_type=
 
711
      proto_field_type_to_drizzle_type(pfield.type());
 
712
 
 
713
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
714
    {
 
715
      drizzle::Table::Field::VirtualFieldOptions field_options=
 
716
        pfield.virtual_options();
 
717
 
 
718
      drizzle_field_type=proto_field_type_to_drizzle_type(field_options.type());
 
719
 
 
720
      field_is_stored= field_options.physically_stored();
 
721
    }
 
722
 
 
723
    field_offsets[fieldnr]= stored_columns_reclength;
 
724
 
 
725
    /* the below switch is very similar to
 
726
       Create_field::create_length_to_internal_length in field.cc
 
727
       (which should one day be replace by just this code)
 
728
    */
 
729
    switch(drizzle_field_type)
 
730
    {
 
731
    case DRIZZLE_TYPE_BLOB:
 
732
    case DRIZZLE_TYPE_VARCHAR:
 
733
      {
 
734
        drizzle::Table::Field::StringFieldOptions field_options=
 
735
          pfield.string_options();
 
736
 
 
737
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
738
                                            field_options.collation_id() : 0);
 
739
 
 
740
        if (!cs)
 
741
          cs= default_charset_info;
 
742
 
 
743
        field_pack_length[fieldnr]=
 
744
          calc_pack_length(drizzle_field_type,
 
745
                           field_options.length() * cs->mbmaxlen);
 
746
 
 
747
      }
 
748
      break;
 
749
    case DRIZZLE_TYPE_ENUM:
 
750
      {
 
751
        drizzle::Table::Field::SetFieldOptions field_options=
 
752
          pfield.set_options();
 
753
 
 
754
        field_pack_length[fieldnr]=
 
755
          get_enum_pack_length(field_options.field_value_size());
 
756
 
 
757
        interval_count++;
 
758
        interval_parts+= field_options.field_value_size();
 
759
      }
 
760
      break;
 
761
    case DRIZZLE_TYPE_NEWDECIMAL:
 
762
      {
 
763
        drizzle::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
764
 
 
765
        field_pack_length[fieldnr]=
 
766
          my_decimal_get_binary_size(fo.precision(), fo.scale());
 
767
      }
 
768
      break;
 
769
    default:
 
770
      /* Zero is okay here as length is fixed for other types. */
 
771
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
 
772
    }
 
773
 
 
774
    share->reclength+= field_pack_length[fieldnr];
 
775
 
 
776
    if(field_is_stored)
 
777
      stored_columns_reclength+= field_pack_length[fieldnr];
 
778
  }
 
779
 
 
780
  /* data_offset added to stored_rec_length later */
 
781
  share->stored_rec_length= stored_columns_reclength;
 
782
 
 
783
  /* fix up offsets for non-stored fields (at end of record) */
 
784
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
785
  {
 
786
    drizzle::Table::Field pfield= table.field(fieldnr);
 
787
 
 
788
    bool field_is_stored= true;
 
789
 
 
790
    enum_field_types drizzle_field_type=
 
791
      proto_field_type_to_drizzle_type(pfield.type());
 
792
 
 
793
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
794
    {
 
795
      drizzle::Table::Field::VirtualFieldOptions field_options=
 
796
        pfield.virtual_options();
 
797
 
 
798
      field_is_stored= field_options.physically_stored();
 
799
    }
 
800
 
 
801
    if(!field_is_stored)
 
802
    {
 
803
      field_offsets[fieldnr]= stored_columns_reclength;
 
804
      stored_columns_reclength+= field_pack_length[fieldnr];
 
805
    }
 
806
  }
 
807
  share->null_fields= null_fields;
 
808
 
 
809
  ulong null_bits= null_fields;
 
810
  if(!table_options.pack_record())
 
811
    null_bits++;
 
812
  ulong data_offset= (null_bits + 7)/8;
 
813
 
 
814
 
 
815
  share->reclength+= data_offset;
 
816
  share->stored_rec_length+= data_offset;
 
817
 
 
818
  ulong rec_buff_length;
 
819
 
 
820
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
717
821
  share->rec_buff_length= rec_buff_length;
 
822
 
 
823
  unsigned char* record= NULL;
 
824
 
718
825
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
719
826
                                     rec_buff_length)))
720
 
    goto err;                                   /* purecov: inspected */
 
827
    abort();
 
828
 
 
829
  memset(record, 0, rec_buff_length);
 
830
 
 
831
  int null_count= 0;
 
832
 
 
833
  if(!table_options.pack_record())
 
834
  {
 
835
    null_count++; // one bit for delete mark.
 
836
    *record|= 1;
 
837
  }
 
838
 
721
839
  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)
 
840
 
 
841
  if(interval_count)
736
842
  {
737
 
    share->comment.length=  (int) (forminfo[46]);
738
 
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
739
 
                                     share->comment.length);
 
843
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
844
                                           interval_count*sizeof(TYPELIB));
740
845
  }
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
 
 
 
846
  else
 
847
    share->intervals= NULL;
 
848
 
 
849
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
850
                                  (share->fields+1)*sizeof(char*));
 
851
 
 
852
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
853
                                  (share->fields+1)*sizeof(unsigned int));
 
854
 
 
855
  share->fieldnames.type_names[share->fields]= NULL;
 
856
  share->fieldnames.type_lengths[share->fields]= 0;
 
857
  share->fieldnames.count= share->fields;
 
858
 
 
859
 
 
860
  /* Now fix the TYPELIBs for the intervals (enum values)
 
861
     and field names.
 
862
   */
 
863
 
 
864
  uint32_t interval_nr= 0;
 
865
 
 
866
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
775
867
  {
776
 
    /* Set ENUM and SET lengths */
777
 
    TYPELIB *interval;
778
 
    for (interval= share->intervals;
779
 
         interval < share->intervals + interval_count;
780
 
         interval++)
 
868
    drizzle::Table::Field pfield= table.field(fieldnr);
 
869
 
 
870
    /* field names */
 
871
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
 
872
                                                        pfield.name().c_str(),
 
873
                                                        pfield.name().length());
 
874
 
 
875
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
 
876
 
 
877
    /* enum typelibs */
 
878
    if(pfield.type() != drizzle::Table::Field::ENUM)
 
879
      continue;
 
880
 
 
881
    drizzle::Table::Field::SetFieldOptions field_options=
 
882
      pfield.set_options();
 
883
 
 
884
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
885
                                             field_options.collation_id() : 0);
 
886
 
 
887
    if (!charset)
 
888
      charset= default_charset_info;
 
889
 
 
890
    TYPELIB *t= &(share->intervals[interval_nr]);
 
891
 
 
892
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
893
                           (field_options.field_value_size()+1)*sizeof(char*));
 
894
 
 
895
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
896
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
 
897
 
 
898
    t->type_names[field_options.field_value_size()]= NULL;
 
899
    t->type_lengths[field_options.field_value_size()]= 0;
 
900
 
 
901
    t->count= field_options.field_value_size();
 
902
    t->name= NULL;
 
903
 
 
904
    for(int n=0; n < field_options.field_value_size(); n++)
781
905
    {
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;
 
906
      t->type_names[n]= strmake_root(&share->mem_root,
 
907
                                     field_options.field_value(n).c_str(),
 
908
                                     field_options.field_value(n).length());
 
909
 
 
910
      /* Go ask the charset what the length is as for "" length=1
 
911
         and there's stripping spaces or some other crack going on.
 
912
       */
 
913
      uint32_t lengthsp;
 
914
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
915
                                        field_options.field_value(n).length());
 
916
      t->type_lengths[n]= lengthsp;
792
917
    }
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)
 
918
    interval_nr++;
 
919
  }
 
920
 
 
921
 
 
922
  /* and read the fields */
 
923
  interval_nr= 0;
 
924
 
 
925
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
926
 
 
927
  if(use_hash)
818
928
    use_hash= !hash_init(&share->name_hash,
819
929
                         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++)
 
930
                         share->fields, 0, 0,
 
931
                         (hash_get_key) get_field_name, 0, 0);
 
932
 
 
933
  unsigned char* null_pos= record;;
 
934
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
 
935
 
 
936
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
824
937
  {
825
 
    uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
826
 
    enum_field_types field_type;
 
938
    drizzle::Table::Field pfield= table.field(fieldnr);
 
939
 
827
940
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
828
 
    const CHARSET_INFO *charset= NULL;
 
941
 
 
942
    switch(pfield.format())
 
943
    {
 
944
    case drizzle::Table::Field::DefaultFormat:
 
945
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
946
      break;
 
947
    case drizzle::Table::Field::FixedFormat:
 
948
      column_format= COLUMN_FORMAT_TYPE_FIXED;
 
949
      break;
 
950
    case drizzle::Table::Field::DynamicFormat:
 
951
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
 
952
      break;
 
953
    default:
 
954
      assert(1);
 
955
    }
 
956
 
 
957
    Field::utype unireg_type= Field::NONE;
 
958
 
 
959
    if(pfield.has_numeric_options()
 
960
       && pfield.numeric_options().is_autoincrement())
 
961
    {
 
962
      unireg_type= Field::NEXT_NUMBER;
 
963
    }
 
964
 
 
965
    if(pfield.has_options()
 
966
       && pfield.options().has_default_value()
 
967
       && pfield.options().default_value().compare("NOW()")==0)
 
968
    {
 
969
      if(pfield.options().has_update_value()
 
970
         && pfield.options().update_value().compare("NOW()")==0)
 
971
      {
 
972
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
973
      }
 
974
      else if (!pfield.options().has_update_value())
 
975
      {
 
976
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
977
      }
 
978
      else
 
979
        assert(1); // Invalid update value.
 
980
    }
 
981
    else if (pfield.has_options()
 
982
             && pfield.options().has_update_value()
 
983
             && pfield.options().update_value().compare("NOW()")==0)
 
984
    {
 
985
      unireg_type= Field::TIMESTAMP_UN_FIELD;
 
986
    }
 
987
 
829
988
    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
 
      }
 
989
    if(!pfield.has_comment())
 
990
    {
 
991
      comment.str= (char*)"";
 
992
      comment.length= 0;
869
993
    }
870
994
    else
871
995
    {
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
 
    {
 
996
      size_t len= pfield.comment().length();
 
997
      const char* str= pfield.comment().c_str();
 
998
 
 
999
      comment.str= strmake_root(&share->mem_root, str, len);
 
1000
      comment.length= len;
 
1001
    }
 
1002
 
 
1003
    enum_field_types field_type;
 
1004
    virtual_column_info *vcol_info= NULL;
 
1005
    bool field_is_stored= true;
 
1006
 
 
1007
 
 
1008
    field_type= proto_field_type_to_drizzle_type(pfield.type());
 
1009
 
 
1010
    if(field_type==DRIZZLE_TYPE_VIRTUAL)
 
1011
    {
 
1012
      drizzle::Table::Field::VirtualFieldOptions field_options=
 
1013
        pfield.virtual_options();
 
1014
 
 
1015
      vcol_info= new virtual_column_info();
 
1016
      field_type= proto_field_type_to_drizzle_type(field_options.type());
 
1017
      field_is_stored= field_options.physically_stored();
 
1018
 
 
1019
      size_t len= field_options.expression().length();
 
1020
      const char* str= field_options.expression().c_str();
 
1021
 
 
1022
      vcol_info->expr_str.str= strmake_root(&share->mem_root, str, len);
 
1023
      vcol_info->expr_str.length= len;
 
1024
 
 
1025
      share->vfields++;
 
1026
    }
 
1027
 
 
1028
    const CHARSET_INFO *charset= &my_charset_bin;
 
1029
 
 
1030
    if(field_type==DRIZZLE_TYPE_BLOB
 
1031
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
1032
    {
 
1033
      drizzle::Table::Field::StringFieldOptions field_options=
 
1034
        pfield.string_options();
 
1035
 
 
1036
      charset= get_charset(field_options.has_collation_id()?
 
1037
                           field_options.collation_id() : 0);
 
1038
 
 
1039
      if (!charset)
 
1040
        charset= default_charset_info;
 
1041
 
 
1042
    }
 
1043
 
 
1044
    if(field_type==DRIZZLE_TYPE_ENUM)
 
1045
    {
 
1046
      drizzle::Table::Field::SetFieldOptions field_options=
 
1047
        pfield.set_options();
 
1048
 
 
1049
      charset= get_charset(field_options.has_collation_id()?
 
1050
                           field_options.collation_id() : 0);
 
1051
 
 
1052
      if (!charset)
 
1053
        charset= default_charset_info;
 
1054
 
 
1055
    }
 
1056
 
 
1057
    Item *default_value= NULL;
 
1058
 
 
1059
    if(pfield.options().has_default_value()
 
1060
       || pfield.options().has_default_null()
 
1061
       || pfield.options().has_default_bin_value())
 
1062
    {
 
1063
      default_value= default_value_item(field_type,
 
1064
                                        charset,
 
1065
                                        pfield.options().default_null(),
 
1066
                                        &pfield.options().default_value(),
 
1067
                                        &pfield.options().default_bin_value());
 
1068
    }
 
1069
 
 
1070
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
 
1071
 
 
1072
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
1073
    memset(&temp_table, 0, sizeof(temp_table));
 
1074
    temp_table.s= share;
 
1075
    temp_table.in_use= session;
 
1076
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
 
1077
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
1078
 
 
1079
    Field* f= make_field(share, &share->mem_root,
 
1080
                         record+field_offsets[fieldnr]+data_offset,
 
1081
                         pfield.options().length(),
 
1082
                         null_pos,
 
1083
                         null_bit_pos,
 
1084
                         pack_flag,
 
1085
                         field_type,
 
1086
                         charset,
 
1087
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
1088
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
1089
                         share->intervals+(interval_nr++)
 
1090
                         : (TYPELIB*) 0),
 
1091
                        share->fieldnames.type_names[fieldnr]);
 
1092
 
 
1093
    share->field[fieldnr]= f;
 
1094
 
 
1095
    f->init(&temp_table); /* blob default values need table obj */
 
1096
 
 
1097
    if(!(f->flags & NOT_NULL_FLAG))
 
1098
    {
 
1099
      *f->null_ptr|= f->null_bit;
934
1100
      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)
 
1101
        null_pos++;
 
1102
      null_count++;
 
1103
    }
 
1104
 
 
1105
    if(default_value)
 
1106
    {
 
1107
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
1108
      session->count_cuted_fields= CHECK_FIELD_WARN;
 
1109
      int res= default_value->save_in_field(f, 1);
 
1110
      session->count_cuted_fields= old_count_cuted_fields;
 
1111
      if (res != 0 && res != 3)
 
1112
      {
 
1113
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
 
1114
        error= 1;
 
1115
        goto err;
 
1116
      }
 
1117
    }
 
1118
    else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
 
1119
            (f->flags & NOT_NULL_FLAG))
 
1120
    {
 
1121
      f->set_notnull();
 
1122
      f->store((int64_t) 1, true);
 
1123
    }
 
1124
    else
 
1125
      f->reset();
 
1126
 
 
1127
    /* hack to undo f->init() */
 
1128
    f->table= NULL;
 
1129
    f->orig_table= NULL;
 
1130
 
 
1131
    f->field_index= fieldnr;
 
1132
    f->comment= comment;
 
1133
    f->vcol_info= vcol_info;
 
1134
    f->is_stored= field_is_stored;
 
1135
    if(!default_value
 
1136
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
1137
       && (f->flags & NOT_NULL_FLAG)
 
1138
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
 
1139
      f->flags|= NO_DEFAULT_VALUE_FLAG;
 
1140
 
 
1141
    if(f->unireg_check == Field::NEXT_NUMBER)
 
1142
      share->found_next_number_field= &(share->field[fieldnr]);
 
1143
 
 
1144
    if(share->timestamp_field == f)
 
1145
      share->timestamp_field_offset= fieldnr;
 
1146
 
 
1147
    if (use_hash) /* supposedly this never fails... but comments lie */
946
1148
      (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,
 
1149
                            (unsigned char*)&(share->field[fieldnr]));
 
1150
 
 
1151
    if(!f->is_stored)
 
1152
    {
 
1153
      share->stored_fields--;
 
1154
    }
 
1155
  }
 
1156
 
 
1157
  keyinfo= share->key_info;
 
1158
  for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
 
1159
  {
 
1160
    key_part= keyinfo->key_part;
 
1161
 
 
1162
    for(unsigned int partnr= 0;
 
1163
        partnr < keyinfo->key_parts;
 
1164
        partnr++, key_part++)
 
1165
    {
 
1166
      /* Fix up key_part->offset by adding data_offset.
 
1167
         We really should compute offset as well.
 
1168
         But at least this way we are a little better. */
 
1169
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
1170
    }
 
1171
  }
 
1172
 
 
1173
  /*
 
1174
    We need to set the unused bits to 1. If the number of bits is a multiple
 
1175
    of 8 there are no unused bits.
 
1176
  */
 
1177
 
 
1178
  if (null_count & 7)
 
1179
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
1180
 
 
1181
  share->null_bytes= (null_pos - (unsigned char*) record +
 
1182
                      (null_bit_pos + 7) / 8);
 
1183
 
 
1184
  share->last_null_bit_pos= null_bit_pos;
 
1185
 
 
1186
  free(field_offsets);
 
1187
  free(field_pack_length);
 
1188
 
 
1189
  if(!(handler_file= get_new_handler(share, session->mem_root,
 
1190
                                     share->db_type())))
 
1191
    abort(); // FIXME
 
1192
 
 
1193
  /* Fix key stuff */
 
1194
  if (share->key_parts)
 
1195
  {
 
1196
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
955
1197
                                       &share->keynames, 3) - 1);
 
1198
 
956
1199
    int64_t ha_option= handler_file->ha_table_flags();
 
1200
 
957
1201
    keyinfo= share->key_info;
958
1202
    key_part= keyinfo->key_part;
959
1203
 
960
1204
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
961
1205
    {
962
1206
      uint32_t usable_parts= 0;
963
 
      keyinfo->name=(char*) share->keynames.type_names[key];
964
1207
 
965
1208
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
966
1209
      {
969
1212
          declare this as a primary key.
970
1213
        */
971
1214
        primary_key=key;
972
 
        for (i=0 ; i < keyinfo->key_parts ;i++)
 
1215
        for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
973
1216
        {
974
1217
          uint32_t fieldnr= key_part[i].fieldnr;
975
1218
          if (!fieldnr ||
977
1220
              share->field[fieldnr-1]->key_length() !=
978
1221
              key_part[i].length)
979
1222
          {
980
 
            primary_key=MAX_KEY;                // Can't be used
 
1223
            primary_key=MAX_KEY;                // Can't be used
981
1224
            break;
982
1225
          }
983
1226
        }
984
1227
      }
985
1228
 
986
 
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1229
      for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
987
1230
      {
988
1231
        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
1232
        if (!key_part->fieldnr)
995
1233
        {
996
 
          error= 4;                             // Wrong file
997
 
          goto err;
 
1234
//          error= 4;                             // Wrong file
 
1235
          abort(); // goto err;
998
1236
        }
999
1237
        field= key_part->field= share->field[key_part->fieldnr-1];
1000
1238
        key_part->type= field->key_type();
1001
1239
        if (field->null_ptr)
1002
1240
        {
1003
 
          key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
 
1241
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1004
1242
                                        share->default_values);
1005
1243
          key_part->null_bit= field->null_bit;
1006
1244
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1091
1329
                                      fieldnr);
1092
1330
        }
1093
1331
      }
 
1332
 
1094
1333
    }
1095
1334
    else
1096
1335
      share->primary_key = MAX_KEY; // we do not have a primary key
1097
1336
  }
1098
1337
  else
1099
1338
    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
1339
 
1111
1340
  if (share->found_next_number_field)
1112
1341
  {
1113
 
    reg_field= *share->found_next_number_field;
1114
 
    if ((int) (share->next_number_index= (uint)
 
1342
    Field *reg_field= *share->found_next_number_field;
 
1343
    if ((int) (share->next_number_index= (uint32_t)
1115
1344
               find_ref_key(share->key_info, share->keys,
1116
1345
                            share->default_values, reg_field,
1117
1346
                            &share->next_number_key_offset,
1133
1362
    /* Store offsets to blob fields to find them fast */
1134
1363
    if (!(share->blob_field= save=
1135
1364
          (uint*) alloc_root(&share->mem_root,
1136
 
                             (uint) (share->blob_fields* sizeof(uint)))))
 
1365
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1137
1366
      goto err;
1138
1367
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1139
1368
    {
1142
1371
    }
1143
1372
  }
1144
1373
 
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
1374
  share->db_low_byte_first= handler_file->low_byte_first();
1154
1375
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1155
1376
 
 
1377
  my_bitmap_map *bitmaps;
 
1378
 
1156
1379
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1157
1380
                                             share->column_bitmap_size)))
1158
1381
    goto err;
1159
1382
  bitmap_init(&share->all_set, bitmaps, share->fields, false);
1160
1383
  bitmap_set_all(&share->all_set);
1161
1384
 
1162
 
  delete handler_file;
1163
 
  if (buff)
1164
 
    free(buff);
 
1385
  if(handler_file)
 
1386
    delete handler_file;
1165
1387
  return (0);
1166
1388
 
1167
 
 err:
1168
 
  if (buff)
1169
 
    free(buff);
 
1389
err:
1170
1390
  share->error= error;
1171
1391
  share->open_errno= my_errno;
1172
 
  share->errarg= errarg;
1173
 
  if (disk_buff)
1174
 
    free(disk_buff);
1175
 
  delete handler_file;
 
1392
  share->errarg= 0;
1176
1393
  hash_free(&share->name_hash);
1177
 
 
1178
 
  open_table_error(share, error, share->open_errno, errarg);
 
1394
  if(handler_file)
 
1395
    delete handler_file;
 
1396
  open_table_error(share, error, share->open_errno, 0);
 
1397
  return error;
 
1398
}
 
1399
 
 
1400
/*
 
1401
  Read table definition from a binary / text based .frm file
 
1402
 
 
1403
  SYNOPSIS
 
1404
  open_table_def()
 
1405
  session               Thread handler
 
1406
  share         Fill this with table definition
 
1407
  db_flags      Bit mask of the following flags: OPEN_VIEW
 
1408
 
 
1409
  NOTES
 
1410
    This function is called when the table definition is not cached in
 
1411
    table_def_cache
 
1412
    The data is returned in 'share', which is alloced by
 
1413
    alloc_table_share().. The code assumes that share is initialized.
 
1414
 
 
1415
  RETURN VALUES
 
1416
   0    ok
 
1417
   1    Error (see open_table_error)
 
1418
   2    Error (see open_table_error)
 
1419
   3    Wrong data in .frm file
 
1420
   4    Error (see open_table_error)
 
1421
   5    Error (see open_table_error: charset unavailable)
 
1422
   6    Unknown .frm version
 
1423
*/
 
1424
 
 
1425
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
 
1426
{
 
1427
  int error;
 
1428
  bool error_given;
 
1429
  string proto_path("");
 
1430
 
 
1431
  error= 1;
 
1432
  error_given= 0;
 
1433
 
 
1434
  proto_path.reserve(FN_REFLEN);
 
1435
  proto_path.append(share->normalized_path.str);
 
1436
 
 
1437
  proto_path.append(".dfe");
 
1438
 
 
1439
  drizzle::Table table;
 
1440
 
 
1441
  if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
 
1442
  {
 
1443
    if(error>0)
 
1444
    {
 
1445
      my_errno= error;
 
1446
      error= 1;
 
1447
    }
 
1448
    else
 
1449
    {
 
1450
      if(!table.IsInitialized())
 
1451
      {
 
1452
        error= 4;
 
1453
      }
 
1454
    }
 
1455
    goto err_not_open;
 
1456
  }
 
1457
 
 
1458
  error= parse_table_proto(session, table, share);
 
1459
 
 
1460
  share->table_category= get_table_category(& share->db, & share->table_name);
 
1461
 
 
1462
  if (!error)
 
1463
    session->status_var.opened_shares++;
 
1464
 
 
1465
err_not_open:
 
1466
  if (error && !error_given)
 
1467
  {
 
1468
    share->error= error;
 
1469
    open_table_error(share, error, (share->open_errno= my_errno), 0);
 
1470
  }
 
1471
 
1179
1472
  return(error);
1180
 
} /* open_binary_frm */
 
1473
}
 
1474
 
 
1475
/*
 
1476
  Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
 
1477
  This routine is used for error handling purposes.
 
1478
 
 
1479
  SYNOPSIS
 
1480
    clear_field_flag()
 
1481
    table                Table object for which virtual columns are set-up
 
1482
 
 
1483
  RETURN VALUE
 
1484
    NONE
 
1485
*/
 
1486
static void clear_field_flag(Table *table)
 
1487
{
 
1488
  Field **ptr;
 
1489
 
 
1490
  for (ptr= table->field; *ptr; ptr++)
 
1491
    (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
 
1492
}
 
1493
 
 
1494
/*
 
1495
  The function uses the feature in fix_fields where the flag
 
1496
  GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
 
1497
  This field must always be reset before returning from the function
 
1498
  since it is used for other purposes as well.
 
1499
 
 
1500
  SYNOPSIS
 
1501
    fix_fields_vcol_func()
 
1502
    session                  The thread object
 
1503
    func_item            The item tree reference of the virtual columnfunction
 
1504
    table                The table object
 
1505
    field_name           The name of the processed field
 
1506
 
 
1507
  RETURN VALUE
 
1508
    true                 An error occurred, something was wrong with the
 
1509
                         function.
 
1510
    false                Ok, a partition field array was created
 
1511
*/
 
1512
 
 
1513
bool fix_fields_vcol_func(Session *session,
 
1514
                          Item* func_expr,
 
1515
                          Table *table,
 
1516
                          const char *field_name)
 
1517
{
 
1518
  uint32_t dir_length, home_dir_length;
 
1519
  bool result= true;
 
1520
  TableList tables;
 
1521
  TableList *save_table_list, *save_first_table, *save_last_table;
 
1522
  int error;
 
1523
  Name_resolution_context *context;
 
1524
  const char *save_where;
 
1525
  char* db_name;
 
1526
  char db_name_string[FN_REFLEN];
 
1527
  bool save_use_only_table_context;
 
1528
  Field **ptr, *field;
 
1529
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
 
1530
  assert(func_expr);
 
1531
 
 
1532
  /*
 
1533
    Set-up the TABLE_LIST object to be a list with a single table
 
1534
    Set the object to zero to create NULL pointers and set alias
 
1535
    and real name to table name and get database name from file name.
 
1536
  */
 
1537
 
 
1538
  bzero((void*)&tables, sizeof(TableList));
 
1539
  tables.alias= tables.table_name= (char*) table->s->table_name.str;
 
1540
  tables.table= table;
 
1541
  tables.next_local= NULL;
 
1542
  tables.next_name_resolution_table= NULL;
 
1543
  memcpy(db_name_string,
 
1544
         table->s->normalized_path.str,
 
1545
         table->s->normalized_path.length);
 
1546
  db_name_string[table->s->normalized_path.length]= '\0';
 
1547
  dir_length= dirname_length(db_name_string);
 
1548
  db_name_string[dir_length - 1]= 0;
 
1549
  home_dir_length= dirname_length(db_name_string);
 
1550
  db_name= &db_name_string[home_dir_length];
 
1551
  tables.db= db_name;
 
1552
 
 
1553
  session->mark_used_columns= MARK_COLUMNS_NONE;
 
1554
 
 
1555
  context= session->lex->current_context();
 
1556
  table->map= 1; //To ensure correct calculation of const item
 
1557
  table->get_fields_in_item_tree= true;
 
1558
  save_table_list= context->table_list;
 
1559
  save_first_table= context->first_name_resolution_table;
 
1560
  save_last_table= context->last_name_resolution_table;
 
1561
  context->table_list= &tables;
 
1562
  context->first_name_resolution_table= &tables;
 
1563
  context->last_name_resolution_table= NULL;
 
1564
  func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
 
1565
  save_where= session->where;
 
1566
  session->where= "virtual column function";
 
1567
 
 
1568
  /* Save the context before fixing the fields*/
 
1569
  save_use_only_table_context= session->lex->use_only_table_context;
 
1570
  session->lex->use_only_table_context= true;
 
1571
  /* Fix fields referenced to by the virtual column function */
 
1572
  error= func_expr->fix_fields(session, (Item**)0);
 
1573
  /* Restore the original context*/
 
1574
  session->lex->use_only_table_context= save_use_only_table_context;
 
1575
  context->table_list= save_table_list;
 
1576
  context->first_name_resolution_table= save_first_table;
 
1577
  context->last_name_resolution_table= save_last_table;
 
1578
 
 
1579
  if (unlikely(error))
 
1580
  {
 
1581
    clear_field_flag(table);
 
1582
    goto end;
 
1583
  }
 
1584
  session->where= save_where;
 
1585
  /*
 
1586
    Walk through the Item tree checking if all items are valid
 
1587
   to be part of the virtual column
 
1588
 */
 
1589
  error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
 
1590
  if (error)
 
1591
  {
 
1592
    my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
 
1593
    clear_field_flag(table);
 
1594
    goto end;
 
1595
  }
 
1596
  if (unlikely(func_expr->const_item()))
 
1597
  {
 
1598
    my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
 
1599
    clear_field_flag(table);
 
1600
    goto end;
 
1601
  }
 
1602
  /* Ensure that this virtual column is not based on another virtual field. */
 
1603
  ptr= table->field;
 
1604
  while ((field= *(ptr++)))
 
1605
  {
 
1606
    if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
 
1607
        (field->vcol_info))
 
1608
    {
 
1609
      my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
 
1610
      clear_field_flag(table);
 
1611
      goto end;
 
1612
    }
 
1613
  }
 
1614
  /*
 
1615
    Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
 
1616
    when calling fix_fields.
 
1617
  */
 
1618
  clear_field_flag(table);
 
1619
  result= false;
 
1620
 
 
1621
end:
 
1622
  table->get_fields_in_item_tree= false;
 
1623
  session->mark_used_columns= save_mark_used_columns;
 
1624
  table->map= 0; //Restore old value
 
1625
  return(result);
 
1626
}
 
1627
 
 
1628
/*
 
1629
  Unpack the definition of a virtual column
 
1630
 
 
1631
  SYNOPSIS
 
1632
    unpack_vcol_info_from_frm()
 
1633
    session                  Thread handler
 
1634
    table                Table with the checked field
 
1635
    field                Pointer to Field object
 
1636
    open_mode            Open table mode needed to determine
 
1637
                         which errors need to be generated in a failure
 
1638
    error_reported       updated flag for the caller that no other error
 
1639
                         messages are to be generated.
 
1640
 
 
1641
  RETURN VALUES
 
1642
    true            Failure
 
1643
    false           Success
 
1644
*/
 
1645
bool unpack_vcol_info_from_frm(Session *session,
 
1646
                               Table *table,
 
1647
                               Field *field,
 
1648
                               LEX_STRING *vcol_expr,
 
1649
                               open_table_mode open_mode,
 
1650
                               bool *error_reported)
 
1651
{
 
1652
  assert(vcol_expr);
 
1653
 
 
1654
  /*
 
1655
    Step 1: Construct a statement for the parser.
 
1656
    The parsed string needs to take the following format:
 
1657
    "PARSE_VCOL_EXPR (<expr_string_from_frm>)"
 
1658
  */
 
1659
  char *vcol_expr_str;
 
1660
  int str_len= 0;
 
1661
 
 
1662
  if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
 
1663
                                          vcol_expr->length +
 
1664
                                            parse_vcol_keyword.length + 3)))
 
1665
  {
 
1666
    return(true);
 
1667
  }
 
1668
  memcpy(vcol_expr_str,
 
1669
         (char*) parse_vcol_keyword.str,
 
1670
         parse_vcol_keyword.length);
 
1671
  str_len= parse_vcol_keyword.length;
 
1672
  memcpy(vcol_expr_str + str_len, "(", 1);
 
1673
  str_len++;
 
1674
  memcpy(vcol_expr_str + str_len,
 
1675
         (char*) vcol_expr->str,
 
1676
         vcol_expr->length);
 
1677
  str_len+= vcol_expr->length;
 
1678
  memcpy(vcol_expr_str + str_len, ")", 1);
 
1679
  str_len++;
 
1680
  memcpy(vcol_expr_str + str_len, "\0", 1);
 
1681
  str_len++;
 
1682
  Lex_input_stream lip(session, vcol_expr_str, str_len);
 
1683
 
 
1684
  /*
 
1685
    Step 2: Setup session for parsing.
 
1686
    1) make Item objects be created in the memory allocated for the Table
 
1687
       object (not TABLE_SHARE)
 
1688
    2) ensure that created Item's are not put on to session->free_list
 
1689
       (which is associated with the parsed statement and hence cleared after
 
1690
       the parsing)
 
1691
    3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
 
1692
       to be parsed as a SQL command.
 
1693
  */
 
1694
  MEM_ROOT **root_ptr, *old_root;
 
1695
  Item *backup_free_list= session->free_list;
 
1696
  root_ptr= current_mem_root_ptr();
 
1697
  old_root= *root_ptr;
 
1698
  *root_ptr= &table->mem_root;
 
1699
  session->free_list= NULL;
 
1700
  session->lex->parse_vcol_expr= true;
 
1701
 
 
1702
  /*
 
1703
    Step 3: Use the parser to build an Item object from.
 
1704
  */
 
1705
  if (parse_sql(session, &lip))
 
1706
  {
 
1707
    goto parse_err;
 
1708
  }
 
1709
  /* From now on use vcol_info generated by the parser. */
 
1710
  field->vcol_info= session->lex->vcol_info;
 
1711
 
 
1712
  /* Validate the Item tree. */
 
1713
  if (fix_fields_vcol_func(session,
 
1714
                           field->vcol_info->expr_item,
 
1715
                           table,
 
1716
                           field->field_name))
 
1717
  {
 
1718
    if (open_mode == OTM_CREATE)
 
1719
    {
 
1720
      /*
 
1721
        During CREATE/ALTER TABLE it is ok to receive errors here.
 
1722
        It is not ok if it happens during the opening of an frm
 
1723
        file as part of a normal query.
 
1724
      */
 
1725
      *error_reported= true;
 
1726
    }
 
1727
    field->vcol_info= NULL;
 
1728
    goto parse_err;
 
1729
  }
 
1730
  field->vcol_info->item_free_list= session->free_list;
 
1731
  session->free_list= backup_free_list;
 
1732
  *root_ptr= old_root;
 
1733
 
 
1734
  return(false);
 
1735
 
 
1736
parse_err:
 
1737
  session->lex->parse_vcol_expr= false;
 
1738
  session->free_items();
 
1739
  *root_ptr= old_root;
 
1740
  session->free_list= backup_free_list;
 
1741
  return(true);
 
1742
}
1181
1743
 
1182
1744
 
1183
1745
/*
1185
1747
 
1186
1748
  SYNOPSIS
1187
1749
    open_table_from_share()
1188
 
    thd                 Thread handler
 
1750
    session                     Thread handler
1189
1751
    share               Table definition
1190
1752
    alias               Alias for table
1191
1753
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1208
1770
   7    Table definition has changed in engine
1209
1771
*/
1210
1772
 
1211
 
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
 
1773
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1212
1774
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1213
1775
                          Table *outparam, open_table_mode open_mode)
1214
1776
{
1216
1778
  uint32_t records, i, bitmap_size;
1217
1779
  bool error_reported= false;
1218
1780
  unsigned char *record, *bitmaps;
1219
 
  Field **field_ptr;
 
1781
  Field **field_ptr, **vfield_ptr;
1220
1782
 
1221
 
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
1222
 
  assert(thd->lex->is_lex_started);
 
1783
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1784
  assert(session->lex->is_lex_started);
1223
1785
 
1224
1786
  error= 1;
1225
1787
  memset(outparam, 0, sizeof(*outparam));
1226
 
  outparam->in_use= thd;
 
1788
  outparam->in_use= session;
1227
1789
  outparam->s= share;
1228
1790
  outparam->db_stat= db_stat;
1229
1791
  outparam->write_row_record= NULL;
1230
1792
 
1231
1793
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1232
1794
 
1233
 
  if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
 
1795
  if (!(outparam->alias= strdup(alias)))
1234
1796
    goto err;
1235
1797
  outparam->quick_keys.init();
1236
1798
  outparam->covering_keys.init();
1292
1854
#endif
1293
1855
 
1294
1856
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1295
 
                                          (uint) ((share->fields+1)*
 
1857
                                          (uint32_t) ((share->fields+1)*
1296
1858
                                                  sizeof(Field*)))))
1297
1859
    goto err;                                   /* purecov: inspected */
1298
1860
 
1299
1861
  outparam->field= field_ptr;
1300
1862
 
1301
1863
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
1302
 
  if (share->null_field_first)
1303
 
    outparam->null_flags= (unsigned char*) record+1;
1304
 
  else
1305
 
    outparam->null_flags= (unsigned char*) (record+ 1+ share->reclength -
1306
 
                                    share->null_bytes);
 
1864
 
 
1865
  outparam->null_flags= (unsigned char*) record+1;
1307
1866
 
1308
1867
  /* Setup copy of fields from share, but use the right alias and record */
1309
1868
  for (i=0 ; i < share->fields; i++, field_ptr++)
1315
1874
 
1316
1875
  if (share->found_next_number_field)
1317
1876
    outparam->found_next_number_field=
1318
 
      outparam->field[(uint) (share->found_next_number_field - share->field)];
 
1877
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1319
1878
  if (share->timestamp_field)
1320
1879
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1321
1880
 
1331
1890
      goto err;
1332
1891
    outparam->key_info= key_info;
1333
1892
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1334
 
    
 
1893
 
1335
1894
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1336
1895
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1337
1896
                                                   share->key_parts));
1366
1925
    }
1367
1926
  }
1368
1927
 
 
1928
  /*
 
1929
    Process virtual columns, if any.
 
1930
  */
 
1931
  if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1932
                                              (uint32_t) ((share->vfields+1)*
 
1933
                                                      sizeof(Field*)))))
 
1934
    goto err;
 
1935
 
 
1936
  outparam->vfield= vfield_ptr;
 
1937
 
 
1938
  for (field_ptr= outparam->field; *field_ptr; field_ptr++)
 
1939
  {
 
1940
    if ((*field_ptr)->vcol_info)
 
1941
    {
 
1942
      if (unpack_vcol_info_from_frm(session,
 
1943
                                    outparam,
 
1944
                                    *field_ptr,
 
1945
                                    &(*field_ptr)->vcol_info->expr_str,
 
1946
                                    open_mode,
 
1947
                                    &error_reported))
 
1948
      {
 
1949
        error= 4; // in case no error is reported
 
1950
        goto err;
 
1951
      }
 
1952
      *(vfield_ptr++)= *field_ptr;
 
1953
    }
 
1954
  }
 
1955
  *vfield_ptr= NULL;                              // End marker
 
1956
  /* Check virtual columns against table's storage engine. */
 
1957
  if ((share->vfields && outparam->file) &&
 
1958
        (not outparam->file->check_if_supported_virtual_columns()))
 
1959
  {
 
1960
    my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
1961
             MYF(0),
 
1962
             "Specified storage engine");
 
1963
    error_reported= true;
 
1964
    goto err;
 
1965
  }
 
1966
 
1369
1967
  /* Allocate bitmaps */
1370
1968
 
1371
1969
  bitmap_size= share->column_bitmap_size;
1427
2025
    }
1428
2026
  }
1429
2027
 
1430
 
#if defined(HAVE_purify) 
 
2028
#if defined(HAVE_purify)
1431
2029
  memset(bitmaps, 0, bitmap_size*3);
1432
2030
#endif
1433
2031
 
1434
2032
  outparam->no_replicate= outparam->file;
1435
 
  thd->status_var.opened_tables++;
 
2033
  session->status_var.opened_tables++;
1436
2034
 
1437
2035
  return (0);
1438
2036
 
1447
2045
  return (error);
1448
2046
}
1449
2047
 
 
2048
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
 
2049
uint32_t  Table::tmpkeyval()
 
2050
{
 
2051
  return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
 
2052
}
1450
2053
 
1451
2054
/*
1452
2055
  Free information allocated by openfrm
1457
2060
    free_share          Is 1 if we also want to free table_share
1458
2061
*/
1459
2062
 
1460
 
int closefrm(register Table *table, bool free_share)
 
2063
int Table::closefrm(bool free_share)
1461
2064
{
1462
2065
  int error=0;
1463
2066
 
1464
 
  if (table->db_stat)
1465
 
    error=table->file->close();
1466
 
  free((char*) table->alias);
1467
 
  table->alias= 0;
1468
 
  if (table->field)
 
2067
  if (db_stat)
 
2068
    error= file->close();
 
2069
  free((char*) alias);
 
2070
  alias= NULL;
 
2071
  if (field)
1469
2072
  {
1470
 
    for (Field **ptr=table->field ; *ptr ; ptr++)
 
2073
    for (Field **ptr=field ; *ptr ; ptr++)
1471
2074
      delete *ptr;
1472
 
    table->field= 0;
 
2075
    field= 0;
1473
2076
  }
1474
 
  delete table->file;
1475
 
  table->file= 0;                               /* For easier errorchecking */
 
2077
  delete file;
 
2078
  file= 0;                              /* For easier errorchecking */
1476
2079
  if (free_share)
1477
2080
  {
1478
 
    if (table->s->tmp_table == NO_TMP_TABLE)
1479
 
      release_table_share(table->s, RELEASE_NORMAL);
 
2081
    if (s->tmp_table == NO_TMP_TABLE)
 
2082
      release_table_share(s, RELEASE_NORMAL);
1480
2083
    else
1481
 
      free_table_share(table->s);
 
2084
      free_table_share(s);
1482
2085
  }
1483
 
  free_root(&table->mem_root, MYF(0));
1484
 
  return(error);
 
2086
  free_root(&mem_root, MYF(0));
 
2087
 
 
2088
  return error;
1485
2089
}
1486
2090
 
1487
2091
 
1517
2121
  if (names)
1518
2122
  {
1519
2123
    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))) ||
 
2124
    lseek(file,64,SEEK_SET);
 
2125
    if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
1523
2126
        my_read(file, buf+a_length, (size_t) (length+names*4),
1524
2127
                MYF(MY_NABP)))
1525
2128
    {                                           /* purecov: inspected */
1559
2162
 
1560
2163
  if (*to)
1561
2164
    free(*to);
1562
 
  if (!(*to= (unsigned char*) my_malloc(length+1,MYF(MY_WME))) ||
 
2165
  if (!(*to= (unsigned char*) malloc(length+1)) ||
1563
2166
      my_read(file, *to, length,MYF(MY_NABP)))
1564
2167
  {
1565
2168
    if (*to)
1574
2177
 
1575
2178
        /* Add a new form to a form file */
1576
2179
 
1577
 
ulong make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
 
2180
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
1578
2181
                     const char *newname)
1579
2182
{
1580
2183
  uint32_t i,bufflength,maxlength,n_length,length,names;
1581
 
  ulong endpos,newpos;
 
2184
  off_t endpos,newpos;
1582
2185
  unsigned char buff[IO_SIZE];
1583
2186
  unsigned char *pos;
1584
2187
 
1585
 
  length=(uint) strlen(newname)+1;
 
2188
  length=(uint32_t) strlen(newname)+1;
1586
2189
  n_length=uint2korr(fileinfo+4);
1587
2190
  maxlength=uint2korr(fileinfo+6);
1588
2191
  names=uint2korr(fileinfo+8);
1592
2195
  {                                             /* Expand file */
1593
2196
    newpos+=IO_SIZE;
1594
2197
    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 */
 
2198
    endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
 
2199
    bufflength= (uint32_t) (endpos & (IO_SIZE-1));      /* IO_SIZE is a power of 2 */
1597
2200
 
1598
2201
    while (endpos > maxlength)
1599
2202
    {
1600
 
      my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0));
 
2203
      lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
1601
2204
      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));
 
2205
        return(0L);
 
2206
      lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
1605
2207
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1606
 
        return(0);
 
2208
        return(0);
1607
2209
      endpos-=bufflength; bufflength=IO_SIZE;
1608
2210
    }
1609
2211
    memset(buff, 0, IO_SIZE);                   /* Null new block */
1610
 
    my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0));
 
2212
    lseek(file,(ulong) maxlength,SEEK_SET);
1611
2213
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1612
 
        return(0L);
 
2214
      return(0L);
1613
2215
    maxlength+=IO_SIZE;                         /* Fix old ref */
1614
2216
    int2store(fileinfo+6,maxlength);
1615
 
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i-- ;
1616
 
         pos+=4)
 
2217
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
 
2218
         pos+=4)
1617
2219
    {
1618
2220
      endpos=uint4korr(pos)+IO_SIZE;
1619
2221
      int4store(pos,endpos);
1623
2225
  if (n_length == 1 )
1624
2226
  {                                             /* First name */
1625
2227
    length++;
1626
 
    strxmov((char*) buff,"/",newname,"/",NULL);
 
2228
    sprintf((char*)buff,"/%s/",newname);
1627
2229
  }
1628
2230
  else
1629
 
    strxmov((char*) buff,newname,"/",NULL); /* purecov: inspected */
1630
 
  my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0));
 
2231
    sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
 
2232
  lseek(file, 63 + n_length,SEEK_SET);
1631
2233
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1632
2234
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
1633
2235
                         names*4, MYF(MY_NABP+MY_WME))) ||
1636
2238
 
1637
2239
  int2store(fileinfo+8,names+1);
1638
2240
  int2store(fileinfo+4,n_length+length);
1639
 
  (void)ftruncate(file, newpos);/* Append file with '\0' */
 
2241
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
1640
2242
  return(newpos);
1641
2243
} /* make_new_entry */
1642
2244
 
1656
2258
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1657
2259
    else
1658
2260
    {
1659
 
      strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
2261
      sprintf(buff,"%s",share->normalized_path.str);
1660
2262
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1661
2263
               errortype, buff, db_errno);
1662
2264
    }
1665
2267
  {
1666
2268
    handler *file= 0;
1667
2269
    const char *datext= "";
1668
 
    
 
2270
 
1669
2271
    if (share->db_type() != NULL)
1670
2272
    {
1671
 
      if ((file= get_new_handler(share, current_thd->mem_root,
 
2273
      if ((file= get_new_handler(share, current_session->mem_root,
1672
2274
                                 share->db_type())))
1673
2275
      {
1674
2276
        if (!(datext= *file->bas_ext()))
1677
2279
    }
1678
2280
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1679
2281
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1680
 
    strxmov(buff, share->normalized_path.str, datext, NULL);
 
2282
    sprintf(buff,"%s%s", share->normalized_path.str,datext);
1681
2283
    my_error(err_no,errortype, buff, db_errno);
1682
2284
    delete file;
1683
2285
    break;
1684
2286
  }
1685
2287
  case 5:
1686
2288
  {
1687
 
    const char *csname= get_charset_name((uint) errarg);
 
2289
    const char *csname= get_charset_name((uint32_t) errarg);
1688
2290
    char tmp[10];
1689
2291
    if (!csname || csname[0] =='?')
1690
2292
    {
1692
2294
      csname= tmp;
1693
2295
    }
1694
2296
    my_printf_error(ER_UNKNOWN_COLLATION,
1695
 
                    _("Unknown collation '%s' in table '%-.64s' definition"), 
 
2297
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1696
2298
                    MYF(0), csname, share->table_name.str);
1697
2299
    break;
1698
2300
  }
1699
2301
  case 6:
1700
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
2302
    sprintf(buff,"%s",share->normalized_path.str);
1701
2303
    my_printf_error(ER_NOT_FORM_FILE,
1702
2304
                    _("Table '%-.64s' was created with a different version "
1703
 
                    "of MySQL and cannot be read"), 
 
2305
                    "of Drizzle and cannot be read"),
1704
2306
                    MYF(0), buff);
1705
2307
    break;
1706
2308
  case 8:
1707
2309
    break;
1708
2310
  default:                              /* Better wrong error than none */
1709
2311
  case 4:
1710
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
2312
    sprintf(buff,"%s",share->normalized_path.str);
1711
2313
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1712
2314
    break;
1713
2315
  }
1746
2348
    }
1747
2349
    else
1748
2350
      ptr++;
1749
 
    point_to_type->count= (uint) (*array - point_to_type->type_names);
 
2351
    point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
1750
2352
    point_to_type++;
1751
2353
    *((*array)++)= NULL;                /* End of type */
1752
2354
  }
1762
2364
    return 0;
1763
2365
  result->count=strings.elements;
1764
2366
  result->name="";
1765
 
  uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
 
2367
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
1766
2368
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1767
2369
    return 0;
1768
2370
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1778
2380
  return result;
1779
2381
}
1780
2382
 
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
2383
        /* Check that the integer is in the internal */
1817
2384
 
1818
2385
int set_zone(register int nr, int min_zone, int max_zone)
1838
2405
/*
1839
2406
  Store an SQL quoted string.
1840
2407
 
1841
 
  SYNOPSIS  
 
2408
  SYNOPSIS
1842
2409
    append_unescaped()
1843
2410
    res         result String
1844
2411
    pos         string to be quoted
1863
2430
    {
1864
2431
      res->append(pos, mblen);
1865
2432
      pos+= mblen;
 
2433
      if (pos >= end)
 
2434
        break;
1866
2435
      continue;
1867
2436
    }
1868
2437
#endif
1897
2466
}
1898
2467
 
1899
2468
 
1900
 
        /* Create a .frm file */
1901
 
 
1902
 
File create_frm(THD *thd, const char *name, const char *db,
1903
 
                const char *table, uint32_t reclength, unsigned char *fileinfo,
1904
 
                HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
1905
 
{
1906
 
  register File file;
1907
 
  ulong length;
1908
 
  unsigned char fill[IO_SIZE];
1909
 
  int create_flags= O_RDWR | O_TRUNC;
1910
 
  ulong key_comment_total_bytes= 0;
1911
 
  uint32_t i;
1912
 
 
1913
 
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1914
 
    create_flags|= O_EXCL | O_NOFOLLOW;
1915
 
 
1916
 
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
1917
 
  if (create_info->max_rows > UINT32_MAX)
1918
 
    create_info->max_rows= UINT32_MAX;
1919
 
  if (create_info->min_rows > UINT32_MAX)
1920
 
    create_info->min_rows= UINT32_MAX;
1921
 
 
1922
 
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
1923
 
  {
1924
 
    uint32_t key_length, tmp_key_length;
1925
 
    uint32_t tmp;
1926
 
    memset(fileinfo, 0, 64);
1927
 
    /* header */
1928
 
    fileinfo[0]=(unsigned char) 254;
1929
 
    fileinfo[1]= 1;
1930
 
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
1931
 
 
1932
 
    fileinfo[3]= (unsigned char) ha_legacy_type(
1933
 
          ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
1934
 
    fileinfo[4]=1;
1935
 
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
1936
 
    for (i= 0; i < keys; i++)
1937
 
    {
1938
 
      assert(test(key_info[i].flags & HA_USES_COMMENT) == 
1939
 
                 (key_info[i].comment.length > 0));
1940
 
      if (key_info[i].flags & HA_USES_COMMENT)
1941
 
        key_comment_total_bytes += 2 + key_info[i].comment.length;
1942
 
    }
1943
 
    /*
1944
 
      Keep in sync with pack_keys() in unireg.cc
1945
 
      For each key:
1946
 
      8 bytes for the key header
1947
 
      9 bytes for each key-part (MAX_REF_PARTS)
1948
 
      NAME_LEN bytes for the name
1949
 
      1 byte for the NAMES_SEP_CHAR (before the name)
1950
 
      For all keys:
1951
 
      6 bytes for the header
1952
 
      1 byte for the NAMES_SEP_CHAR (after the last name)
1953
 
      9 extra bytes (padding for safety? alignment?)
1954
 
      comments
1955
 
    */
1956
 
    key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
1957
 
                 key_comment_total_bytes);
1958
 
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
1959
 
                                  create_info->extra_size));
1960
 
    int4store(fileinfo+10,length);
1961
 
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
1962
 
    int2store(fileinfo+14,tmp_key_length);
1963
 
    int2store(fileinfo+16,reclength);
1964
 
    int4store(fileinfo+18,create_info->max_rows);
1965
 
    int4store(fileinfo+22,create_info->min_rows);
1966
 
    /* fileinfo[26] is set in mysql_create_frm() */
1967
 
    fileinfo[27]=2;                             // Use long pack-fields
1968
 
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
1969
 
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
1970
 
    int2store(fileinfo+30,create_info->table_options);
1971
 
    fileinfo[32]=0;                             // No filename anymore
1972
 
    fileinfo[33]=5;                             // Mark for 5.0 frm file
1973
 
    int4store(fileinfo+34,create_info->avg_row_length);
1974
 
    fileinfo[38]= (create_info->default_table_charset ?
1975
 
                   create_info->default_table_charset->number : 0);
1976
 
    fileinfo[39]= (unsigned char) create_info->page_checksum;
1977
 
    fileinfo[40]= (unsigned char) create_info->row_type;
1978
 
    /* Next few bytes where for RAID support */
1979
 
    fileinfo[41]= 0;
1980
 
    fileinfo[42]= 0;
1981
 
    int4store(fileinfo+43,create_info->block_size);
1982
 
 
1983
 
    fileinfo[44]= 0;
1984
 
    fileinfo[45]= 0;
1985
 
    fileinfo[46]= 0;
1986
 
    int4store(fileinfo+47, key_length);
1987
 
    tmp= DRIZZLE_VERSION_ID;          // Store to avoid warning from int4store
1988
 
    int4store(fileinfo+51, tmp);
1989
 
    int4store(fileinfo+55, create_info->extra_size);
1990
 
    /*
1991
 
      59-60 is reserved for extra_rec_buf_length,
1992
 
      61 for default_part_db_type
1993
 
    */
1994
 
    int2store(fileinfo+62, create_info->key_block_size);
1995
 
    memset(fill, 0, IO_SIZE);
1996
 
    for (; length > IO_SIZE ; length-= IO_SIZE)
1997
 
    {
1998
 
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
1999
 
      {
2000
 
        my_close(file,MYF(0));
2001
 
        my_delete(name,MYF(0));
2002
 
        return(-1);
2003
 
      }
2004
 
    }
2005
 
  }
2006
 
  else
2007
 
  {
2008
 
    if (my_errno == ENOENT)
2009
 
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
2010
 
    else
2011
 
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
2012
 
  }
2013
 
  return (file);
2014
 
} /* create_frm */
2015
 
 
2016
2469
/*
2017
2470
  Set up column usage bitmaps for a temporary table
2018
2471
 
2052
2505
  return;
2053
2506
}
2054
2507
 
2055
 
int
2056
 
rename_file_ext(const char * from,const char * to,const char * ext)
 
2508
int rename_file_ext(const char * from,const char * to,const char * ext)
2057
2509
{
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)));
 
2510
  string from_s, to_s;
 
2511
 
 
2512
  from_s.append(from);
 
2513
  from_s.append(ext);
 
2514
  to_s.append(to);
 
2515
  to_s.append(ext);
 
2516
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
2062
2517
}
2063
2518
 
2064
2519
 
2118
2573
  length= str.length();
2119
2574
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
2120
2575
    return NULL;
2121
 
  memcpy(to,str.ptr(),(uint) length);
 
2576
  memcpy(to,str.ptr(),(uint32_t) length);
2122
2577
  to[length]=0;
2123
2578
  return to;
2124
2579
}
2129
2584
    that are present in this value, returns the length of the value
2130
2585
*/
2131
2586
uint32_t calculate_key_len(Table *table, uint32_t key,
2132
 
                       const unsigned char *buf __attribute__((unused)),
 
2587
                       const unsigned char *,
2133
2588
                       key_part_map keypart_map)
2134
2589
{
2135
2590
  /* works only with key prefixes */
2206
2661
{
2207
2662
  uint32_t name_length= 0;  // name length in symbols
2208
2663
  bool last_char_is_space= true;
2209
 
  
 
2664
 
2210
2665
  while (*name)
2211
2666
  {
2212
2667
#if defined(USE_MB) && defined(USE_MB_IDENT)
2213
2668
    last_char_is_space= my_isspace(system_charset_info, *name);
2214
2669
    if (use_mb(system_charset_info))
2215
2670
    {
2216
 
      int len=my_ismbchar(system_charset_info, name, 
 
2671
      int len=my_ismbchar(system_charset_info, name,
2217
2672
                          name+system_charset_info->mbmaxlen);
2218
2673
      if (len)
2219
2674
      {
2238
2693
    name_length++;
2239
2694
  }
2240
2695
  /* Error if empty or too long column name */
2241
 
  return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
 
2696
  return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
2242
2697
}
2243
2698
 
2244
2699
 
2274
2729
    /* previous MySQL version */
2275
2730
    if (DRIZZLE_VERSION_ID > s->mysql_version)
2276
2731
    {
2277
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
 
2732
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2278
2733
                      alias, table_f_count, s->fields,
2279
2734
                      s->mysql_version, DRIZZLE_VERSION_ID);
2280
2735
      return(true);
2281
2736
    }
2282
2737
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
2283
2738
    {
2284
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
 
2739
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2285
2740
                      table_f_count, s->fields);
2286
2741
      return(true);
2287
2742
    }
2300
2755
    sql_type.length(0);
2301
2756
    if (i < s->fields)
2302
2757
    {
2303
 
      Field *field= this->field[i];
 
2758
      Field *cur_field= this->field[i];
2304
2759
 
2305
 
      if (strncmp(field->field_name, table_def->name.str,
 
2760
      if (strncmp(cur_field->field_name, table_def->name.str,
2306
2761
                  table_def->name.length))
2307
2762
      {
2308
2763
        /*
2310
2765
          Still this can be a sign of a tampered table, output an error
2311
2766
          to the error log.
2312
2767
        */
2313
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2768
        errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2314
2769
                        "expected column '%s' at position %d, found '%s'."),
2315
2770
                        s->db.str, alias, table_def->name.str, i,
2316
 
                        field->field_name);
 
2771
                        cur_field->field_name);
2317
2772
      }
2318
 
      field->sql_type(sql_type);
 
2773
      cur_field->sql_type(sql_type);
2319
2774
      /*
2320
2775
        Generally, if column types don't match, then something is
2321
2776
        wrong.
2336
2791
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2337
2792
                  table_def->type.length - 1))
2338
2793
      {
2339
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2794
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2795
                      _("Incorrect definition of table %s.%s: "
2340
2796
                        "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());
 
2797
                        "%s, found type %s."),
 
2798
                      s->db.str, alias,
 
2799
                      table_def->name.str, i, table_def->type.str,
 
2800
                      sql_type.c_ptr_safe());
2344
2801
        error= true;
2345
2802
      }
2346
 
      else if (table_def->cset.str && !field->has_charset())
 
2803
      else if (table_def->cset.str && !cur_field->has_charset())
2347
2804
      {
2348
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2805
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2806
                      _("Incorrect definition of table %s.%s: "
2349
2807
                        "expected the type of column '%s' at position %d "
2350
2808
                        "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);
 
2809
                        "character set."),
 
2810
                      s->db.str, alias,
 
2811
                      table_def->name.str, i, table_def->cset.str);
2353
2812
        error= true;
2354
2813
      }
2355
2814
      else if (table_def->cset.str &&
2356
 
               strcmp(field->charset()->csname, table_def->cset.str))
 
2815
               strcmp(cur_field->charset()->csname, table_def->cset.str))
2357
2816
      {
2358
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2817
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2818
                      _("Incorrect definition of table %s.%s: "
2359
2819
                        "expected the type of column '%s' at position %d "
2360
2820
                        "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);
 
2821
                        "character set '%s'."),
 
2822
                      s->db.str, alias,
 
2823
                      table_def->name.str, i, table_def->cset.str,
 
2824
                      cur_field->charset()->csname);
2364
2825
        error= true;
2365
2826
      }
2366
2827
    }
2367
2828
    else
2368
2829
    {
2369
 
      sql_print_error(_("Incorrect definition of table %s.%s: "
 
2830
      errmsg_printf(ERRMSG_LVL_ERROR,
 
2831
                    _("Incorrect definition of table %s.%s: "
2370
2832
                      "expected column '%s' at position %d to have type %s "
2371
2833
                      " but the column is not found."),
2372
 
                      s->db.str, alias,
2373
 
                      table_def->name.str, i, table_def->type.str);
 
2834
                    s->db.str, alias,
 
2835
                    table_def->name.str, i, table_def->type.str);
2374
2836
      error= true;
2375
2837
    }
2376
2838
  }
2388
2850
  DESCRIPTION
2389
2851
    Create Item_field object for each column in the table and
2390
2852
    initialize it with the corresponding Field. New items are
2391
 
    created in the current THD memory root.
 
2853
    created in the current Session memory root.
2392
2854
 
2393
2855
  RETURN VALUE
2394
2856
    0                    success
2474
2936
 
2475
2937
void TableList::cleanup_items()
2476
2938
{
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);
 
2939
}
 
2940
 
 
2941
 
 
2942
bool TableList::placeholder()
 
2943
{
 
2944
  return derived || schema_table || (create && !table->getDBStat()) || !table;
2484
2945
}
2485
2946
 
2486
2947
 
2666
3127
 
2667
3128
/*
2668
3129
  Tell handler we are going to call position() and rnd_pos() later.
2669
 
  
 
3130
 
2670
3131
  NOTES:
2671
3132
  This is needed for handlers that uses the primary key to find the
2672
3133
  row. In this case we have to extend the read bitmap with the primary
2742
3203
  KEY_PART_INFO *key_part_end= (key_part +
2743
3204
                                key_info[index].key_parts);
2744
3205
  for (;key_part != key_part_end; key_part++)
 
3206
  {
2745
3207
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
 
3208
    if (key_part->field->vcol_info &&
 
3209
        key_part->field->vcol_info->expr_item)
 
3210
      key_part->field->vcol_info->
 
3211
               expr_item->walk(&Item::register_field_in_bitmap,
 
3212
                               1, (unsigned char *) bitmap);
 
3213
  }
2746
3214
}
2747
3215
 
2748
3216
 
2799
3267
    }
2800
3268
    file->column_bitmaps_signal();
2801
3269
  }
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))
 
3270
 
2804
3271
  {
2805
3272
    /*
2806
3273
      If the handler has no cursor capabilites, or we have row-based
2851
3318
    }
2852
3319
    file->column_bitmaps_signal();
2853
3320
  }
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))
 
3321
 
2856
3322
  {
2857
3323
    /*
2858
3324
      If the handler has no cursor capabilites, or we have row-based
2868
3334
      file->column_bitmaps_signal();
2869
3335
    }
2870
3336
  }
 
3337
  /* Mark all virtual columns as writable */
 
3338
  mark_virtual_columns();
2871
3339
  return;
2872
3340
}
2873
3341
 
2883
3351
{
2884
3352
  if (found_next_number_field)
2885
3353
    mark_auto_increment_column();
2886
 
}
 
3354
  /* Mark all virtual columns as writable */
 
3355
  mark_virtual_columns();
 
3356
}
 
3357
 
 
3358
/*
 
3359
  @brief Update the write and read table bitmap to allow
 
3360
         using procedure save_in_field for all virtual columns
 
3361
         in the table.
 
3362
 
 
3363
  @return       void
 
3364
 
 
3365
  @detail
 
3366
    Each virtual field is set in the write column map.
 
3367
    All fields that the virtual columns are based on are set in the
 
3368
    read bitmap.
 
3369
*/
 
3370
 
 
3371
void Table::mark_virtual_columns(void)
 
3372
{
 
3373
  Field **vfield_ptr, *tmp_vfield;
 
3374
  bool bitmap_updated= false;
 
3375
 
 
3376
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
 
3377
  {
 
3378
    tmp_vfield= *vfield_ptr;
 
3379
    assert(tmp_vfield->vcol_info && tmp_vfield->vcol_info->expr_item);
 
3380
    tmp_vfield->vcol_info->expr_item->walk(&Item::register_field_in_read_map,
 
3381
                                           1, (unsigned char *) 0);
 
3382
    bitmap_set_bit(read_set, tmp_vfield->field_index);
 
3383
    bitmap_set_bit(write_set, tmp_vfield->field_index);
 
3384
    bitmap_updated= true;
 
3385
  }
 
3386
  if (bitmap_updated)
 
3387
    file->column_bitmaps_signal();
 
3388
}
 
3389
 
2887
3390
 
2888
3391
/*
2889
3392
  Cleanup this table for re-execution.
2892
3395
    TableList::reinit_before_use()
2893
3396
*/
2894
3397
 
2895
 
void TableList::reinit_before_use(THD *thd)
 
3398
void TableList::reinit_before_use(Session *session)
2896
3399
{
2897
3400
  /*
2898
3401
    Reset old pointers to TABLEs: they are not valid since the tables
2908
3411
  {
2909
3412
    embedded= parent_embedding;
2910
3413
    if (embedded->prep_on_expr)
2911
 
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
 
3414
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
2912
3415
    parent_embedding= embedded->embedding;
2913
3416
  }
2914
3417
  while (parent_embedding &&
2920
3423
 
2921
3424
  SYNOPSIS
2922
3425
    TableList::containing_subselect()
2923
 
 
 
3426
 
2924
3427
  RETURN
2925
3428
    Subselect item for the subquery that contains the FROM list
2926
3429
    this table is taken from if there is any
2929
3432
*/
2930
3433
 
2931
3434
Item_subselect *TableList::containing_subselect()
2932
 
{    
 
3435
{
2933
3436
  return (select_lex ? select_lex->master_unit()->item : 0);
2934
3437
}
2935
3438
 
2941
3444
      table         the Table to operate on.
2942
3445
 
2943
3446
  DESCRIPTION
2944
 
    The parser collects the index hints for each table in a "tagged list" 
 
3447
    The parser collects the index hints for each table in a "tagged list"
2945
3448
    (TableList::index_hints). Using the information in this tagged list
2946
 
    this function sets the members Table::keys_in_use_for_query, 
 
3449
    this function sets the members Table::keys_in_use_for_query,
2947
3450
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
2948
3451
    Table::force_index and Table::covering_keys.
2949
3452
 
2950
3453
    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 
 
3454
    and USE INDEX, so this is checked here. Then the FORCE INDEX list
2952
3455
    (if non-empty) is appended to the USE INDEX list and a flag is set.
2953
3456
 
2954
 
    Multiple hints of the same kind are processed so that each clause 
 
3457
    Multiple hints of the same kind are processed so that each clause
2955
3458
    is applied to what is computed in the previous clause.
2956
3459
    For example:
2957
3460
        USE INDEX (i1) USE INDEX (i2)
2958
3461
    is equivalent to
2959
3462
        USE INDEX (i1,i2)
2960
3463
    and means "consider only i1 and i2".
2961
 
        
 
3464
 
2962
3465
    Similarly
2963
3466
        USE INDEX () USE INDEX (i1)
2964
3467
    is equivalent to
2967
3470
 
2968
3471
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
2969
3472
    not an error.
2970
 
        
 
3473
 
2971
3474
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
2972
3475
    order:
2973
3476
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
2976
3479
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
2977
3480
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
2978
3481
 
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, 
 
3482
    As an optimization if there is a covering index, and we have
 
3483
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
2981
3484
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
2982
3485
 
2983
3486
  RETURN VALUE
2987
3490
bool TableList::process_index_hints(Table *tbl)
2988
3491
{
2989
3492
  /* initialize the result variables */
2990
 
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
 
3493
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
2991
3494
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
2992
3495
 
2993
3496
  /* index hint list processing */
2998
3501
    key_map index_group[INDEX_HINT_FORCE + 1];
2999
3502
    Index_hint *hint;
3000
3503
    int type;
3001
 
    bool have_empty_use_join= false, have_empty_use_order= false, 
 
3504
    bool have_empty_use_join= false, have_empty_use_order= false,
3002
3505
         have_empty_use_group= false;
3003
3506
    List_iterator <Index_hint> iter(*index_hints);
3004
3507
 
3036
3539
        continue;
3037
3540
      }
3038
3541
 
3039
 
      /* 
3040
 
        Check if an index with the given name exists and get his offset in 
3041
 
        the keys bitmask for the table 
 
3542
      /*
 
3543
        Check if an index with the given name exists and get his offset in
 
3544
        the keys bitmask for the table
3042
3545
      */
3043
3546
      if (tbl->s->keynames.type_names == 0 ||
3044
3547
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
3119
3622
  return length;
3120
3623
}
3121
3624
 
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
3625
/****************************************************************************
3166
3626
 Functions for creating temporary tables.
3167
3627
****************************************************************************/
3168
3628
 
3169
3629
 
3170
3630
/* Prototypes */
3171
 
void free_tmp_table(THD *thd, Table *entry);
 
3631
void free_tmp_table(Session *session, Table *entry);
3172
3632
 
3173
3633
/**
3174
3634
  Create field for temporary table from given field.
3175
3635
 
3176
 
  @param thd           Thread handler
 
3636
  @param session               Thread handler
3177
3637
  @param org_field    field from which new field will be created
3178
3638
  @param name         New field name
3179
3639
  @param table         Temporary table
3192
3652
    new_created field
3193
3653
*/
3194
3654
 
3195
 
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
 
3655
Field *create_tmp_field_from_field(Session *session, Field *org_field,
3196
3656
                                   const char *name, Table *table,
3197
3657
                                   Item_field *item, uint32_t convert_blob_length)
3198
3658
{
3199
3659
  Field *new_field;
3200
3660
 
3201
 
  /* 
3202
 
    Make sure that the blob fits into a Field_varstring which has 
3203
 
    2-byte lenght. 
 
3661
  /*
 
3662
    Make sure that the blob fits into a Field_varstring which has
 
3663
    2-byte lenght.
3204
3664
  */
3205
3665
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
3206
3666
      (org_field->flags & BLOB_FLAG))
3209
3669
                                   org_field->field_name, table->s,
3210
3670
                                   org_field->charset());
3211
3671
  else
3212
 
    new_field= org_field->new_field(thd->mem_root, table,
 
3672
    new_field= org_field->new_field(session->mem_root, table,
3213
3673
                                    table == org_field->table);
3214
3674
  if (new_field)
3215
3675
  {
3230
3690
  return new_field;
3231
3691
}
3232
3692
 
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
3693
 
3368
3694
/**
3369
3695
  Create field for information schema table.
3370
3696
 
3371
 
  @param thd            Thread handler
 
3697
  @param session                Thread handler
3372
3698
  @param table          Temporary table
3373
3699
  @param item           Item to create a field for
3374
3700
 
3378
3704
    new_created field
3379
3705
*/
3380
3706
 
3381
 
Field *create_tmp_field_for_schema(THD *thd __attribute__((unused)),
3382
 
                                   Item *item, Table *table)
 
3707
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
3383
3708
{
3384
3709
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
3385
3710
  {
3400
3725
 
3401
3726
 
3402
3727
/**
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
3728
  Create a temp table according to a field list.
3528
3729
 
3529
3730
  Given field pointers are changed to point at tmp_table for
3534
3735
  corresponding Item_field items, pointing at the fields in the
3535
3736
  temporary table, unless this was prohibited by true
3536
3737
  value of argument save_sum_fields. The Item_field objects
3537
 
  are created in THD memory root.
 
3738
  are created in Session memory root.
3538
3739
 
3539
 
  @param thd                  thread handle
 
3740
  @param session                  thread handle
3540
3741
  @param param                a description used as input to create the table
3541
3742
  @param fields               list of items that will be used to define
3542
3743
                              column types of the table (also see NOTES)
3552
3753
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
3553
3754
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
3554
3755
#define RATIO_TO_PACK_ROWS             2
3555
 
#define MIN_STRING_LENGTH_TO_PACK_ROWS   10
3556
3756
 
3557
3757
Table *
3558
 
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
 
3758
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
3559
3759
                 order_st *group, bool distinct, bool save_sum_fields,
3560
3760
                 uint64_t select_options, ha_rows rows_limit,
3561
3761
                 char *table_alias)
3586
3786
  uint32_t total_uneven_bit_length= 0;
3587
3787
  bool force_copy_fields= param->force_copy_fields;
3588
3788
 
3589
 
  status_var_increment(thd->status_var.created_tmp_tables);
 
3789
  status_var_increment(session->status_var.created_tmp_tables);
3590
3790
 
3591
3791
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
3592
3792
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
3593
3793
 
3594
3794
  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);
 
3795
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
 
3796
            (unsigned long)current_pid, temp_pool_slot);
3597
3797
  else
3598
3798
  {
3599
3799
    /* 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++);
 
3800
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
3801
            session->thread_id, session->tmp_table++);
3602
3802
  }
3603
3803
 
3604
3804
  /*
3605
3805
    No need to change table name to lower case as we are only creating
3606
3806
    MyISAM or HEAP tables here
3607
3807
  */
3608
 
  fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3808
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
3609
3809
 
3610
3810
 
3611
3811
  if (group)
3637
3837
    When loose index scan is employed as access method, it already
3638
3838
    computes all groups and the result of all aggregate functions. We
3639
3839
    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
 
3840
    functions Tmp_Table_Param::items_to_copy, so that the values of
3641
3841
    these items are stored in the temporary table.
3642
3842
  */
3643
3843
  if (param->precomputed_group_by)
3644
3844
    copy_func_count+= param->sum_func_count;
3645
 
  
 
3845
 
3646
3846
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
3647
3847
 
3648
3848
  if (!multi_alloc_root(&own_root,
3650
3850
                        &share, sizeof(*share),
3651
3851
                        &reg_field, sizeof(Field*) * (field_count+1),
3652
3852
                        &default_field, sizeof(Field*) * (field_count),
3653
 
                        &blob_field, sizeof(uint)*(field_count+1),
 
3853
                        &blob_field, sizeof(uint32_t)*(field_count+1),
3654
3854
                        &from_field, sizeof(Field*)*field_count,
3655
3855
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
3656
3856
                        &param->keyinfo, sizeof(*param->keyinfo),
3658
3858
                        sizeof(*key_part_info)*(param->group_parts+1),
3659
3859
                        &param->start_recinfo,
3660
3860
                        sizeof(*param->recinfo)*(field_count*2+4),
3661
 
                        &tmpname, (uint) strlen(path)+1,
 
3861
                        &tmpname, (uint32_t) strlen(path)+1,
3662
3862
                        &group_buff, (group && ! using_unique_constraint ?
3663
3863
                                      param->group_length : 0),
3664
3864
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3668
3868
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3669
3869
    return(NULL);                               /* purecov: inspected */
3670
3870
  }
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]))
 
3871
  /* Copy_field belongs to Tmp_Table_Param, allocate it in Session mem_root */
 
3872
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
3673
3873
  {
3674
3874
    if (temp_pool_slot != MY_BIT_NONE)
3675
3875
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3677
3877
    return(NULL);                               /* purecov: inspected */
3678
3878
  }
3679
3879
  param->items_to_copy= copy_func;
3680
 
  my_stpcpy(tmpname,path);
 
3880
  strcpy(tmpname,path);
3681
3881
  /* make table according to fields */
3682
3882
 
3683
3883
  memset(table, 0, sizeof(*table));
3686
3886
  memset(from_field, 0, sizeof(Field*)*field_count);
3687
3887
 
3688
3888
  table->mem_root= own_root;
3689
 
  mem_root_save= thd->mem_root;
3690
 
  thd->mem_root= &table->mem_root;
 
3889
  mem_root_save= session->mem_root;
 
3890
  session->mem_root= &table->mem_root;
3691
3891
 
3692
3892
  table->field=reg_field;
3693
3893
  table->alias= table_alias;
3696
3896
  table->map=1;
3697
3897
  table->temp_pool_slot = temp_pool_slot;
3698
3898
  table->copy_blobs= 1;
3699
 
  table->in_use= thd;
 
3899
  table->in_use= session;
3700
3900
  table->quick_keys.init();
3701
3901
  table->covering_keys.init();
3702
3902
  table->keys_in_use_for_query.init();
3703
3903
 
3704
3904
  table->setShare(share);
3705
 
  init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
 
3905
  init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
3706
3906
  share->blob_field= blob_field;
3707
3907
  share->blob_ptr_size= portable_sizeof_char_ptr;
3708
3908
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
3754
3954
        if (!arg->const_item())
3755
3955
        {
3756
3956
          Field *new_field=
3757
 
            create_tmp_field(thd, table, arg, arg->type(), &copy_func,
 
3957
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
3758
3958
                             tmp_from_field, &default_field[fieldnr],
3759
3959
                             group != 0,not_all_columns,
3760
3960
                             distinct, 0,
3774
3974
            string_count++;
3775
3975
            string_total_length+= new_field->pack_length();
3776
3976
          }
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;
 
3977
          session->mem_root= mem_root_save;
 
3978
          session->change_item_tree(argp, new Item_field(new_field));
 
3979
          session->mem_root= &table->mem_root;
3780
3980
          if (!(new_field->flags & NOT_NULL_FLAG))
3781
3981
          {
3782
3982
            null_count++;
3803
4003
        that in the later case group is set to the row pointer.
3804
4004
      */
3805
4005
      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,
 
4006
        create_tmp_field_for_schema(session, item, table) :
 
4007
        create_tmp_field(session, table, item, type, &copy_func,
3808
4008
                         tmp_from_field, &default_field[fieldnr],
3809
4009
                         group != 0,
3810
4010
                         !force_copy_fields &&
3822
4022
 
3823
4023
      if (!new_field)
3824
4024
      {
3825
 
        if (thd->is_fatal_error)
 
4025
        if (session->is_fatal_error)
3826
4026
          goto err;                             // Got OOM
3827
4027
        continue;                               // Some kindf of const item
3828
4028
      }
3860
4060
      null_count= 0;
3861
4061
    }
3862
4062
  }
3863
 
  assert(fieldnr == (uint) (reg_field - table->field));
3864
 
  assert(field_count >= (uint) (reg_field - table->field));
 
4063
  assert(fieldnr == (uint32_t) (reg_field - table->field));
 
4064
  assert(field_count >= (uint32_t) (reg_field - table->field));
3865
4065
  field_count= fieldnr;
3866
4066
  *reg_field= 0;
3867
4067
  *blob_field= 0;                               // End marker
3873
4073
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3874
4074
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
3875
4075
  {
3876
 
    share->db_plugin= ha_lock_engine(0, myisam_hton);
 
4076
    share->db_plugin= ha_lock_engine(0, myisam_engine);
3877
4077
    table->file= get_new_handler(share, &table->mem_root,
3878
4078
                                 share->db_type());
3879
4079
    if (group &&
3883
4083
  }
3884
4084
  else
3885
4085
  {
3886
 
    share->db_plugin= ha_lock_engine(0, heap_hton);
 
4086
    share->db_plugin= ha_lock_engine(0, heap_engine);
3887
4087
    table->file= get_new_handler(share, &table->mem_root,
3888
4088
                                 share->db_type());
3889
4089
  }
3924
4124
    share->default_values= table->record[1]+alloc_length;
3925
4125
  }
3926
4126
  copy_func[0]=0;                               // End marker
3927
 
  param->func_count= copy_func - param->items_to_copy; 
 
4127
  param->func_count= copy_func - param->items_to_copy;
3928
4128
 
3929
4129
  table->setup_tmp_table_column_bitmaps(bitmaps);
3930
4130
 
3984
4184
    */
3985
4185
    if (default_field[i] && default_field[i]->ptr)
3986
4186
    {
3987
 
      /* 
 
4187
      /*
3988
4188
         default_field[i] is set only in the cases  when 'field' can
3989
4189
         inherit the default value that is defined for the field referred
3990
4190
         by the Item_field object from which 'field' has been created.
4003
4203
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
4004
4204
      }
4005
4205
      orig_field->move_field_offset(-diff);     // Back to record[0]
4006
 
    } 
 
4206
    }
4007
4207
 
4008
4208
    if (from_field[i])
4009
4209
    {                                           /* Not a table Item */
4030
4230
  param->recinfo=recinfo;
4031
4231
  store_record(table,s->default_values);        // Make empty default record
4032
4232
 
4033
 
  if (thd->variables.tmp_table_size == ~ (uint64_t) 0)          // No limit
 
4233
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
4034
4234
    share->max_rows= ~(ha_rows) 0;
4035
4235
  else
4036
 
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
4037
 
                                 cmin(thd->variables.tmp_table_size,
4038
 
                                     thd->variables.max_heap_table_size) :
4039
 
                                 thd->variables.tmp_table_size) /
 
4236
    share->max_rows= (ha_rows) (((share->db_type() == heap_engine) ?
 
4237
                                 cmin(session->variables.tmp_table_size,
 
4238
                                     session->variables.max_heap_table_size) :
 
4239
                                 session->variables.tmp_table_size) /
4040
4240
                                 share->reclength);
4041
 
  set_if_bigger(share->max_rows,1);             // For dummy start options
 
4241
  set_if_bigger(share->max_rows,(ha_rows)1);    // For dummy start options
4042
4242
  /*
4043
4243
    Push the LIMIT clause to the temporary table creation, so that we
4044
4244
    materialize only up to 'rows_limit' records instead of all result records.
4080
4280
      if (!using_unique_constraint)
4081
4281
      {
4082
4282
        cur_group->buff=(char*) group_buff;
4083
 
        if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
 
4283
        if (!(cur_group->field= field->new_key_field(session->mem_root,table,
4084
4284
                                                     group_buff +
4085
4285
                                                     test(maybe_null),
4086
4286
                                                     field->null_ptr,
4096
4296
          */
4097
4297
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
4098
4298
          key_part_info->null_bit=field->null_bit;
4099
 
          key_part_info->null_offset= (uint) (field->null_ptr -
 
4299
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
4100
4300
                                              (unsigned char*) table->record[0]);
4101
4301
          cur_group->buff++;                        // Pointer to field data
4102
4302
          group_buff++;                         // Skipp null flag
4158
4358
                                                (uint32_t) key_part_info->length,
4159
4359
                                                0,
4160
4360
                                                (unsigned char*) 0,
4161
 
                                                (uint) 0,
 
4361
                                                (uint32_t) 0,
4162
4362
                                                Field::NONE,
4163
 
                                                NULL, 
 
4363
                                                NULL,
4164
4364
                                                table->s,
4165
4365
                                                &my_charset_bin);
4166
4366
      if (!key_part_info->field)
4191
4391
 
4192
4392
      if ((*reg_field)->real_maybe_null())
4193
4393
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
4194
 
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB || 
 
4394
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB ||
4195
4395
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
4196
4396
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
4197
4397
 
4204
4404
    }
4205
4405
  }
4206
4406
 
4207
 
  if (thd->is_fatal_error)                              // If end of memory
 
4407
  if (session->is_fatal_error)                          // If end of memory
4208
4408
    goto err;                                    /* purecov: inspected */
4209
4409
  share->db_record_offset= 1;
4210
 
  if (share->db_type() == myisam_hton)
 
4410
  if (share->db_type() == myisam_engine)
4211
4411
  {
4212
4412
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
4213
4413
                                       &param->recinfo, select_options))
4216
4416
  if (table->open_tmp_table())
4217
4417
    goto err;
4218
4418
 
4219
 
  thd->mem_root= mem_root_save;
 
4419
  session->mem_root= mem_root_save;
4220
4420
 
4221
4421
  return(table);
4222
4422
 
4223
4423
err:
4224
 
  thd->mem_root= mem_root_save;
4225
 
  table->free_tmp_table(thd);                    /* purecov: inspected */
 
4424
  session->mem_root= mem_root_save;
 
4425
  table->free_tmp_table(session);                    /* purecov: inspected */
4226
4426
  if (temp_pool_slot != MY_BIT_NONE)
4227
4427
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4228
4428
  return(NULL);                         /* purecov: inspected */
4239
4439
    The sole purpose of this Table object is to use the power of Field
4240
4440
    class to read/write data to/from table->record[0]. Then one can store
4241
4441
    the record in any container (RB tree, hash, etc).
4242
 
    The table is created in THD mem_root, so are the table's fields.
 
4442
    The table is created in Session mem_root, so are the table's fields.
4243
4443
    Consequently, if you don't BLOB fields, you don't need to free it.
4244
4444
 
4245
 
  @param thd         connection handle
 
4445
  @param session         connection handle
4246
4446
  @param field_list  list of column definitions
4247
4447
 
4248
4448
  @return
4249
4449
    0 if out of memory, Table object in case of success
4250
4450
*/
4251
4451
 
4252
 
Table *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
 
4452
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4253
4453
{
4254
4454
  uint32_t field_count= field_list.elements;
4255
4455
  uint32_t blob_count= 0;
4263
4463
  Table *table;
4264
4464
  TABLE_SHARE *share;
4265
4465
 
4266
 
  if (!multi_alloc_root(thd->mem_root,
 
4466
  if (!multi_alloc_root(session->mem_root,
4267
4467
                        &table, sizeof(*table),
4268
4468
                        &share, sizeof(*share),
4269
4469
                        &field, (field_count + 1) * sizeof(Field*),
4270
 
                        &blob_field, (field_count+1) *sizeof(uint),
 
4470
                        &blob_field, (field_count+1) *sizeof(uint32_t),
4271
4471
                        &bitmaps, bitmap_buffer_size(field_count)*2,
4272
4472
                        NULL))
4273
4473
    return 0;
4285
4485
  List_iterator_fast<Create_field> it(field_list);
4286
4486
  while ((cdef= it++))
4287
4487
  {
4288
 
    *field= make_field(share, 0, cdef->length,
 
4488
    *field= make_field(share, NULL, 0, cdef->length,
4289
4489
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4290
4490
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
4291
4491
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
4299
4499
      null_count++;
4300
4500
 
4301
4501
    if ((*field)->flags & BLOB_FLAG)
4302
 
      share->blob_field[blob_count++]= (uint) (field - table->field);
 
4502
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
4303
4503
 
4304
4504
    field++;
4305
4505
  }
4310
4510
  null_pack_length= (null_count + 7)/8;
4311
4511
  share->reclength= record_length + null_pack_length;
4312
4512
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4313
 
  table->record[0]= (unsigned char*) thd->alloc(share->rec_buff_length);
 
4513
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4314
4514
  if (!table->record[0])
4315
4515
    goto error;
4316
4516
 
4321
4521
    share->null_bytes= null_pack_length;
4322
4522
  }
4323
4523
 
4324
 
  table->in_use= thd;           /* field->reset() may access table->in_use */
 
4524
  table->in_use= session;           /* field->reset() may access table->in_use */
4325
4525
  {
4326
4526
    /* Set up field pointers */
4327
4527
    unsigned char *null_pos= table->record[0];
4380
4580
      start_recinfo   MyISAM's column descriptions
4381
4581
      recinfo INOUT   End of MyISAM's column descriptions
4382
4582
      options         Option bits
4383
 
   
 
4583
 
4384
4584
  DESCRIPTION
4385
4585
    Create a MyISAM temporary table according to passed description. The is
4386
4586
    assumed to have one unique index or constraint.
4391
4591
         when there are many nullable columns)
4392
4592
      2. Table columns
4393
4593
      3. One free MI_COLUMNDEF element (*recinfo points here)
4394
 
   
 
4594
 
4395
4595
    This function may use the free element to create hash column for unique
4396
4596
    constraint.
4397
4597
 
4400
4600
     true  - Error
4401
4601
*/
4402
4602
 
4403
 
bool Table::create_myisam_tmp_table(KEY *keyinfo, 
 
4603
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4404
4604
                                    MI_COLUMNDEF *start_recinfo,
4405
 
                                    MI_COLUMNDEF **recinfo, 
 
4605
                                    MI_COLUMNDEF **recinfo,
4406
4606
                                    uint64_t options)
4407
4607
{
4408
4608
  int error;
4449
4649
    }
4450
4650
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4451
4651
    {
4452
 
      Field *field=keyinfo->key_part[i].field;
 
4652
      Field *key_field=keyinfo->key_part[i].field;
4453
4653
      seg->flag=     0;
4454
 
      seg->language= field->charset()->number;
 
4654
      seg->language= key_field->charset()->number;
4455
4655
      seg->length=   keyinfo->key_part[i].length;
4456
4656
      seg->start=    keyinfo->key_part[i].offset;
4457
 
      if (field->flags & BLOB_FLAG)
 
4657
      if (key_field->flags & BLOB_FLAG)
4458
4658
      {
4459
4659
        seg->type=
4460
4660
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4461
4661
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4462
 
        seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
 
4662
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
4663
                                  - share->blob_ptr_size);
4463
4664
        seg->flag= HA_BLOB_PART;
4464
4665
        seg->length=0;                  // Whole blob in unique constraint
4465
4666
      }
4467
4668
      {
4468
4669
        seg->type= keyinfo->key_part[i].type;
4469
4670
      }
4470
 
      if (!(field->flags & NOT_NULL_FLAG))
 
4671
      if (!(key_field->flags & NOT_NULL_FLAG))
4471
4672
      {
4472
 
        seg->null_bit= field->null_bit;
4473
 
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) record[0]);
 
4673
        seg->null_bit= key_field->null_bit;
 
4674
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
4474
4675
        /*
4475
4676
          We are using a GROUP BY on something that contains NULL
4476
4677
          In this case we have to tell MyISAM that two NULL should
4489
4690
    create_info.data_file_length= ~(uint64_t) 0;
4490
4691
 
4491
4692
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4492
 
                       (uint) (*recinfo-start_recinfo),
 
4693
                       (uint32_t) (*recinfo-start_recinfo),
4493
4694
                       start_recinfo,
4494
4695
                       share->uniques, &uniquedef,
4495
4696
                       &create_info,
4507
4708
}
4508
4709
 
4509
4710
 
4510
 
void Table::free_tmp_table(THD *thd)
 
4711
void Table::free_tmp_table(Session *session)
4511
4712
{
4512
4713
  MEM_ROOT own_root= mem_root;
4513
4714
  const char *save_proc_info;
4514
4715
 
4515
 
  save_proc_info=thd->get_proc_info();
4516
 
  thd_proc_info(thd, "removing tmp table");
 
4716
  save_proc_info=session->get_proc_info();
 
4717
  session->set_proc_info("removing tmp table");
 
4718
 
 
4719
  // Release latches since this can take a long time
 
4720
  ha_release_temporary_latches(session);
4517
4721
 
4518
4722
  if (file)
4519
4723
  {
4532
4736
  if (temp_pool_slot != MY_BIT_NONE)
4533
4737
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4534
4738
 
4535
 
  plugin_unlock(0, s->db_plugin);
4536
 
 
4537
4739
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4538
 
  thd_proc_info(thd, save_proc_info);
 
4740
  session->set_proc_info(save_proc_info);
4539
4741
 
4540
4742
  return;
4541
4743
}
4545
4747
  to this.
4546
4748
*/
4547
4749
 
4548
 
bool create_myisam_from_heap(THD *thd, Table *table,
 
4750
bool create_myisam_from_heap(Session *session, Table *table,
4549
4751
                             MI_COLUMNDEF *start_recinfo,
4550
 
                             MI_COLUMNDEF **recinfo, 
 
4752
                             MI_COLUMNDEF **recinfo,
4551
4753
                             int error, bool ignore_last_dupp_key_error)
4552
4754
{
4553
4755
  Table new_table;
4555
4757
  const char *save_proc_info;
4556
4758
  int write_err;
4557
4759
 
4558
 
  if (table->s->db_type() != heap_hton || 
 
4760
  if (table->s->db_type() != heap_engine ||
4559
4761
      error != HA_ERR_RECORD_FILE_FULL)
4560
4762
  {
4561
4763
    table->file->print_error(error,MYF(0));
4562
4764
    return(1);
4563
4765
  }
 
4766
 
 
4767
  // Release latches since this can take a long time
 
4768
  ha_release_temporary_latches(session);
 
4769
 
4564
4770
  new_table= *table;
4565
4771
  share= *table->s;
4566
4772
  new_table.s= &share;
4567
 
  new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
 
4773
  new_table.s->db_plugin= ha_lock_engine(session, myisam_engine);
4568
4774
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4569
4775
                                        new_table.s->db_type())))
4570
4776
    return(1);                          // End of memory
4571
4777
 
4572
 
  save_proc_info=thd->get_proc_info();
4573
 
  thd_proc_info(thd, "converting HEAP to MyISAM");
 
4778
  save_proc_info=session->get_proc_info();
 
4779
  session->set_proc_info("converting HEAP to MyISAM");
4574
4780
 
4575
4781
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4576
 
                                        recinfo, thd->lex->select_lex.options | 
4577
 
                                        thd->options))
 
4782
                                        recinfo, session->lex->select_lex.options |
 
4783
                                        session->options))
4578
4784
    goto err2;
4579
4785
  if (new_table.open_tmp_table())
4580
4786
    goto err1;
4588
4794
    new_table.no_rows=1;
4589
4795
  }
4590
4796
 
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
4797
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4600
4798
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4601
 
#endif
4602
4799
 
4603
4800
  /*
4604
4801
    copy all old rows from heap table to MyISAM table
4624
4821
  (void) table->file->close();                  // This deletes the table !
4625
4822
  delete table->file;
4626
4823
  table->file=0;
4627
 
  plugin_unlock(0, table->s->db_plugin);
4628
 
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
 
4824
  share.db_plugin= plugin_lock(0, &share.db_plugin);
4629
4825
  new_table.s= table->s;                       // Keep old share
4630
4826
  *table= new_table;
4631
4827
  *table->s= share;
4632
 
  
 
4828
 
4633
4829
  table->file->change_table_ptr(table, table->s);
4634
4830
  table->use_all_columns();
4635
4831
  if (save_proc_info)
4637
4833
    const char *new_proc_info=
4638
4834
      (!strcmp(save_proc_info,"Copying to tmp table") ?
4639
4835
      "Copying to tmp table on disk" : save_proc_info);
4640
 
    thd_proc_info(thd, new_proc_info);
 
4836
    session->set_proc_info(new_proc_info);
4641
4837
  }
4642
4838
  return(0);
4643
4839
 
4649
4845
  new_table.file->ha_delete_table(new_table.s->table_name.str);
4650
4846
 err2:
4651
4847
  delete new_table.file;
4652
 
  thd_proc_info(thd, save_proc_info);
 
4848
  session->set_proc_info(save_proc_info);
4653
4849
  table->mem_root= new_table.mem_root;
4654
4850
  return(1);
4655
4851
}
4749
4945
    print them to the .err log
4750
4946
  */
4751
4947
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
4752
 
    sql_print_error(_("Got error %d when reading table '%s'"),
 
4948
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
4753
4949
                    error, s->path.str);
4754
4950
  file->print_error(error,MYF(0));
4755
4951
 
4757
4953
}
4758
4954
 
4759
4955
 
 
4956
/*
 
4957
  Calculate data for each virtual field marked for write in the
 
4958
  corresponding column map.
 
4959
 
 
4960
  SYNOPSIS
 
4961
    update_virtual_fields_marked_for_write()
 
4962
    table                  The Table object
 
4963
    ignore_stored          Indication whether physically stored virtual
 
4964
                           fields do not need updating.
 
4965
                           This value is false when during INSERT and UPDATE
 
4966
                           and true in all other cases.
 
4967
 
 
4968
  RETURN
 
4969
    0  - Success
 
4970
    >0 - Error occurred during the generation/calculation of a virtual field value
 
4971
 
 
4972
*/
 
4973
 
 
4974
int update_virtual_fields_marked_for_write(Table *table,
 
4975
                                           bool ignore_stored)
 
4976
{
 
4977
  Field **vfield_ptr, *vfield;
 
4978
  int error= 0;
 
4979
  if ((not table) or (not table->vfield))
 
4980
    return(0);
 
4981
 
 
4982
  /* Iterate over virtual fields in the table */
 
4983
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
 
4984
  {
 
4985
    vfield= (*vfield_ptr);
 
4986
    assert(vfield->vcol_info && vfield->vcol_info->expr_item);
 
4987
    /*
 
4988
      Only update those fields that are marked in the write_set bitmap
 
4989
      and not _already_ physically stored in the database.
 
4990
    */
 
4991
    if (bitmap_is_set(table->write_set, vfield->field_index) &&
 
4992
        (not (ignore_stored && vfield->is_stored))
 
4993
       )
 
4994
    {
 
4995
      /* Generate the actual value of the virtual fields */
 
4996
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
 
4997
    }
 
4998
  }
 
4999
  return(0);
 
5000
}
 
5001
 
 
5002
 
 
5003
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
 
5004
{
 
5005
  used_fields= 0;
 
5006
  const_table= 0;
 
5007
  null_row= 0;
 
5008
  status= STATUS_NO_RECORD;
 
5009
  maybe_null= table_list->outer_join;
 
5010
  TableList *embedding= table_list->embedding;
 
5011
  while (!maybe_null && embedding)
 
5012
  {
 
5013
    maybe_null= embedding->outer_join;
 
5014
    embedding= embedding->embedding;
 
5015
  }
 
5016
  tablenr= table_number;
 
5017
  map= (table_map) 1 << table_number;
 
5018
  force_index= table_list->force_index;
 
5019
  covering_keys= s->keys_for_keyread;
 
5020
  merge_keys.clear_all();
 
5021
}
 
5022
 
 
5023
 
4760
5024
/*****************************************************************************
4761
5025
** Instansiate templates
4762
5026
*****************************************************************************/