~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-05-15 17:06:35 UTC
  • mto: This revision was merged to the branch mainline in revision 1023.
  • Revision ID: brian@gaz-20090515170635-croy1u63a3gqdn9n
Dead convert functions for character sets.

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/table_list.h>
 
29
#include <drizzled/session.h>
 
30
#include <drizzled/sql_base.h>
 
31
#include <drizzled/field/blob.h>
 
32
#include <drizzled/field/varstring.h>
 
33
#include <drizzled/field/double.h>
 
34
#include <string>
 
35
 
 
36
#include <drizzled/unireg.h>
 
37
#include <drizzled/message/table.pb.h>
 
38
 
 
39
#include <drizzled/item/string.h>
 
40
#include <drizzled/item/int.h>
 
41
#include <drizzled/item/decimal.h>
 
42
#include <drizzled/item/float.h>
 
43
#include <drizzled/item/null.h>
 
44
 
 
45
 
 
46
using namespace std;
27
47
 
28
48
/* Functions defined in this file */
29
49
 
30
 
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
 
50
void open_table_error(TableShare *share, int error, int db_errno,
31
51
                      myf errortype, int errarg);
32
 
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
33
 
                           unsigned char *head, File file);
34
52
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);
 
53
                              uint32_t types, char **names);
37
54
 
38
55
/*************************************************************************/
39
56
 
40
57
/* Get column name from column hash */
41
58
 
42
 
static unsigned char *get_field_name(Field **buff, size_t *length,
43
 
                             bool not_used __attribute__((unused)))
 
59
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
44
60
{
45
 
  *length= (uint) strlen((*buff)->field_name);
 
61
  *length= (uint32_t) strlen((*buff)->field_name);
46
62
  return (unsigned char*) (*buff)->field_name;
47
63
}
48
64
 
56
72
 
57
73
  DESCRIPTION
58
74
    Checks file name part starting with the rightmost '.' character,
59
 
    and returns it if it is equal to '.frm'. 
 
75
    and returns it if it is equal to '.frm'.
60
76
 
61
77
  TODO
62
78
    It is a good idea to get rid of this function modifying the code
71
87
char *fn_rext(char *name)
72
88
{
73
89
  char *res= strrchr(name, '.');
74
 
  if (res && !strcmp(res, reg_ext))
 
90
  if (res && !strcmp(res, ".dfe"))
75
91
    return res;
76
92
  return name + strlen(name);
77
93
}
81
97
  assert(db != NULL);
82
98
  assert(name != NULL);
83
99
 
84
 
  if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
 
100
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
85
101
      (my_strcasecmp(system_charset_info,
86
 
                    INFORMATION_SCHEMA_NAME.str,
 
102
                    INFORMATION_SCHEMA_NAME.c_str(),
87
103
                    db->str) == 0))
88
104
  {
89
105
    return TABLE_CATEGORY_INFORMATION;
94
110
 
95
111
 
96
112
/*
97
 
  Allocate a setup TABLE_SHARE structure
 
113
  Allocate a setup TableShare structure
98
114
 
99
115
  SYNOPSIS
100
116
    alloc_table_share()
107
123
    #  Share
108
124
*/
109
125
 
110
 
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
 
126
TableShare *alloc_table_share(TableList *table_list, char *key,
111
127
                               uint32_t key_length)
112
128
{
113
129
  MEM_ROOT mem_root;
114
 
  TABLE_SHARE *share;
 
130
  TableShare *share;
115
131
  char *key_buff, *path_buff;
116
132
  char path[FN_REFLEN];
117
133
  uint32_t path_length;
132
148
 
133
149
    share->path.str= path_buff;
134
150
    share->path.length= path_length;
135
 
    my_stpcpy(share->path.str, path);
 
151
    strcpy(share->path.str, path);
136
152
    share->normalized_path.str=    share->path.str;
137
153
    share->normalized_path.length= path_length;
138
154
 
139
155
    share->version=       refresh_version;
140
156
 
141
 
    /*
142
 
      This constant is used to mark that no table map version has been
143
 
      assigned.  No arithmetic is done on the value: it will be
144
 
      overwritten with a value taken from DRIZZLE_BIN_LOG.
145
 
    */
146
 
    share->table_map_version= UINT64_MAX;
147
 
 
148
 
    /*
149
 
      Since alloc_table_share() can be called without any locking (for
150
 
      example, ha_create_table... functions), we do not assign a table
151
 
      map id here.  Instead we assign a value that is not used
152
 
      elsewhere, and then assign a table map id inside open_table()
153
 
      under the protection of the LOCK_open mutex.
154
 
    */
155
 
    share->table_map_id= UINT32_MAX;
156
 
    share->cached_row_logging_check= -1;
157
 
 
158
157
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
159
158
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
160
159
    pthread_cond_init(&share->cond, NULL);
163
162
}
164
163
 
165
164
 
166
 
/*
167
 
  Initialize share for temporary tables
168
 
 
169
 
  SYNOPSIS
170
 
    init_tmp_table_share()
171
 
    thd         thread handle
172
 
    share       Share to fill
173
 
    key         Table_cache_key, as generated from create_table_def_key.
174
 
                must start with db name.    
175
 
    key_length  Length of key
176
 
    table_name  Table name
177
 
    path        Path to file (possible in lower case) without .frm
178
 
 
179
 
  NOTES
180
 
    This is different from alloc_table_share() because temporary tables
181
 
    don't have to be shared between threads or put into the table def
182
 
    cache, so we can do some things notable simpler and faster
183
 
 
184
 
    If table is not put in thd->temporary_tables (happens only when
185
 
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
186
 
    use key_length= 0 as neither table_cache_key or key_length will be used).
187
 
*/
188
 
 
189
 
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
190
 
                          uint32_t key_length, const char *table_name,
191
 
                          const char *path)
192
 
{
193
 
 
194
 
  memset(share, 0, sizeof(*share));
195
 
  init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
196
 
  share->table_category=         TABLE_CATEGORY_TEMPORARY;
197
 
  share->tmp_table=              INTERNAL_TMP_TABLE;
198
 
  share->db.str=                 (char*) key;
199
 
  share->db.length=              strlen(key);
200
 
  share->table_cache_key.str=    (char*) key;
201
 
  share->table_cache_key.length= key_length;
202
 
  share->table_name.str=         (char*) table_name;
203
 
  share->table_name.length=      strlen(table_name);
204
 
  share->path.str=               (char*) path;
205
 
  share->normalized_path.str=    (char*) path;
206
 
  share->path.length= share->normalized_path.length= strlen(path);
207
 
  share->frm_version=            FRM_VER_TRUE_VARCHAR;
208
 
  /*
209
 
    Temporary tables are not replicated, but we set up these fields
210
 
    anyway to be able to catch errors.
211
 
   */
212
 
  share->table_map_version= ~(uint64_t)0;
213
 
  share->cached_row_logging_check= -1;
214
 
 
215
 
  /*
216
 
    table_map_id is also used for MERGE tables to suppress repeated
217
 
    compatibility checks.
218
 
  */
219
 
  share->table_map_id= (ulong) thd->query_id;
220
 
 
221
 
  return;
222
 
}
223
 
 
224
 
 
225
 
/*
226
 
  Free table share and memory used by it
227
 
 
228
 
  SYNOPSIS
229
 
    free_table_share()
230
 
    share               Table share
231
 
 
232
 
  NOTES
233
 
    share->mutex must be locked when we come here if it's not a temp table
234
 
*/
235
 
 
236
 
void free_table_share(TABLE_SHARE *share)
237
 
{
238
 
  MEM_ROOT mem_root;
239
 
  assert(share->ref_count == 0);
240
 
 
241
 
  /*
242
 
    If someone is waiting for this to be deleted, inform it about this.
243
 
    Don't do a delete until we know that no one is refering to this anymore.
244
 
  */
245
 
  if (share->tmp_table == NO_TMP_TABLE)
246
 
  {
247
 
    /* share->mutex is locked in release_table_share() */
248
 
    while (share->waiting_on_cond)
249
 
    {
250
 
      pthread_cond_broadcast(&share->cond);
251
 
      pthread_cond_wait(&share->cond, &share->mutex);
252
 
    }
253
 
    /* No thread refers to this anymore */
254
 
    pthread_mutex_unlock(&share->mutex);
255
 
    pthread_mutex_destroy(&share->mutex);
256
 
    pthread_cond_destroy(&share->cond);
257
 
  }
258
 
  hash_free(&share->name_hash);
259
 
  
260
 
  plugin_unlock(NULL, share->db_plugin);
261
 
  share->db_plugin= NULL;
262
 
 
263
 
  /* We must copy mem_root from share because share is allocated through it */
264
 
  memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
265
 
  free_root(&mem_root, MYF(0));                 // Free's share
266
 
  return;
267
 
}
268
 
 
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)))
295
 
{
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
 
165
enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
 
166
{
 
167
  enum_field_types field_type;
 
168
 
 
169
  switch(proto_field_type)
 
170
  {
 
171
  case drizzled::message::Table::Field::TINYINT:
 
172
    field_type= DRIZZLE_TYPE_TINY;
 
173
    break;
 
174
  case drizzled::message::Table::Field::INTEGER:
 
175
    field_type= DRIZZLE_TYPE_LONG;
 
176
    break;
 
177
  case drizzled::message::Table::Field::DOUBLE:
 
178
    field_type= DRIZZLE_TYPE_DOUBLE;
 
179
    break;
 
180
  case drizzled::message::Table::Field::TIMESTAMP:
 
181
    field_type= DRIZZLE_TYPE_TIMESTAMP;
 
182
    break;
 
183
  case drizzled::message::Table::Field::BIGINT:
 
184
    field_type= DRIZZLE_TYPE_LONGLONG;
 
185
    break;
 
186
  case drizzled::message::Table::Field::DATETIME:
 
187
    field_type= DRIZZLE_TYPE_DATETIME;
 
188
    break;
 
189
  case drizzled::message::Table::Field::DATE:
 
190
    field_type= DRIZZLE_TYPE_DATE;
 
191
    break;
 
192
  case drizzled::message::Table::Field::VARCHAR:
 
193
    field_type= DRIZZLE_TYPE_VARCHAR;
 
194
    break;
 
195
  case drizzled::message::Table::Field::DECIMAL:
 
196
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
197
    break;
 
198
  case drizzled::message::Table::Field::ENUM:
 
199
    field_type= DRIZZLE_TYPE_ENUM;
 
200
    break;
 
201
  case drizzled::message::Table::Field::BLOB:
 
202
    field_type= DRIZZLE_TYPE_BLOB;
 
203
    break;
 
204
  default:
 
205
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
385
206
    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);
 
207
  }
 
208
 
 
209
  return field_type;
 
210
}
 
211
 
 
212
Item * default_value_item(enum_field_types field_type,
 
213
                          const CHARSET_INFO *charset,
 
214
                          bool default_null, const string *default_value,
 
215
                          const string *default_bin_value)
 
216
{
 
217
  Item *default_item= NULL;
 
218
  int error= 0;
 
219
 
 
220
  if(default_null)
 
221
  {
 
222
    return new Item_null();
 
223
  }
 
224
 
 
225
  switch(field_type)
 
226
  {
 
227
  case DRIZZLE_TYPE_TINY:
 
228
  case DRIZZLE_TYPE_LONG:
 
229
  case DRIZZLE_TYPE_LONGLONG:
 
230
    default_item= new Item_int(default_value->c_str(),
 
231
                               (int64_t) my_strtoll10(default_value->c_str(),
 
232
                                                      NULL,
 
233
                                                      &error),
 
234
                               default_value->length());
 
235
    break;
 
236
  case DRIZZLE_TYPE_DOUBLE:
 
237
    default_item= new Item_float(default_value->c_str(),
 
238
                                 default_value->length());
 
239
    break;
 
240
  case DRIZZLE_TYPE_NULL:
 
241
    assert(false);
 
242
  case DRIZZLE_TYPE_TIMESTAMP:
 
243
  case DRIZZLE_TYPE_DATETIME:
 
244
  case DRIZZLE_TYPE_DATE:
 
245
    if (default_value->compare("NOW()") == 0)
 
246
      break;
 
247
  case DRIZZLE_TYPE_ENUM:
 
248
    default_item= new Item_string(default_value->c_str(),
 
249
                                  default_value->length(),
 
250
                                  system_charset_info);
 
251
    break;
 
252
  case DRIZZLE_TYPE_VARCHAR:
 
253
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
 
254
    if(charset==&my_charset_bin)
 
255
    {
 
256
      default_item= new Item_string(default_bin_value->c_str(),
 
257
                                    default_bin_value->length(),
 
258
                                    &my_charset_bin);
 
259
    }
 
260
    else
 
261
    {
 
262
      default_item= new Item_string(default_value->c_str(),
 
263
                                    default_value->length(),
 
264
                                    system_charset_info);
 
265
    }
 
266
    break;
 
267
  case DRIZZLE_TYPE_NEWDECIMAL:
 
268
    default_item= new Item_decimal(default_value->c_str(),
 
269
                                   default_value->length(),
 
270
                                   system_charset_info);
 
271
    break;
 
272
  }
 
273
 
 
274
  return default_item;
 
275
}
 
276
 
 
277
int parse_table_proto(Session *session, drizzled::message::Table &table, TableShare *share)
 
278
{
 
279
  int error= 0;
 
280
  handler *handler_file= NULL;
 
281
 
 
282
  {
 
283
    LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
 
284
                              strlen(table.engine().name().c_str()) };
 
285
    share->storage_engine= ha_resolve_by_name(session, &engine_name);
 
286
  }
 
287
 
 
288
  share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
 
289
 
 
290
  drizzled::message::Table::TableOptions table_options;
 
291
 
 
292
  if(table.has_options())
 
293
    table_options= table.options();
 
294
 
 
295
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
 
296
 
 
297
  if(table_options.has_pack_keys())
 
298
  {
 
299
    if(table_options.pack_keys())
 
300
      db_create_options|= HA_OPTION_PACK_KEYS;
 
301
    else
 
302
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
 
303
  }
 
304
 
 
305
  if(table_options.pack_record())
 
306
    db_create_options|= HA_OPTION_PACK_RECORD;
 
307
 
 
308
  if(table_options.has_checksum())
 
309
  {
 
310
    if(table_options.checksum())
 
311
      db_create_options|= HA_OPTION_CHECKSUM;
 
312
    else
 
313
      db_create_options|= HA_OPTION_NO_CHECKSUM;
 
314
  }
 
315
 
 
316
  if(table_options.has_delay_key_write())
 
317
  {
 
318
    if(table_options.delay_key_write())
 
319
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
 
320
    else
 
321
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
 
322
  }
 
323
 
 
324
  /* db_create_options was stored as 2 bytes in FRM
 
325
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
 
326
   */
 
327
  share->db_create_options= (db_create_options & 0x0000FFFF);
469
328
  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
 
  }
 
329
 
 
330
 
 
331
  share->avg_row_length= table_options.has_avg_row_length() ?
 
332
    table_options.avg_row_length() : 0;
 
333
 
 
334
  share->page_checksum= table_options.has_page_checksum() ?
 
335
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
336
    : HA_CHOICE_UNDEF;
 
337
 
 
338
  share->row_type= table_options.has_row_type() ?
 
339
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
340
 
 
341
  share->block_size= table_options.has_block_size() ?
 
342
    table_options.block_size() : 0;
 
343
 
 
344
  share->table_charset= get_charset(table_options.has_collation_id()?
 
345
                                    table_options.collation_id() : 0);
 
346
 
482
347
  if (!share->table_charset)
483
348
  {
484
349
    /* unknown charset in head[38] or pre-3.23 frm */
485
350
    if (use_mb(default_charset_info))
486
351
    {
487
352
      /* 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);
 
353
      errmsg_printf(ERRMSG_LVL_WARN,
 
354
                    _("'%s' had no or invalid character set, "
 
355
                      "and default character set is multi-byte, "
 
356
                      "so character column sizes may have changed"),
 
357
                    share->path.str);
492
358
    }
493
359
    share->table_charset= default_charset_info;
494
360
  }
 
361
 
495
362
  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 */
 
363
 
 
364
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
365
 
499
366
  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;
 
367
 
 
368
  share->max_rows= table_options.has_max_rows() ?
 
369
    table_options.max_rows() : 0;
 
370
 
 
371
  share->min_rows= table_options.has_min_rows() ?
 
372
    table_options.min_rows() : 0;
 
373
 
 
374
  share->keys= table.indexes_size();
 
375
 
 
376
  share->key_parts= 0;
 
377
  for(int indx= 0; indx < table.indexes_size(); indx++)
 
378
    share->key_parts+= table.indexes(indx).index_part_size();
 
379
 
 
380
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
381
                                     table.indexes_size() * sizeof(KEY)
 
382
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
383
 
 
384
  KEY_PART_INFO *key_part;
 
385
 
 
386
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
387
    (share->key_info+table.indexes_size());
 
388
 
 
389
 
 
390
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
391
                                            sizeof(ulong*)*share->key_parts);
 
392
 
 
393
  share->keynames.count= table.indexes_size();
 
394
  share->keynames.name= NULL;
 
395
  share->keynames.type_names= (const char**)
 
396
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
397
 
 
398
  share->keynames.type_lengths= (unsigned int*)
 
399
    alloc_root(&share->mem_root,
 
400
               sizeof(unsigned int) * (table.indexes_size()+1));
 
401
 
 
402
  share->keynames.type_names[share->keynames.count]= NULL;
 
403
  share->keynames.type_lengths[share->keynames.count]= 0;
 
404
 
 
405
  KEY* keyinfo= share->key_info;
 
406
  for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
407
  {
 
408
    drizzled::message::Table::Index indx= table.indexes(keynr);
 
409
 
 
410
    keyinfo->table= 0;
 
411
    keyinfo->flags= 0;
 
412
 
 
413
    if(indx.is_unique())
 
414
      keyinfo->flags|= HA_NOSAME;
 
415
 
 
416
    if(indx.has_options())
 
417
    {
 
418
      drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
 
419
      if(indx_options.pack_key())
 
420
        keyinfo->flags|= HA_PACK_KEY;
 
421
 
 
422
      if(indx_options.var_length_key())
 
423
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
424
 
 
425
      if(indx_options.null_part_key())
 
426
        keyinfo->flags|= HA_NULL_PART_KEY;
 
427
 
 
428
      if(indx_options.binary_pack_key())
 
429
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
430
 
 
431
      if(indx_options.has_partial_segments())
 
432
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
433
 
 
434
      if(indx_options.auto_generated_key())
 
435
        keyinfo->flags|= HA_GENERATED_KEY;
 
436
 
 
437
      if(indx_options.has_key_block_size())
 
438
      {
 
439
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
440
        keyinfo->block_size= indx_options.key_block_size();
 
441
      }
 
442
      else
 
443
      {
 
444
        keyinfo->block_size= 0;
 
445
      }
 
446
 
 
447
    }
 
448
 
 
449
    switch(indx.type())
 
450
    {
 
451
    case drizzled::message::Table::Index::UNKNOWN_INDEX:
 
452
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
453
      break;
 
454
    case drizzled::message::Table::Index::BTREE:
 
455
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
456
      break;
 
457
    case drizzled::message::Table::Index::RTREE:
 
458
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
459
      break;
 
460
    case drizzled::message::Table::Index::HASH:
 
461
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
462
      break;
 
463
    case drizzled::message::Table::Index::FULLTEXT:
 
464
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
465
 
 
466
    default:
 
467
      /* TODO: suitable warning ? */
 
468
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
469
      break;
 
470
    }
 
471
 
 
472
    keyinfo->key_length= indx.key_length();
 
473
 
 
474
    keyinfo->key_parts= indx.index_part_size();
 
475
 
 
476
    keyinfo->key_part= key_part;
549
477
    keyinfo->rec_per_key= rec_per_key;
550
 
    for (j=keyinfo->key_parts ; j-- ; key_part++)
 
478
 
 
479
    for(unsigned int partnr= 0;
 
480
        partnr < keyinfo->key_parts;
 
481
        partnr++, key_part++)
551
482
    {
 
483
      drizzled::message::Table::Index::IndexPart part;
 
484
      part= indx.index_part(partnr);
 
485
 
552
486
      *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);
 
487
 
 
488
      key_part->field= NULL;
 
489
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
 
490
      key_part->null_bit= 0;
 
491
      /* key_part->null_offset is only set if null_bit (see later) */
 
492
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
493
      /* key_part->type ???? */
 
494
      key_part->key_part_flag= 0;
 
495
      if(part.has_in_reverse_order())
 
496
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
497
 
 
498
      key_part->length= part.compare_length();
 
499
 
 
500
      key_part->store_length= key_part->length;
 
501
 
 
502
      /* key_part->offset is set later */
 
503
      key_part->key_type= part.key_type();
 
504
 
 
505
    }
 
506
 
 
507
    if(!indx.has_comment())
 
508
    {
 
509
      keyinfo->comment.length= 0;
 
510
      keyinfo->comment.str= NULL;
 
511
    }
 
512
    else
 
513
    {
 
514
      keyinfo->flags|= HA_USES_COMMENT;
 
515
      keyinfo->comment.length= indx.comment().length();
 
516
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
517
                                         indx.comment().c_str(),
 
518
                                         keyinfo->comment.length);
 
519
    }
 
520
 
 
521
    keyinfo->name= strmake_root(&share->mem_root,
 
522
                                indx.name().c_str(),
 
523
                                indx.name().length());
 
524
 
 
525
    share->keynames.type_names[keynr]= keyinfo->name;
 
526
    share->keynames.type_lengths[keynr]= indx.name().length();
 
527
  }
 
528
 
 
529
  share->keys_for_keyread.reset();
 
530
  set_prefix(share->keys_in_use, share->keys);
 
531
 
 
532
  if(table_options.has_connect_string())
 
533
  {
 
534
    size_t len= table_options.connect_string().length();
 
535
    const char* str= table_options.connect_string().c_str();
 
536
 
 
537
    share->connect_string.length= len;
 
538
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
539
  }
 
540
 
 
541
  if(table_options.has_comment())
 
542
  {
 
543
    size_t len= table_options.comment().length();
 
544
    const char* str= table_options.comment().c_str();
 
545
 
 
546
    share->comment.length= len;
 
547
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
548
  }
 
549
 
 
550
  share->key_block_size= table_options.has_key_block_size() ?
 
551
    table_options.key_block_size() : 0;
 
552
 
 
553
  share->fields= table.field_size();
 
554
 
 
555
  share->field= (Field**) alloc_root(&share->mem_root,
 
556
                                     ((share->fields+1) * sizeof(Field*)));
 
557
  share->field[share->fields]= NULL;
 
558
 
 
559
  uint32_t null_fields= 0;
 
560
  share->reclength= 0;
 
561
 
 
562
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
 
563
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
 
564
 
 
565
  assert(field_offsets && field_pack_length); // TODO: fixme
 
566
 
 
567
  uint32_t interval_count= 0;
 
568
  uint32_t interval_parts= 0;
 
569
 
 
570
  uint32_t stored_columns_reclength= 0;
 
571
 
 
572
  for (unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
573
  {
 
574
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
575
    if(pfield.has_constraints() && pfield.constraints().is_nullable())
 
576
      null_fields++;
 
577
 
 
578
    enum_field_types drizzle_field_type=
 
579
      proto_field_type_to_drizzle_type(pfield.type());
 
580
 
 
581
    field_offsets[fieldnr]= stored_columns_reclength;
 
582
 
 
583
    /* the below switch is very similar to
 
584
       Create_field::create_length_to_internal_length in field.cc
 
585
       (which should one day be replace by just this code)
 
586
    */
 
587
    switch(drizzle_field_type)
 
588
    {
 
589
    case DRIZZLE_TYPE_BLOB:
 
590
    case DRIZZLE_TYPE_VARCHAR:
 
591
      {
 
592
        drizzled::message::Table::Field::StringFieldOptions field_options=
 
593
          pfield.string_options();
 
594
 
 
595
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
596
                                            field_options.collation_id() : 0);
 
597
 
 
598
        if (!cs)
 
599
          cs= default_charset_info;
 
600
 
 
601
        field_pack_length[fieldnr]=
 
602
          calc_pack_length(drizzle_field_type,
 
603
                           field_options.length() * cs->mbmaxlen);
 
604
 
 
605
      }
 
606
      break;
 
607
    case DRIZZLE_TYPE_ENUM:
 
608
      {
 
609
        drizzled::message::Table::Field::SetFieldOptions field_options=
 
610
          pfield.set_options();
 
611
 
 
612
        field_pack_length[fieldnr]=
 
613
          get_enum_pack_length(field_options.field_value_size());
 
614
 
 
615
        interval_count++;
 
616
        interval_parts+= field_options.field_value_size();
 
617
      }
 
618
      break;
 
619
    case DRIZZLE_TYPE_NEWDECIMAL:
 
620
      {
 
621
        drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
622
 
 
623
        field_pack_length[fieldnr]=
 
624
          my_decimal_get_binary_size(fo.precision(), fo.scale());
 
625
      }
 
626
      break;
 
627
    default:
 
628
      /* Zero is okay here as length is fixed for other types. */
 
629
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
 
630
    }
 
631
 
 
632
    share->reclength+= field_pack_length[fieldnr];
 
633
    stored_columns_reclength+= field_pack_length[fieldnr];
 
634
 
 
635
  }
 
636
 
 
637
  /* data_offset added to stored_rec_length later */
 
638
  share->stored_rec_length= stored_columns_reclength;
 
639
 
 
640
  share->null_fields= null_fields;
 
641
 
 
642
  ulong null_bits= null_fields;
 
643
  if(!table_options.pack_record())
 
644
    null_bits++;
 
645
  ulong data_offset= (null_bits + 7)/8;
 
646
 
 
647
 
 
648
  share->reclength+= data_offset;
 
649
  share->stored_rec_length+= data_offset;
 
650
 
 
651
  ulong rec_buff_length;
 
652
 
 
653
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
717
654
  share->rec_buff_length= rec_buff_length;
 
655
 
 
656
  unsigned char* record= NULL;
 
657
 
718
658
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
719
659
                                     rec_buff_length)))
720
 
    goto err;                                   /* purecov: inspected */
 
660
    abort();
 
661
 
 
662
  memset(record, 0, rec_buff_length);
 
663
 
 
664
  int null_count= 0;
 
665
 
 
666
  if(!table_options.pack_record())
 
667
  {
 
668
    null_count++; // one bit for delete mark.
 
669
    *record|= 1;
 
670
  }
 
671
 
721
672
  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)
 
673
 
 
674
  if(interval_count)
736
675
  {
737
 
    share->comment.length=  (int) (forminfo[46]);
738
 
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
739
 
                                     share->comment.length);
 
676
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
677
                                           interval_count*sizeof(TYPELIB));
740
678
  }
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
 
 
 
679
  else
 
680
    share->intervals= NULL;
 
681
 
 
682
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
683
                                  (share->fields+1)*sizeof(char*));
 
684
 
 
685
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
686
                                  (share->fields+1)*sizeof(unsigned int));
 
687
 
 
688
  share->fieldnames.type_names[share->fields]= NULL;
 
689
  share->fieldnames.type_lengths[share->fields]= 0;
 
690
  share->fieldnames.count= share->fields;
 
691
 
 
692
 
 
693
  /* Now fix the TYPELIBs for the intervals (enum values)
 
694
     and field names.
 
695
   */
 
696
 
 
697
  uint32_t interval_nr= 0;
 
698
 
 
699
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
775
700
  {
776
 
    /* Set ENUM and SET lengths */
777
 
    TYPELIB *interval;
778
 
    for (interval= share->intervals;
779
 
         interval < share->intervals + interval_count;
780
 
         interval++)
 
701
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
702
 
 
703
    /* field names */
 
704
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
 
705
                                                        pfield.name().c_str(),
 
706
                                                        pfield.name().length());
 
707
 
 
708
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
 
709
 
 
710
    /* enum typelibs */
 
711
    if(pfield.type() != drizzled::message::Table::Field::ENUM)
 
712
      continue;
 
713
 
 
714
    drizzled::message::Table::Field::SetFieldOptions field_options=
 
715
      pfield.set_options();
 
716
 
 
717
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
718
                                             field_options.collation_id() : 0);
 
719
 
 
720
    if (!charset)
 
721
      charset= default_charset_info;
 
722
 
 
723
    TYPELIB *t= &(share->intervals[interval_nr]);
 
724
 
 
725
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
726
                           (field_options.field_value_size()+1)*sizeof(char*));
 
727
 
 
728
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
729
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
 
730
 
 
731
    t->type_names[field_options.field_value_size()]= NULL;
 
732
    t->type_lengths[field_options.field_value_size()]= 0;
 
733
 
 
734
    t->count= field_options.field_value_size();
 
735
    t->name= NULL;
 
736
 
 
737
    for(int n=0; n < field_options.field_value_size(); n++)
781
738
    {
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;
 
739
      t->type_names[n]= strmake_root(&share->mem_root,
 
740
                                     field_options.field_value(n).c_str(),
 
741
                                     field_options.field_value(n).length());
 
742
 
 
743
      /* Go ask the charset what the length is as for "" length=1
 
744
         and there's stripping spaces or some other crack going on.
 
745
       */
 
746
      uint32_t lengthsp;
 
747
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
748
                                        field_options.field_value(n).length());
 
749
      t->type_lengths[n]= lengthsp;
792
750
    }
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)
 
751
    interval_nr++;
 
752
  }
 
753
 
 
754
 
 
755
  /* and read the fields */
 
756
  interval_nr= 0;
 
757
 
 
758
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
759
 
 
760
  if(use_hash)
818
761
    use_hash= !hash_init(&share->name_hash,
819
762
                         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++)
 
763
                         share->fields, 0, 0,
 
764
                         (hash_get_key) get_field_name, 0, 0);
 
765
 
 
766
  unsigned char* null_pos= record;;
 
767
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
 
768
 
 
769
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
824
770
  {
825
 
    uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
826
 
    enum_field_types field_type;
 
771
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
772
 
827
773
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
828
 
    const CHARSET_INFO *charset= NULL;
 
774
 
 
775
    switch(pfield.format())
 
776
    {
 
777
    case drizzled::message::Table::Field::DefaultFormat:
 
778
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
779
      break;
 
780
    case drizzled::message::Table::Field::FixedFormat:
 
781
      column_format= COLUMN_FORMAT_TYPE_FIXED;
 
782
      break;
 
783
    case drizzled::message::Table::Field::DynamicFormat:
 
784
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
 
785
      break;
 
786
    default:
 
787
      assert(1);
 
788
    }
 
789
 
 
790
    Field::utype unireg_type= Field::NONE;
 
791
 
 
792
    if(pfield.has_numeric_options()
 
793
       && pfield.numeric_options().is_autoincrement())
 
794
    {
 
795
      unireg_type= Field::NEXT_NUMBER;
 
796
    }
 
797
 
 
798
    if(pfield.has_options()
 
799
       && pfield.options().has_default_value()
 
800
       && pfield.options().default_value().compare("NOW()")==0)
 
801
    {
 
802
      if(pfield.options().has_update_value()
 
803
         && pfield.options().update_value().compare("NOW()")==0)
 
804
      {
 
805
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
806
      }
 
807
      else if (!pfield.options().has_update_value())
 
808
      {
 
809
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
810
      }
 
811
      else
 
812
        assert(1); // Invalid update value.
 
813
    }
 
814
    else if (pfield.has_options()
 
815
             && pfield.options().has_update_value()
 
816
             && pfield.options().update_value().compare("NOW()")==0)
 
817
    {
 
818
      unireg_type= Field::TIMESTAMP_UN_FIELD;
 
819
    }
 
820
 
829
821
    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
 
      }
 
822
    if(!pfield.has_comment())
 
823
    {
 
824
      comment.str= (char*)"";
 
825
      comment.length= 0;
869
826
    }
870
827
    else
871
828
    {
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
 
    {
 
829
      size_t len= pfield.comment().length();
 
830
      const char* str= pfield.comment().c_str();
 
831
 
 
832
      comment.str= strmake_root(&share->mem_root, str, len);
 
833
      comment.length= len;
 
834
    }
 
835
 
 
836
    enum_field_types field_type;
 
837
 
 
838
    field_type= proto_field_type_to_drizzle_type(pfield.type());
 
839
 
 
840
    const CHARSET_INFO *charset= &my_charset_bin;
 
841
 
 
842
    if(field_type==DRIZZLE_TYPE_BLOB
 
843
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
844
    {
 
845
      drizzled::message::Table::Field::StringFieldOptions field_options=
 
846
        pfield.string_options();
 
847
 
 
848
      charset= get_charset(field_options.has_collation_id()?
 
849
                           field_options.collation_id() : 0);
 
850
 
 
851
      if (!charset)
 
852
        charset= default_charset_info;
 
853
 
 
854
    }
 
855
 
 
856
    if(field_type==DRIZZLE_TYPE_ENUM)
 
857
    {
 
858
      drizzled::message::Table::Field::SetFieldOptions field_options=
 
859
        pfield.set_options();
 
860
 
 
861
      charset= get_charset(field_options.has_collation_id()?
 
862
                           field_options.collation_id() : 0);
 
863
 
 
864
      if (!charset)
 
865
        charset= default_charset_info;
 
866
 
 
867
    }
 
868
 
 
869
    Item *default_value= NULL;
 
870
 
 
871
    if(pfield.options().has_default_value()
 
872
       || pfield.options().has_default_null()
 
873
       || pfield.options().has_default_bin_value())
 
874
    {
 
875
      default_value= default_value_item(field_type,
 
876
                                        charset,
 
877
                                        pfield.options().default_null(),
 
878
                                        &pfield.options().default_value(),
 
879
                                        &pfield.options().default_bin_value());
 
880
    }
 
881
 
 
882
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
 
883
 
 
884
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
885
    memset(&temp_table, 0, sizeof(temp_table));
 
886
    temp_table.s= share;
 
887
    temp_table.in_use= session;
 
888
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
 
889
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
890
 
 
891
    Field* f= make_field(share, &share->mem_root,
 
892
                         record+field_offsets[fieldnr]+data_offset,
 
893
                         pfield.options().length(),
 
894
                         null_pos,
 
895
                         null_bit_pos,
 
896
                         pack_flag,
 
897
                         field_type,
 
898
                         charset,
 
899
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
900
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
901
                         share->intervals+(interval_nr++)
 
902
                         : (TYPELIB*) 0),
 
903
                        share->fieldnames.type_names[fieldnr]);
 
904
 
 
905
    share->field[fieldnr]= f;
 
906
 
 
907
    f->init(&temp_table); /* blob default values need table obj */
 
908
 
 
909
    if(!(f->flags & NOT_NULL_FLAG))
 
910
    {
 
911
      *f->null_ptr|= f->null_bit;
934
912
      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)
 
913
        null_pos++;
 
914
      null_count++;
 
915
    }
 
916
 
 
917
    if(default_value)
 
918
    {
 
919
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
920
      session->count_cuted_fields= CHECK_FIELD_WARN;
 
921
      int res= default_value->save_in_field(f, 1);
 
922
      session->count_cuted_fields= old_count_cuted_fields;
 
923
      if (res != 0 && res != 3)
 
924
      {
 
925
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
 
926
        error= 1;
 
927
        goto err;
 
928
      }
 
929
    }
 
930
    else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
 
931
            (f->flags & NOT_NULL_FLAG))
 
932
    {
 
933
      f->set_notnull();
 
934
      f->store((int64_t) 1, true);
 
935
    }
 
936
    else
 
937
      f->reset();
 
938
 
 
939
    /* hack to undo f->init() */
 
940
    f->table= NULL;
 
941
    f->orig_table= NULL;
 
942
 
 
943
    f->field_index= fieldnr;
 
944
    f->comment= comment;
 
945
    if(!default_value
 
946
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
947
       && (f->flags & NOT_NULL_FLAG)
 
948
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
 
949
      f->flags|= NO_DEFAULT_VALUE_FLAG;
 
950
 
 
951
    if(f->unireg_check == Field::NEXT_NUMBER)
 
952
      share->found_next_number_field= &(share->field[fieldnr]);
 
953
 
 
954
    if(share->timestamp_field == f)
 
955
      share->timestamp_field_offset= fieldnr;
 
956
 
 
957
    if (use_hash) /* supposedly this never fails... but comments lie */
946
958
      (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,
 
959
                            (unsigned char*)&(share->field[fieldnr]));
 
960
 
 
961
  }
 
962
 
 
963
  keyinfo= share->key_info;
 
964
  for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
 
965
  {
 
966
    key_part= keyinfo->key_part;
 
967
 
 
968
    for(unsigned int partnr= 0;
 
969
        partnr < keyinfo->key_parts;
 
970
        partnr++, key_part++)
 
971
    {
 
972
      /* Fix up key_part->offset by adding data_offset.
 
973
         We really should compute offset as well.
 
974
         But at least this way we are a little better. */
 
975
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
976
    }
 
977
  }
 
978
 
 
979
  /*
 
980
    We need to set the unused bits to 1. If the number of bits is a multiple
 
981
    of 8 there are no unused bits.
 
982
  */
 
983
 
 
984
  if (null_count & 7)
 
985
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
986
 
 
987
  share->null_bytes= (null_pos - (unsigned char*) record +
 
988
                      (null_bit_pos + 7) / 8);
 
989
 
 
990
  share->last_null_bit_pos= null_bit_pos;
 
991
 
 
992
  free(field_offsets);
 
993
  free(field_pack_length);
 
994
 
 
995
  if(!(handler_file= get_new_handler(share, session->mem_root,
 
996
                                     share->db_type())))
 
997
    abort(); // FIXME
 
998
 
 
999
  /* Fix key stuff */
 
1000
  if (share->key_parts)
 
1001
  {
 
1002
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
955
1003
                                       &share->keynames, 3) - 1);
 
1004
 
956
1005
    int64_t ha_option= handler_file->ha_table_flags();
 
1006
 
957
1007
    keyinfo= share->key_info;
958
1008
    key_part= keyinfo->key_part;
959
1009
 
960
1010
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
961
1011
    {
962
1012
      uint32_t usable_parts= 0;
963
 
      keyinfo->name=(char*) share->keynames.type_names[key];
964
1013
 
965
1014
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
966
1015
      {
969
1018
          declare this as a primary key.
970
1019
        */
971
1020
        primary_key=key;
972
 
        for (i=0 ; i < keyinfo->key_parts ;i++)
 
1021
        for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
973
1022
        {
974
1023
          uint32_t fieldnr= key_part[i].fieldnr;
975
1024
          if (!fieldnr ||
977
1026
              share->field[fieldnr-1]->key_length() !=
978
1027
              key_part[i].length)
979
1028
          {
980
 
            primary_key=MAX_KEY;                // Can't be used
 
1029
            primary_key=MAX_KEY;                // Can't be used
981
1030
            break;
982
1031
          }
983
1032
        }
984
1033
      }
985
1034
 
986
 
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1035
      for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
987
1036
      {
988
1037
        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
1038
        if (!key_part->fieldnr)
995
1039
        {
996
 
          error= 4;                             // Wrong file
997
 
          goto err;
 
1040
//          error= 4;                             // Wrong file
 
1041
          abort(); // goto err;
998
1042
        }
999
1043
        field= key_part->field= share->field[key_part->fieldnr-1];
1000
1044
        key_part->type= field->key_type();
1001
1045
        if (field->null_ptr)
1002
1046
        {
1003
 
          key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
 
1047
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1004
1048
                                        share->default_values);
1005
1049
          key_part->null_bit= field->null_bit;
1006
1050
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1024
1068
                           (keyinfo->key_parts == 1)) ?
1025
1069
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1026
1070
        if (i == 0)
1027
 
          field->key_start.set_bit(key);
 
1071
          field->key_start.set(key);
1028
1072
        if (field->key_length() == key_part->length &&
1029
1073
            !(field->flags & BLOB_FLAG))
1030
1074
        {
1031
1075
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1032
1076
          {
1033
 
            share->keys_for_keyread.set_bit(key);
1034
 
            field->part_of_key.set_bit(key);
1035
 
            field->part_of_key_not_clustered.set_bit(key);
 
1077
            share->keys_for_keyread.set(key);
 
1078
            field->part_of_key.set(key);
 
1079
            field->part_of_key_not_clustered.set(key);
1036
1080
          }
1037
1081
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1038
 
            field->part_of_sortkey.set_bit(key);
 
1082
            field->part_of_sortkey.set(key);
1039
1083
        }
1040
1084
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1041
1085
            usable_parts == i)
1051
1095
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1052
1096
          {
1053
1097
            field->part_of_key= share->keys_in_use;
1054
 
            if (field->part_of_sortkey.is_set(key))
 
1098
            if (field->part_of_sortkey.test(key))
1055
1099
              field->part_of_sortkey= share->keys_in_use;
1056
1100
          }
1057
1101
        }
1074
1118
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1075
1119
    }
1076
1120
    if (primary_key < MAX_KEY &&
1077
 
        (share->keys_in_use.is_set(primary_key)))
 
1121
        (share->keys_in_use.test(primary_key)))
1078
1122
    {
1079
1123
      share->primary_key= primary_key;
1080
1124
      /*
1091
1135
                                      fieldnr);
1092
1136
        }
1093
1137
      }
 
1138
 
1094
1139
    }
1095
1140
    else
1096
1141
      share->primary_key = MAX_KEY; // we do not have a primary key
1097
1142
  }
1098
1143
  else
1099
1144
    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
1145
 
1111
1146
  if (share->found_next_number_field)
1112
1147
  {
1113
 
    reg_field= *share->found_next_number_field;
1114
 
    if ((int) (share->next_number_index= (uint)
 
1148
    Field *reg_field= *share->found_next_number_field;
 
1149
    if ((int) (share->next_number_index= (uint32_t)
1115
1150
               find_ref_key(share->key_info, share->keys,
1116
1151
                            share->default_values, reg_field,
1117
1152
                            &share->next_number_key_offset,
1133
1168
    /* Store offsets to blob fields to find them fast */
1134
1169
    if (!(share->blob_field= save=
1135
1170
          (uint*) alloc_root(&share->mem_root,
1136
 
                             (uint) (share->blob_fields* sizeof(uint)))))
 
1171
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1137
1172
      goto err;
1138
1173
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1139
1174
    {
1142
1177
    }
1143
1178
  }
1144
1179
 
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
1180
  share->db_low_byte_first= handler_file->low_byte_first();
1154
1181
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1155
1182
 
 
1183
  my_bitmap_map *bitmaps;
 
1184
 
1156
1185
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1157
1186
                                             share->column_bitmap_size)))
1158
1187
    goto err;
1159
1188
  bitmap_init(&share->all_set, bitmaps, share->fields, false);
1160
1189
  bitmap_set_all(&share->all_set);
1161
1190
 
1162
 
  delete handler_file;
1163
 
  if (buff)
1164
 
    free(buff);
 
1191
  if(handler_file)
 
1192
    delete handler_file;
1165
1193
  return (0);
1166
1194
 
1167
 
 err:
1168
 
  if (buff)
1169
 
    free(buff);
 
1195
err:
1170
1196
  share->error= error;
1171
1197
  share->open_errno= my_errno;
1172
 
  share->errarg= errarg;
1173
 
  if (disk_buff)
1174
 
    free(disk_buff);
1175
 
  delete handler_file;
 
1198
  share->errarg= 0;
1176
1199
  hash_free(&share->name_hash);
1177
 
 
1178
 
  open_table_error(share, error, share->open_errno, errarg);
 
1200
  if(handler_file)
 
1201
    delete handler_file;
 
1202
  open_table_error(share, error, share->open_errno, 0);
 
1203
  return error;
 
1204
}
 
1205
 
 
1206
/*
 
1207
  Read table definition from a binary / text based .frm file
 
1208
 
 
1209
  SYNOPSIS
 
1210
  open_table_def()
 
1211
  session               Thread handler
 
1212
  share         Fill this with table definition
 
1213
 
 
1214
  NOTES
 
1215
    This function is called when the table definition is not cached in
 
1216
    table_def_cache
 
1217
    The data is returned in 'share', which is alloced by
 
1218
    alloc_table_share().. The code assumes that share is initialized.
 
1219
 
 
1220
  RETURN VALUES
 
1221
   0    ok
 
1222
   1    Error (see open_table_error)
 
1223
   2    Error (see open_table_error)
 
1224
   3    Wrong data in .frm file
 
1225
   4    Error (see open_table_error)
 
1226
   5    Error (see open_table_error: charset unavailable)
 
1227
   6    Unknown .frm version
 
1228
*/
 
1229
 
 
1230
int open_table_def(Session *session, TableShare *share)
 
1231
{
 
1232
  int error;
 
1233
  bool error_given;
 
1234
  string proto_path("");
 
1235
 
 
1236
  error= 1;
 
1237
  error_given= 0;
 
1238
 
 
1239
  proto_path.reserve(FN_REFLEN);
 
1240
  proto_path.append(share->normalized_path.str);
 
1241
 
 
1242
  proto_path.append(".dfe");
 
1243
 
 
1244
  drizzled::message::Table table;
 
1245
 
 
1246
  if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
 
1247
  {
 
1248
    if(error>0)
 
1249
    {
 
1250
      my_errno= error;
 
1251
      error= 1;
 
1252
    }
 
1253
    else
 
1254
    {
 
1255
      if(!table.IsInitialized())
 
1256
      {
 
1257
        error= 4;
 
1258
      }
 
1259
    }
 
1260
    goto err_not_open;
 
1261
  }
 
1262
 
 
1263
  error= parse_table_proto(session, table, share);
 
1264
 
 
1265
  share->table_category= get_table_category(& share->db, & share->table_name);
 
1266
 
 
1267
  if (!error)
 
1268
    session->status_var.opened_shares++;
 
1269
 
 
1270
err_not_open:
 
1271
  if (error && !error_given)
 
1272
  {
 
1273
    share->error= error;
 
1274
    open_table_error(share, error, (share->open_errno= my_errno), 0);
 
1275
  }
 
1276
 
1179
1277
  return(error);
1180
 
} /* open_binary_frm */
 
1278
}
1181
1279
 
1182
1280
 
1183
1281
/*
1184
 
  Open a table based on a TABLE_SHARE
 
1282
  Open a table based on a TableShare
1185
1283
 
1186
1284
  SYNOPSIS
1187
1285
    open_table_from_share()
1188
 
    thd                 Thread handler
 
1286
    session                     Thread handler
1189
1287
    share               Table definition
1190
1288
    alias               Alias for table
1191
1289
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1208
1306
   7    Table definition has changed in engine
1209
1307
*/
1210
1308
 
1211
 
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
 
1309
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1212
1310
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1213
1311
                          Table *outparam, open_table_mode open_mode)
1214
1312
{
1218
1316
  unsigned char *record, *bitmaps;
1219
1317
  Field **field_ptr;
1220
1318
 
1221
 
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
1222
 
  assert(thd->lex->is_lex_started);
 
1319
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1320
  assert(session->lex->is_lex_started);
1223
1321
 
1224
1322
  error= 1;
1225
1323
  memset(outparam, 0, sizeof(*outparam));
1226
 
  outparam->in_use= thd;
 
1324
  outparam->in_use= session;
1227
1325
  outparam->s= share;
1228
1326
  outparam->db_stat= db_stat;
1229
1327
  outparam->write_row_record= NULL;
1230
1328
 
1231
1329
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1232
1330
 
1233
 
  if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
 
1331
  if (!(outparam->alias= strdup(alias)))
1234
1332
    goto err;
1235
 
  outparam->quick_keys.init();
1236
 
  outparam->covering_keys.init();
1237
 
  outparam->keys_in_use_for_query.init();
 
1333
  outparam->quick_keys.reset();
 
1334
  outparam->covering_keys.reset();
 
1335
  outparam->keys_in_use_for_query.reset();
1238
1336
 
1239
1337
  /* Allocate handler */
1240
1338
  outparam->file= 0;
1292
1390
#endif
1293
1391
 
1294
1392
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1295
 
                                          (uint) ((share->fields+1)*
 
1393
                                          (uint32_t) ((share->fields+1)*
1296
1394
                                                  sizeof(Field*)))))
1297
1395
    goto err;                                   /* purecov: inspected */
1298
1396
 
1299
1397
  outparam->field= field_ptr;
1300
1398
 
1301
1399
  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);
 
1400
 
 
1401
  outparam->null_flags= (unsigned char*) record+1;
1307
1402
 
1308
1403
  /* Setup copy of fields from share, but use the right alias and record */
1309
1404
  for (i=0 ; i < share->fields; i++, field_ptr++)
1315
1410
 
1316
1411
  if (share->found_next_number_field)
1317
1412
    outparam->found_next_number_field=
1318
 
      outparam->field[(uint) (share->found_next_number_field - share->field)];
 
1413
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1319
1414
  if (share->timestamp_field)
1320
1415
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1321
1416
 
1331
1426
      goto err;
1332
1427
    outparam->key_info= key_info;
1333
1428
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1334
 
    
 
1429
 
1335
1430
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1336
1431
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1337
1432
                                                   share->key_parts));
1427
1522
    }
1428
1523
  }
1429
1524
 
1430
 
#if defined(HAVE_purify) 
 
1525
#if defined(HAVE_purify)
1431
1526
  memset(bitmaps, 0, bitmap_size*3);
1432
1527
#endif
1433
1528
 
1434
1529
  outparam->no_replicate= outparam->file;
1435
 
  thd->status_var.opened_tables++;
 
1530
  session->status_var.opened_tables++;
1436
1531
 
1437
1532
  return (0);
1438
1533
 
1447
1542
  return (error);
1448
1543
}
1449
1544
 
 
1545
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
 
1546
uint32_t  Table::tmpkeyval()
 
1547
{
 
1548
  return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
 
1549
}
1450
1550
 
1451
1551
/*
1452
1552
  Free information allocated by openfrm
1457
1557
    free_share          Is 1 if we also want to free table_share
1458
1558
*/
1459
1559
 
1460
 
int closefrm(register Table *table, bool free_share)
 
1560
int Table::closefrm(bool free_share)
1461
1561
{
1462
1562
  int error=0;
1463
1563
 
1464
 
  if (table->db_stat)
1465
 
    error=table->file->close();
1466
 
  free((char*) table->alias);
1467
 
  table->alias= 0;
1468
 
  if (table->field)
 
1564
  if (db_stat)
 
1565
    error= file->close();
 
1566
  free((char*) alias);
 
1567
  alias= NULL;
 
1568
  if (field)
1469
1569
  {
1470
 
    for (Field **ptr=table->field ; *ptr ; ptr++)
 
1570
    for (Field **ptr=field ; *ptr ; ptr++)
1471
1571
      delete *ptr;
1472
 
    table->field= 0;
 
1572
    field= 0;
1473
1573
  }
1474
 
  delete table->file;
1475
 
  table->file= 0;                               /* For easier errorchecking */
 
1574
  delete file;
 
1575
  file= 0;                              /* For easier errorchecking */
1476
1576
  if (free_share)
1477
1577
  {
1478
 
    if (table->s->tmp_table == NO_TMP_TABLE)
1479
 
      release_table_share(table->s, RELEASE_NORMAL);
 
1578
    if (s->tmp_table == NO_TMP_TABLE)
 
1579
      release_table_share(s, RELEASE_NORMAL);
1480
1580
    else
1481
 
      free_table_share(table->s);
 
1581
      s->free_table_share();
1482
1582
  }
1483
 
  free_root(&table->mem_root, MYF(0));
1484
 
  return(error);
 
1583
  free_root(&mem_root, MYF(0));
 
1584
 
 
1585
  return error;
1485
1586
}
1486
1587
 
1487
1588
 
1517
1618
  if (names)
1518
1619
  {
1519
1620
    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))) ||
 
1621
    lseek(file,64,SEEK_SET);
 
1622
    if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
1523
1623
        my_read(file, buf+a_length, (size_t) (length+names*4),
1524
1624
                MYF(MY_NABP)))
1525
1625
    {                                           /* purecov: inspected */
1559
1659
 
1560
1660
  if (*to)
1561
1661
    free(*to);
1562
 
  if (!(*to= (unsigned char*) my_malloc(length+1,MYF(MY_WME))) ||
 
1662
  if (!(*to= (unsigned char*) malloc(length+1)) ||
1563
1663
      my_read(file, *to, length,MYF(MY_NABP)))
1564
1664
  {
1565
1665
    if (*to)
1574
1674
 
1575
1675
        /* Add a new form to a form file */
1576
1676
 
1577
 
ulong make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
 
1677
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
1578
1678
                     const char *newname)
1579
1679
{
1580
1680
  uint32_t i,bufflength,maxlength,n_length,length,names;
1581
 
  ulong endpos,newpos;
 
1681
  off_t endpos,newpos;
1582
1682
  unsigned char buff[IO_SIZE];
1583
1683
  unsigned char *pos;
1584
1684
 
1585
 
  length=(uint) strlen(newname)+1;
 
1685
  length=(uint32_t) strlen(newname)+1;
1586
1686
  n_length=uint2korr(fileinfo+4);
1587
1687
  maxlength=uint2korr(fileinfo+6);
1588
1688
  names=uint2korr(fileinfo+8);
1592
1692
  {                                             /* Expand file */
1593
1693
    newpos+=IO_SIZE;
1594
1694
    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 */
 
1695
    endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
 
1696
    bufflength= (uint32_t) (endpos & (IO_SIZE-1));      /* IO_SIZE is a power of 2 */
1597
1697
 
1598
1698
    while (endpos > maxlength)
1599
1699
    {
1600
 
      my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0));
 
1700
      lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
1601
1701
      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));
 
1702
        return(0L);
 
1703
      lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
1605
1704
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1606
 
        return(0);
 
1705
        return(0);
1607
1706
      endpos-=bufflength; bufflength=IO_SIZE;
1608
1707
    }
1609
1708
    memset(buff, 0, IO_SIZE);                   /* Null new block */
1610
 
    my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0));
 
1709
    lseek(file,(ulong) maxlength,SEEK_SET);
1611
1710
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1612
 
        return(0L);
 
1711
      return(0L);
1613
1712
    maxlength+=IO_SIZE;                         /* Fix old ref */
1614
1713
    int2store(fileinfo+6,maxlength);
1615
 
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i-- ;
1616
 
         pos+=4)
 
1714
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
 
1715
         pos+=4)
1617
1716
    {
1618
1717
      endpos=uint4korr(pos)+IO_SIZE;
1619
1718
      int4store(pos,endpos);
1623
1722
  if (n_length == 1 )
1624
1723
  {                                             /* First name */
1625
1724
    length++;
1626
 
    strxmov((char*) buff,"/",newname,"/",NULL);
 
1725
    sprintf((char*)buff,"/%s/",newname);
1627
1726
  }
1628
1727
  else
1629
 
    strxmov((char*) buff,newname,"/",NULL); /* purecov: inspected */
1630
 
  my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0));
 
1728
    sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
 
1729
  lseek(file, 63 + n_length,SEEK_SET);
1631
1730
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1632
1731
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
1633
1732
                         names*4, MYF(MY_NABP+MY_WME))) ||
1636
1735
 
1637
1736
  int2store(fileinfo+8,names+1);
1638
1737
  int2store(fileinfo+4,n_length+length);
1639
 
  (void)ftruncate(file, newpos);/* Append file with '\0' */
 
1738
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
1640
1739
  return(newpos);
1641
1740
} /* make_new_entry */
1642
1741
 
1643
1742
 
1644
1743
        /* error message when opening a form file */
1645
1744
 
1646
 
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
 
1745
void open_table_error(TableShare *share, int error, int db_errno, int errarg)
1647
1746
{
1648
1747
  int err_no;
1649
1748
  char buff[FN_REFLEN];
1656
1755
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1657
1756
    else
1658
1757
    {
1659
 
      strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
1758
      sprintf(buff,"%s",share->normalized_path.str);
1660
1759
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1661
1760
               errortype, buff, db_errno);
1662
1761
    }
1665
1764
  {
1666
1765
    handler *file= 0;
1667
1766
    const char *datext= "";
1668
 
    
 
1767
 
1669
1768
    if (share->db_type() != NULL)
1670
1769
    {
1671
 
      if ((file= get_new_handler(share, current_thd->mem_root,
 
1770
      if ((file= get_new_handler(share, current_session->mem_root,
1672
1771
                                 share->db_type())))
1673
1772
      {
1674
1773
        if (!(datext= *file->bas_ext()))
1677
1776
    }
1678
1777
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1679
1778
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1680
 
    strxmov(buff, share->normalized_path.str, datext, NULL);
 
1779
    sprintf(buff,"%s%s", share->normalized_path.str,datext);
1681
1780
    my_error(err_no,errortype, buff, db_errno);
1682
1781
    delete file;
1683
1782
    break;
1684
1783
  }
1685
1784
  case 5:
1686
1785
  {
1687
 
    const char *csname= get_charset_name((uint) errarg);
 
1786
    const char *csname= get_charset_name((uint32_t) errarg);
1688
1787
    char tmp[10];
1689
1788
    if (!csname || csname[0] =='?')
1690
1789
    {
1692
1791
      csname= tmp;
1693
1792
    }
1694
1793
    my_printf_error(ER_UNKNOWN_COLLATION,
1695
 
                    _("Unknown collation '%s' in table '%-.64s' definition"), 
 
1794
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1696
1795
                    MYF(0), csname, share->table_name.str);
1697
1796
    break;
1698
1797
  }
1699
1798
  case 6:
1700
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
1799
    sprintf(buff,"%s",share->normalized_path.str);
1701
1800
    my_printf_error(ER_NOT_FORM_FILE,
1702
1801
                    _("Table '%-.64s' was created with a different version "
1703
 
                    "of MySQL and cannot be read"), 
 
1802
                    "of Drizzle and cannot be read"),
1704
1803
                    MYF(0), buff);
1705
1804
    break;
1706
1805
  case 8:
1707
1806
    break;
1708
1807
  default:                              /* Better wrong error than none */
1709
1808
  case 4:
1710
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
 
1809
    sprintf(buff,"%s",share->normalized_path.str);
1711
1810
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1712
1811
    break;
1713
1812
  }
1746
1845
    }
1747
1846
    else
1748
1847
      ptr++;
1749
 
    point_to_type->count= (uint) (*array - point_to_type->type_names);
 
1848
    point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
1750
1849
    point_to_type++;
1751
1850
    *((*array)++)= NULL;                /* End of type */
1752
1851
  }
1762
1861
    return 0;
1763
1862
  result->count=strings.elements;
1764
1863
  result->name="";
1765
 
  uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
 
1864
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
1766
1865
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1767
1866
    return 0;
1768
1867
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1778
1877
  return result;
1779
1878
}
1780
1879
 
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
1880
        /* Check that the integer is in the internal */
1817
1881
 
1818
1882
int set_zone(register int nr, int min_zone, int max_zone)
1838
1902
/*
1839
1903
  Store an SQL quoted string.
1840
1904
 
1841
 
  SYNOPSIS  
 
1905
  SYNOPSIS
1842
1906
    append_unescaped()
1843
1907
    res         result String
1844
1908
    pos         string to be quoted
1863
1927
    {
1864
1928
      res->append(pos, mblen);
1865
1929
      pos+= mblen;
 
1930
      if (pos >= end)
 
1931
        break;
1866
1932
      continue;
1867
1933
    }
1868
1934
#endif
1897
1963
}
1898
1964
 
1899
1965
 
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
1966
/*
2017
1967
  Set up column usage bitmaps for a temporary table
2018
1968
 
2052
2002
  return;
2053
2003
}
2054
2004
 
2055
 
int
2056
 
rename_file_ext(const char * from,const char * to,const char * ext)
 
2005
int rename_file_ext(const char * from,const char * to,const char * ext)
2057
2006
{
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)));
 
2007
  string from_s, to_s;
 
2008
 
 
2009
  from_s.append(from);
 
2010
  from_s.append(ext);
 
2011
  to_s.append(to);
 
2012
  to_s.append(ext);
 
2013
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
2062
2014
}
2063
2015
 
2064
2016
 
2118
2070
  length= str.length();
2119
2071
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
2120
2072
    return NULL;
2121
 
  memcpy(to,str.ptr(),(uint) length);
 
2073
  memcpy(to,str.ptr(),(uint32_t) length);
2122
2074
  to[length]=0;
2123
2075
  return to;
2124
2076
}
2129
2081
    that are present in this value, returns the length of the value
2130
2082
*/
2131
2083
uint32_t calculate_key_len(Table *table, uint32_t key,
2132
 
                       const unsigned char *buf __attribute__((unused)),
 
2084
                       const unsigned char *,
2133
2085
                       key_part_map keypart_map)
2134
2086
{
2135
2087
  /* works only with key prefixes */
2206
2158
{
2207
2159
  uint32_t name_length= 0;  // name length in symbols
2208
2160
  bool last_char_is_space= true;
2209
 
  
 
2161
 
2210
2162
  while (*name)
2211
2163
  {
2212
2164
#if defined(USE_MB) && defined(USE_MB_IDENT)
2213
2165
    last_char_is_space= my_isspace(system_charset_info, *name);
2214
2166
    if (use_mb(system_charset_info))
2215
2167
    {
2216
 
      int len=my_ismbchar(system_charset_info, name, 
 
2168
      int len=my_ismbchar(system_charset_info, name,
2217
2169
                          name+system_charset_info->mbmaxlen);
2218
2170
      if (len)
2219
2171
      {
2238
2190
    name_length++;
2239
2191
  }
2240
2192
  /* Error if empty or too long column name */
2241
 
  return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
 
2193
  return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
2242
2194
}
2243
2195
 
2244
2196
 
2274
2226
    /* previous MySQL version */
2275
2227
    if (DRIZZLE_VERSION_ID > s->mysql_version)
2276
2228
    {
2277
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
 
2229
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2278
2230
                      alias, table_f_count, s->fields,
2279
2231
                      s->mysql_version, DRIZZLE_VERSION_ID);
2280
2232
      return(true);
2281
2233
    }
2282
2234
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
2283
2235
    {
2284
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
 
2236
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2285
2237
                      table_f_count, s->fields);
2286
2238
      return(true);
2287
2239
    }
2300
2252
    sql_type.length(0);
2301
2253
    if (i < s->fields)
2302
2254
    {
2303
 
      Field *field= this->field[i];
 
2255
      Field *cur_field= this->field[i];
2304
2256
 
2305
 
      if (strncmp(field->field_name, table_def->name.str,
 
2257
      if (strncmp(cur_field->field_name, table_def->name.str,
2306
2258
                  table_def->name.length))
2307
2259
      {
2308
2260
        /*
2310
2262
          Still this can be a sign of a tampered table, output an error
2311
2263
          to the error log.
2312
2264
        */
2313
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2265
        errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2314
2266
                        "expected column '%s' at position %d, found '%s'."),
2315
2267
                        s->db.str, alias, table_def->name.str, i,
2316
 
                        field->field_name);
 
2268
                        cur_field->field_name);
2317
2269
      }
2318
 
      field->sql_type(sql_type);
 
2270
      cur_field->sql_type(sql_type);
2319
2271
      /*
2320
2272
        Generally, if column types don't match, then something is
2321
2273
        wrong.
2336
2288
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2337
2289
                  table_def->type.length - 1))
2338
2290
      {
2339
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2291
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2292
                      _("Incorrect definition of table %s.%s: "
2340
2293
                        "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());
 
2294
                        "%s, found type %s."),
 
2295
                      s->db.str, alias,
 
2296
                      table_def->name.str, i, table_def->type.str,
 
2297
                      sql_type.c_ptr_safe());
2344
2298
        error= true;
2345
2299
      }
2346
 
      else if (table_def->cset.str && !field->has_charset())
 
2300
      else if (table_def->cset.str && !cur_field->has_charset())
2347
2301
      {
2348
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2302
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2303
                      _("Incorrect definition of table %s.%s: "
2349
2304
                        "expected the type of column '%s' at position %d "
2350
2305
                        "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);
 
2306
                        "character set."),
 
2307
                      s->db.str, alias,
 
2308
                      table_def->name.str, i, table_def->cset.str);
2353
2309
        error= true;
2354
2310
      }
2355
2311
      else if (table_def->cset.str &&
2356
 
               strcmp(field->charset()->csname, table_def->cset.str))
 
2312
               strcmp(cur_field->charset()->csname, table_def->cset.str))
2357
2313
      {
2358
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2314
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2315
                      _("Incorrect definition of table %s.%s: "
2359
2316
                        "expected the type of column '%s' at position %d "
2360
2317
                        "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);
 
2318
                        "character set '%s'."),
 
2319
                      s->db.str, alias,
 
2320
                      table_def->name.str, i, table_def->cset.str,
 
2321
                      cur_field->charset()->csname);
2364
2322
        error= true;
2365
2323
      }
2366
2324
    }
2367
2325
    else
2368
2326
    {
2369
 
      sql_print_error(_("Incorrect definition of table %s.%s: "
 
2327
      errmsg_printf(ERRMSG_LVL_ERROR,
 
2328
                    _("Incorrect definition of table %s.%s: "
2370
2329
                      "expected column '%s' at position %d to have type %s "
2371
2330
                      " but the column is not found."),
2372
 
                      s->db.str, alias,
2373
 
                      table_def->name.str, i, table_def->type.str);
 
2331
                    s->db.str, alias,
 
2332
                    table_def->name.str, i, table_def->type.str);
2374
2333
      error= true;
2375
2334
    }
2376
2335
  }
2388
2347
  DESCRIPTION
2389
2348
    Create Item_field object for each column in the table and
2390
2349
    initialize it with the corresponding Field. New items are
2391
 
    created in the current THD memory root.
 
2350
    created in the current Session memory root.
2392
2351
 
2393
2352
  RETURN VALUE
2394
2353
    0                    success
2453
2412
TableList *TableList::find_underlying_table(Table *table_to_find)
2454
2413
{
2455
2414
  /* is this real table and table which we are looking for? */
2456
 
  if (table == table_to_find && merge_underlying_list == 0)
 
2415
  if (table == table_to_find)
2457
2416
    return this;
2458
2417
 
2459
 
  for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
2460
 
  {
2461
 
    TableList *result;
2462
 
    if ((result= tbl->find_underlying_table(table_to_find)))
2463
 
      return result;
2464
 
  }
2465
 
  return 0;
 
2418
  return NULL;
2466
2419
}
2467
2420
 
2468
 
/*
2469
 
  cleunup items belonged to view fields translation table
2470
 
 
2471
 
  SYNOPSIS
2472
 
    TableList::cleanup_items()
2473
 
*/
2474
 
 
2475
 
void TableList::cleanup_items()
 
2421
 
 
2422
bool TableList::placeholder()
2476
2423
{
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);
 
2424
  return derived || schema_table || (create && !table->getDBStat()) || !table;
2484
2425
}
2485
2426
 
2486
2427
 
2666
2607
 
2667
2608
/*
2668
2609
  Tell handler we are going to call position() and rnd_pos() later.
2669
 
  
 
2610
 
2670
2611
  NOTES:
2671
2612
  This is needed for handlers that uses the primary key to find the
2672
2613
  row. In this case we have to extend the read bitmap with the primary
2679
2620
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
2680
2621
      s->primary_key < MAX_KEY)
2681
2622
  {
2682
 
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
2683
 
    /* signal change */
2684
 
    file->column_bitmaps_signal();
 
2623
    mark_columns_used_by_index_no_reset(s->primary_key);
2685
2624
  }
2686
2625
  return;
2687
2626
}
2726
2665
  key_read= 0;
2727
2666
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
2728
2667
  default_column_bitmaps();
2729
 
  file->column_bitmaps_signal();
2730
2668
  return;
2731
2669
}
2732
2670
 
2735
2673
  mark columns used by key, but don't reset other fields
2736
2674
*/
2737
2675
 
 
2676
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
 
2677
{
 
2678
    mark_columns_used_by_index_no_reset(index, read_set);
 
2679
}
 
2680
 
2738
2681
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
2739
 
                                                   MY_BITMAP *bitmap)
 
2682
                                                MY_BITMAP *bitmap)
2740
2683
{
2741
2684
  KEY_PART_INFO *key_part= key_info[index].key_part;
2742
2685
  KEY_PART_INFO *key_part_end= (key_part +
2761
2704
    We must set bit in read set as update_auto_increment() is using the
2762
2705
    store() to check overflow of auto_increment values
2763
2706
  */
2764
 
  bitmap_set_bit(read_set, found_next_number_field->field_index);
2765
 
  bitmap_set_bit(write_set, found_next_number_field->field_index);
 
2707
  setReadSet(found_next_number_field->field_index);
 
2708
  setWriteSet(found_next_number_field->field_index);
2766
2709
  if (s->next_number_keypart)
2767
 
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
2768
 
  file->column_bitmaps_signal();
 
2710
    mark_columns_used_by_index_no_reset(s->next_number_index);
2769
2711
}
2770
2712
 
2771
2713
 
2789
2731
 
2790
2732
void Table::mark_columns_needed_for_delete()
2791
2733
{
 
2734
  /*
 
2735
    If the handler has no cursor capabilites, or we have row-based
 
2736
    replication active for the current statement, we have to read
 
2737
    either the primary key, the hidden primary key or all columns to
 
2738
    be able to do an delete
 
2739
 
 
2740
  */
 
2741
  if (s->primary_key == MAX_KEY)
 
2742
  {
 
2743
    /* fallback to use all columns in the table to identify row */
 
2744
    use_all_columns();
 
2745
    return;
 
2746
  }
 
2747
  else
 
2748
    mark_columns_used_by_index_no_reset(s->primary_key);
 
2749
 
 
2750
  /* If we the engine wants all predicates we mark all keys */
2792
2751
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2793
2752
  {
2794
2753
    Field **reg_field;
2795
2754
    for (reg_field= field ; *reg_field ; reg_field++)
2796
2755
    {
2797
2756
      if ((*reg_field)->flags & PART_KEY_FLAG)
2798
 
        bitmap_set_bit(read_set, (*reg_field)->field_index);
2799
 
    }
2800
 
    file->column_bitmaps_signal();
2801
 
  }
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))
2804
 
  {
2805
 
    /*
2806
 
      If the handler has no cursor capabilites, or we have row-based
2807
 
      replication active for the current statement, we have to read
2808
 
      either the primary key, the hidden primary key or all columns to
2809
 
      be able to do an delete
2810
 
    */
2811
 
    if (s->primary_key == MAX_KEY)
2812
 
      file->use_hidden_primary_key();
2813
 
    else
2814
 
    {
2815
 
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
2816
 
      file->column_bitmaps_signal();
 
2757
        setReadSet((*reg_field)->field_index);
2817
2758
    }
2818
2759
  }
2819
2760
}
2839
2780
 
2840
2781
void Table::mark_columns_needed_for_update()
2841
2782
{
 
2783
  /*
 
2784
    If the handler has no cursor capabilites, or we have row-based
 
2785
    logging active for the current statement, we have to read either
 
2786
    the primary key, the hidden primary key or all columns to be
 
2787
    able to do an update
 
2788
  */
 
2789
  if (s->primary_key == MAX_KEY)
 
2790
  {
 
2791
    /* fallback to use all columns in the table to identify row */
 
2792
    use_all_columns();
 
2793
    return;
 
2794
  }
 
2795
  else
 
2796
    mark_columns_used_by_index_no_reset(s->primary_key);
 
2797
 
2842
2798
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2843
2799
  {
2844
2800
    /* Mark all used key columns for read */
2846
2802
    for (reg_field= field ; *reg_field ; reg_field++)
2847
2803
    {
2848
2804
      /* Merge keys is all keys that had a column refered to in the query */
2849
 
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
2850
 
        bitmap_set_bit(read_set, (*reg_field)->field_index);
2851
 
    }
2852
 
    file->column_bitmaps_signal();
2853
 
  }
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))
2856
 
  {
2857
 
    /*
2858
 
      If the handler has no cursor capabilites, or we have row-based
2859
 
      logging active for the current statement, we have to read either
2860
 
      the primary key, the hidden primary key or all columns to be
2861
 
      able to do an update
2862
 
    */
2863
 
    if (s->primary_key == MAX_KEY)
2864
 
      file->use_hidden_primary_key();
2865
 
    else
2866
 
    {
2867
 
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
2868
 
      file->column_bitmaps_signal();
2869
 
    }
2870
 
  }
2871
 
  return;
 
2805
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
 
2806
        setReadSet((*reg_field)->field_index);
 
2807
    }
 
2808
  }
 
2809
 
2872
2810
}
2873
2811
 
2874
2812
 
2885
2823
    mark_auto_increment_column();
2886
2824
}
2887
2825
 
 
2826
 
2888
2827
/*
2889
2828
  Cleanup this table for re-execution.
2890
2829
 
2892
2831
    TableList::reinit_before_use()
2893
2832
*/
2894
2833
 
2895
 
void TableList::reinit_before_use(THD *thd)
 
2834
void TableList::reinit_before_use(Session *session)
2896
2835
{
2897
2836
  /*
2898
2837
    Reset old pointers to TABLEs: they are not valid since the tables
2908
2847
  {
2909
2848
    embedded= parent_embedding;
2910
2849
    if (embedded->prep_on_expr)
2911
 
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
 
2850
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
2912
2851
    parent_embedding= embedded->embedding;
2913
2852
  }
2914
2853
  while (parent_embedding &&
2920
2859
 
2921
2860
  SYNOPSIS
2922
2861
    TableList::containing_subselect()
2923
 
 
 
2862
 
2924
2863
  RETURN
2925
2864
    Subselect item for the subquery that contains the FROM list
2926
2865
    this table is taken from if there is any
2929
2868
*/
2930
2869
 
2931
2870
Item_subselect *TableList::containing_subselect()
2932
 
{    
 
2871
{
2933
2872
  return (select_lex ? select_lex->master_unit()->item : 0);
2934
2873
}
2935
2874
 
2941
2880
      table         the Table to operate on.
2942
2881
 
2943
2882
  DESCRIPTION
2944
 
    The parser collects the index hints for each table in a "tagged list" 
 
2883
    The parser collects the index hints for each table in a "tagged list"
2945
2884
    (TableList::index_hints). Using the information in this tagged list
2946
 
    this function sets the members Table::keys_in_use_for_query, 
 
2885
    this function sets the members Table::keys_in_use_for_query,
2947
2886
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
2948
2887
    Table::force_index and Table::covering_keys.
2949
2888
 
2950
2889
    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 
 
2890
    and USE INDEX, so this is checked here. Then the FORCE INDEX list
2952
2891
    (if non-empty) is appended to the USE INDEX list and a flag is set.
2953
2892
 
2954
 
    Multiple hints of the same kind are processed so that each clause 
 
2893
    Multiple hints of the same kind are processed so that each clause
2955
2894
    is applied to what is computed in the previous clause.
2956
2895
    For example:
2957
2896
        USE INDEX (i1) USE INDEX (i2)
2958
2897
    is equivalent to
2959
2898
        USE INDEX (i1,i2)
2960
2899
    and means "consider only i1 and i2".
2961
 
        
 
2900
 
2962
2901
    Similarly
2963
2902
        USE INDEX () USE INDEX (i1)
2964
2903
    is equivalent to
2967
2906
 
2968
2907
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
2969
2908
    not an error.
2970
 
        
 
2909
 
2971
2910
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
2972
2911
    order:
2973
2912
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
2976
2915
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
2977
2916
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
2978
2917
 
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, 
 
2918
    As an optimization if there is a covering index, and we have
 
2919
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
2981
2920
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
2982
2921
 
2983
2922
  RETURN VALUE
2987
2926
bool TableList::process_index_hints(Table *tbl)
2988
2927
{
2989
2928
  /* initialize the result variables */
2990
 
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
 
2929
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
2991
2930
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
2992
2931
 
2993
2932
  /* index hint list processing */
2998
2937
    key_map index_group[INDEX_HINT_FORCE + 1];
2999
2938
    Index_hint *hint;
3000
2939
    int type;
3001
 
    bool have_empty_use_join= false, have_empty_use_order= false, 
 
2940
    bool have_empty_use_join= false, have_empty_use_order= false,
3002
2941
         have_empty_use_group= false;
3003
2942
    List_iterator <Index_hint> iter(*index_hints);
3004
2943
 
3005
2944
    /* initialize temporary variables used to collect hints of each kind */
3006
2945
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
3007
2946
    {
3008
 
      index_join[type].clear_all();
3009
 
      index_order[type].clear_all();
3010
 
      index_group[type].clear_all();
 
2947
      index_join[type].reset();
 
2948
      index_order[type].reset();
 
2949
      index_group[type].reset();
3011
2950
    }
3012
2951
 
3013
2952
    /* iterate over the hints list */
3020
2959
      {
3021
2960
        if (hint->clause & INDEX_HINT_MASK_JOIN)
3022
2961
        {
3023
 
          index_join[hint->type].clear_all();
 
2962
          index_join[hint->type].reset();
3024
2963
          have_empty_use_join= true;
3025
2964
        }
3026
2965
        if (hint->clause & INDEX_HINT_MASK_ORDER)
3027
2966
        {
3028
 
          index_order[hint->type].clear_all();
 
2967
          index_order[hint->type].reset();
3029
2968
          have_empty_use_order= true;
3030
2969
        }
3031
2970
        if (hint->clause & INDEX_HINT_MASK_GROUP)
3032
2971
        {
3033
 
          index_group[hint->type].clear_all();
 
2972
          index_group[hint->type].reset();
3034
2973
          have_empty_use_group= true;
3035
2974
        }
3036
2975
        continue;
3037
2976
      }
3038
2977
 
3039
 
      /* 
3040
 
        Check if an index with the given name exists and get his offset in 
3041
 
        the keys bitmask for the table 
 
2978
      /*
 
2979
        Check if an index with the given name exists and get his offset in
 
2980
        the keys bitmask for the table
3042
2981
      */
3043
2982
      if (tbl->s->keynames.type_names == 0 ||
3044
2983
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
3052
2991
 
3053
2992
      /* add to the appropriate clause mask */
3054
2993
      if (hint->clause & INDEX_HINT_MASK_JOIN)
3055
 
        index_join[hint->type].set_bit (pos);
 
2994
        index_join[hint->type].set(pos);
3056
2995
      if (hint->clause & INDEX_HINT_MASK_ORDER)
3057
 
        index_order[hint->type].set_bit (pos);
 
2996
        index_order[hint->type].set(pos);
3058
2997
      if (hint->clause & INDEX_HINT_MASK_GROUP)
3059
 
        index_group[hint->type].set_bit (pos);
 
2998
        index_group[hint->type].set(pos);
3060
2999
    }
3061
3000
 
3062
3001
    /* cannot mix USE INDEX and FORCE INDEX */
3063
 
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3064
 
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3065
 
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
3066
 
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
3067
 
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
3068
 
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
 
3002
    if ((index_join[INDEX_HINT_FORCE].any() ||
 
3003
         index_order[INDEX_HINT_FORCE].any() ||
 
3004
         index_group[INDEX_HINT_FORCE].any()) &&
 
3005
        (index_join[INDEX_HINT_USE].any() ||  have_empty_use_join ||
 
3006
         index_order[INDEX_HINT_USE].any() || have_empty_use_order ||
 
3007
         index_group[INDEX_HINT_USE].any() || have_empty_use_group))
3069
3008
    {
3070
3009
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
3071
3010
               index_hint_type_name[INDEX_HINT_FORCE]);
3073
3012
    }
3074
3013
 
3075
3014
    /* process FORCE INDEX as USE INDEX with a flag */
3076
 
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3077
 
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3078
 
        !index_group[INDEX_HINT_FORCE].is_clear_all())
 
3015
    if (index_join[INDEX_HINT_FORCE].any() ||
 
3016
        index_order[INDEX_HINT_FORCE].any() ||
 
3017
        index_group[INDEX_HINT_FORCE].any())
3079
3018
    {
3080
3019
      tbl->force_index= true;
3081
 
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
3082
 
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
3083
 
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
 
3020
      index_join[INDEX_HINT_USE]|= index_join[INDEX_HINT_FORCE];
 
3021
      index_order[INDEX_HINT_USE]|= index_order[INDEX_HINT_FORCE];
 
3022
      index_group[INDEX_HINT_USE]|= index_group[INDEX_HINT_FORCE];
3084
3023
    }
3085
3024
 
3086
3025
    /* apply USE INDEX */
3087
 
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
3088
 
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
3089
 
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
3090
 
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
3091
 
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
3092
 
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
 
3026
    if (index_join[INDEX_HINT_USE].any() || have_empty_use_join)
 
3027
      tbl->keys_in_use_for_query&= index_join[INDEX_HINT_USE];
 
3028
    if (index_order[INDEX_HINT_USE].any() || have_empty_use_order)
 
3029
      tbl->keys_in_use_for_order_by&= index_order[INDEX_HINT_USE];
 
3030
    if (index_group[INDEX_HINT_USE].any() || have_empty_use_group)
 
3031
      tbl->keys_in_use_for_group_by&= index_group[INDEX_HINT_USE];
3093
3032
 
3094
3033
    /* apply IGNORE INDEX */
3095
 
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
3096
 
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
3097
 
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
 
3034
    key_map_subtract(tbl->keys_in_use_for_query, index_join[INDEX_HINT_IGNORE]);
 
3035
    key_map_subtract(tbl->keys_in_use_for_order_by, index_order[INDEX_HINT_IGNORE]);
 
3036
    key_map_subtract(tbl->keys_in_use_for_group_by, index_group[INDEX_HINT_IGNORE]);
3098
3037
  }
3099
3038
 
3100
3039
  /* make sure covering_keys don't include indexes disabled with a hint */
3101
 
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
 
3040
  tbl->covering_keys&= tbl->keys_in_use_for_query;
3102
3041
  return 0;
3103
3042
}
3104
3043
 
3119
3058
  return length;
3120
3059
}
3121
3060
 
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
3061
/****************************************************************************
3166
3062
 Functions for creating temporary tables.
3167
3063
****************************************************************************/
3168
3064
 
3169
3065
 
3170
3066
/* Prototypes */
3171
 
void free_tmp_table(THD *thd, Table *entry);
 
3067
void free_tmp_table(Session *session, Table *entry);
3172
3068
 
3173
3069
/**
3174
3070
  Create field for temporary table from given field.
3175
3071
 
3176
 
  @param thd           Thread handler
 
3072
  @param session               Thread handler
3177
3073
  @param org_field    field from which new field will be created
3178
3074
  @param name         New field name
3179
3075
  @param table         Temporary table
3192
3088
    new_created field
3193
3089
*/
3194
3090
 
3195
 
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
 
3091
Field *create_tmp_field_from_field(Session *session, Field *org_field,
3196
3092
                                   const char *name, Table *table,
3197
3093
                                   Item_field *item, uint32_t convert_blob_length)
3198
3094
{
3199
3095
  Field *new_field;
3200
3096
 
3201
 
  /* 
3202
 
    Make sure that the blob fits into a Field_varstring which has 
3203
 
    2-byte lenght. 
 
3097
  /*
 
3098
    Make sure that the blob fits into a Field_varstring which has
 
3099
    2-byte lenght.
3204
3100
  */
3205
3101
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
3206
3102
      (org_field->flags & BLOB_FLAG))
3209
3105
                                   org_field->field_name, table->s,
3210
3106
                                   org_field->charset());
3211
3107
  else
3212
 
    new_field= org_field->new_field(thd->mem_root, table,
 
3108
    new_field= org_field->new_field(session->mem_root, table,
3213
3109
                                    table == org_field->table);
3214
3110
  if (new_field)
3215
3111
  {
3230
3126
  return new_field;
3231
3127
}
3232
3128
 
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
3129
 
3368
3130
/**
3369
3131
  Create field for information schema table.
3370
3132
 
3371
 
  @param thd            Thread handler
 
3133
  @param session                Thread handler
3372
3134
  @param table          Temporary table
3373
3135
  @param item           Item to create a field for
3374
3136
 
3378
3140
    new_created field
3379
3141
*/
3380
3142
 
3381
 
Field *create_tmp_field_for_schema(THD *thd __attribute__((unused)),
3382
 
                                   Item *item, Table *table)
 
3143
Field *create_tmp_field_for_schema(Item *item, Table *table)
3383
3144
{
3384
3145
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
3385
3146
  {
3400
3161
 
3401
3162
 
3402
3163
/**
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
3164
  Create a temp table according to a field list.
3528
3165
 
3529
3166
  Given field pointers are changed to point at tmp_table for
3534
3171
  corresponding Item_field items, pointing at the fields in the
3535
3172
  temporary table, unless this was prohibited by true
3536
3173
  value of argument save_sum_fields. The Item_field objects
3537
 
  are created in THD memory root.
 
3174
  are created in Session memory root.
3538
3175
 
3539
 
  @param thd                  thread handle
 
3176
  @param session                  thread handle
3540
3177
  @param param                a description used as input to create the table
3541
3178
  @param fields               list of items that will be used to define
3542
3179
                              column types of the table (also see NOTES)
3552
3189
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
3553
3190
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
3554
3191
#define RATIO_TO_PACK_ROWS             2
3555
 
#define MIN_STRING_LENGTH_TO_PACK_ROWS   10
3556
3192
 
3557
3193
Table *
3558
 
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
 
3194
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
3559
3195
                 order_st *group, bool distinct, bool save_sum_fields,
3560
3196
                 uint64_t select_options, ha_rows rows_limit,
3561
3197
                 char *table_alias)
3562
3198
{
3563
3199
  MEM_ROOT *mem_root_save, own_root;
3564
3200
  Table *table;
3565
 
  TABLE_SHARE *share;
 
3201
  TableShare *share;
3566
3202
  uint  i,field_count,null_count,null_pack_length;
3567
3203
  uint32_t  copy_func_count= param->func_count;
3568
3204
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
3586
3222
  uint32_t total_uneven_bit_length= 0;
3587
3223
  bool force_copy_fields= param->force_copy_fields;
3588
3224
 
3589
 
  status_var_increment(thd->status_var.created_tmp_tables);
 
3225
  status_var_increment(session->status_var.created_tmp_tables);
3590
3226
 
3591
3227
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
3592
3228
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
3593
3229
 
3594
3230
  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);
 
3231
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
 
3232
            (unsigned long)current_pid, temp_pool_slot);
3597
3233
  else
3598
3234
  {
3599
3235
    /* 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++);
 
3236
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
3237
            session->thread_id, session->tmp_table++);
3602
3238
  }
3603
3239
 
3604
3240
  /*
3605
3241
    No need to change table name to lower case as we are only creating
3606
3242
    MyISAM or HEAP tables here
3607
3243
  */
3608
 
  fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3244
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
3609
3245
 
3610
3246
 
3611
3247
  if (group)
3637
3273
    When loose index scan is employed as access method, it already
3638
3274
    computes all groups and the result of all aggregate functions. We
3639
3275
    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
 
3276
    functions Tmp_Table_Param::items_to_copy, so that the values of
3641
3277
    these items are stored in the temporary table.
3642
3278
  */
3643
3279
  if (param->precomputed_group_by)
3644
3280
    copy_func_count+= param->sum_func_count;
3645
 
  
 
3281
 
3646
3282
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
3647
3283
 
3648
3284
  if (!multi_alloc_root(&own_root,
3650
3286
                        &share, sizeof(*share),
3651
3287
                        &reg_field, sizeof(Field*) * (field_count+1),
3652
3288
                        &default_field, sizeof(Field*) * (field_count),
3653
 
                        &blob_field, sizeof(uint)*(field_count+1),
 
3289
                        &blob_field, sizeof(uint32_t)*(field_count+1),
3654
3290
                        &from_field, sizeof(Field*)*field_count,
3655
3291
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
3656
3292
                        &param->keyinfo, sizeof(*param->keyinfo),
3658
3294
                        sizeof(*key_part_info)*(param->group_parts+1),
3659
3295
                        &param->start_recinfo,
3660
3296
                        sizeof(*param->recinfo)*(field_count*2+4),
3661
 
                        &tmpname, (uint) strlen(path)+1,
 
3297
                        &tmpname, (uint32_t) strlen(path)+1,
3662
3298
                        &group_buff, (group && ! using_unique_constraint ?
3663
3299
                                      param->group_length : 0),
3664
3300
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3666
3302
  {
3667
3303
    if (temp_pool_slot != MY_BIT_NONE)
3668
3304
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3669
 
    return(NULL);                               /* purecov: inspected */
 
3305
    return NULL;                                /* purecov: inspected */
3670
3306
  }
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]))
 
3307
  /* Copy_field belongs to Tmp_Table_Param, allocate it in Session mem_root */
 
3308
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
3673
3309
  {
3674
3310
    if (temp_pool_slot != MY_BIT_NONE)
3675
3311
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3676
3312
    free_root(&own_root, MYF(0));               /* purecov: inspected */
3677
 
    return(NULL);                               /* purecov: inspected */
 
3313
    return NULL;                                /* purecov: inspected */
3678
3314
  }
3679
3315
  param->items_to_copy= copy_func;
3680
 
  my_stpcpy(tmpname,path);
 
3316
  strcpy(tmpname,path);
3681
3317
  /* make table according to fields */
3682
3318
 
3683
3319
  memset(table, 0, sizeof(*table));
3686
3322
  memset(from_field, 0, sizeof(Field*)*field_count);
3687
3323
 
3688
3324
  table->mem_root= own_root;
3689
 
  mem_root_save= thd->mem_root;
3690
 
  thd->mem_root= &table->mem_root;
 
3325
  mem_root_save= session->mem_root;
 
3326
  session->mem_root= &table->mem_root;
3691
3327
 
3692
3328
  table->field=reg_field;
3693
3329
  table->alias= table_alias;
3696
3332
  table->map=1;
3697
3333
  table->temp_pool_slot = temp_pool_slot;
3698
3334
  table->copy_blobs= 1;
3699
 
  table->in_use= thd;
3700
 
  table->quick_keys.init();
3701
 
  table->covering_keys.init();
3702
 
  table->keys_in_use_for_query.init();
 
3335
  table->in_use= session;
 
3336
  table->quick_keys.reset();
 
3337
  table->covering_keys.reset();
 
3338
  table->keys_in_use_for_query.reset();
3703
3339
 
3704
3340
  table->setShare(share);
3705
 
  init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
 
3341
  share->init(tmpname, tmpname);
3706
3342
  share->blob_field= blob_field;
3707
3343
  share->blob_ptr_size= portable_sizeof_char_ptr;
3708
3344
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
3709
3345
  share->table_charset= param->table_charset;
3710
3346
  share->primary_key= MAX_KEY;               // Indicate no primary key
3711
 
  share->keys_for_keyread.init();
3712
 
  share->keys_in_use.init();
 
3347
  share->keys_for_keyread.reset();
 
3348
  share->keys_in_use.reset();
3713
3349
 
3714
3350
  /* Calculate which type of fields we will store in the temporary table */
3715
3351
 
3754
3390
        if (!arg->const_item())
3755
3391
        {
3756
3392
          Field *new_field=
3757
 
            create_tmp_field(thd, table, arg, arg->type(), &copy_func,
 
3393
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
3758
3394
                             tmp_from_field, &default_field[fieldnr],
3759
3395
                             group != 0,not_all_columns,
3760
3396
                             distinct, 0,
3774
3410
            string_count++;
3775
3411
            string_total_length+= new_field->pack_length();
3776
3412
          }
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;
 
3413
          session->mem_root= mem_root_save;
 
3414
          session->change_item_tree(argp, new Item_field(new_field));
 
3415
          session->mem_root= &table->mem_root;
3780
3416
          if (!(new_field->flags & NOT_NULL_FLAG))
3781
3417
          {
3782
3418
            null_count++;
3803
3439
        that in the later case group is set to the row pointer.
3804
3440
      */
3805
3441
      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,
 
3442
        create_tmp_field_for_schema(item, table) :
 
3443
        create_tmp_field(session, table, item, type, &copy_func,
3808
3444
                         tmp_from_field, &default_field[fieldnr],
3809
3445
                         group != 0,
3810
3446
                         !force_copy_fields &&
3822
3458
 
3823
3459
      if (!new_field)
3824
3460
      {
3825
 
        if (thd->is_fatal_error)
 
3461
        if (session->is_fatal_error)
3826
3462
          goto err;                             // Got OOM
3827
3463
        continue;                               // Some kindf of const item
3828
3464
      }
3860
3496
      null_count= 0;
3861
3497
    }
3862
3498
  }
3863
 
  assert(fieldnr == (uint) (reg_field - table->field));
3864
 
  assert(field_count >= (uint) (reg_field - table->field));
 
3499
  assert(fieldnr == (uint32_t) (reg_field - table->field));
 
3500
  assert(field_count >= (uint32_t) (reg_field - table->field));
3865
3501
  field_count= fieldnr;
3866
3502
  *reg_field= 0;
3867
3503
  *blob_field= 0;                               // End marker
3873
3509
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3874
3510
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
3875
3511
  {
3876
 
    share->db_plugin= ha_lock_engine(0, myisam_hton);
 
3512
    share->storage_engine= myisam_engine;
3877
3513
    table->file= get_new_handler(share, &table->mem_root,
3878
3514
                                 share->db_type());
3879
3515
    if (group &&
3883
3519
  }
3884
3520
  else
3885
3521
  {
3886
 
    share->db_plugin= ha_lock_engine(0, heap_hton);
 
3522
    share->storage_engine= heap_engine;
3887
3523
    table->file= get_new_handler(share, &table->mem_root,
3888
3524
                                 share->db_type());
3889
3525
  }
3924
3560
    share->default_values= table->record[1]+alloc_length;
3925
3561
  }
3926
3562
  copy_func[0]=0;                               // End marker
3927
 
  param->func_count= copy_func - param->items_to_copy; 
 
3563
  param->func_count= copy_func - param->items_to_copy;
3928
3564
 
3929
3565
  table->setup_tmp_table_column_bitmaps(bitmaps);
3930
3566
 
3984
3620
    */
3985
3621
    if (default_field[i] && default_field[i]->ptr)
3986
3622
    {
3987
 
      /* 
 
3623
      /*
3988
3624
         default_field[i] is set only in the cases  when 'field' can
3989
3625
         inherit the default value that is defined for the field referred
3990
3626
         by the Item_field object from which 'field' has been created.
4003
3639
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
4004
3640
      }
4005
3641
      orig_field->move_field_offset(-diff);     // Back to record[0]
4006
 
    } 
 
3642
    }
4007
3643
 
4008
3644
    if (from_field[i])
4009
3645
    {                                           /* Not a table Item */
4028
3664
 
4029
3665
  param->copy_field_end=copy;
4030
3666
  param->recinfo=recinfo;
4031
 
  store_record(table,s->default_values);        // Make empty default record
 
3667
  table->storeRecordAsDefault();        // Make empty default record
4032
3668
 
4033
 
  if (thd->variables.tmp_table_size == ~ (uint64_t) 0)          // No limit
 
3669
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
4034
3670
    share->max_rows= ~(ha_rows) 0;
4035
3671
  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) /
 
3672
    share->max_rows= (ha_rows) (((share->db_type() == heap_engine) ?
 
3673
                                 cmin(session->variables.tmp_table_size,
 
3674
                                     session->variables.max_heap_table_size) :
 
3675
                                 session->variables.tmp_table_size) /
4040
3676
                                 share->reclength);
4041
 
  set_if_bigger(share->max_rows,1);             // For dummy start options
 
3677
  set_if_bigger(share->max_rows,(ha_rows)1);    // For dummy start options
4042
3678
  /*
4043
3679
    Push the LIMIT clause to the temporary table creation, so that we
4044
3680
    materialize only up to 'rows_limit' records instead of all result records.
4080
3716
      if (!using_unique_constraint)
4081
3717
      {
4082
3718
        cur_group->buff=(char*) group_buff;
4083
 
        if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
 
3719
        if (!(cur_group->field= field->new_key_field(session->mem_root,table,
4084
3720
                                                     group_buff +
4085
3721
                                                     test(maybe_null),
4086
3722
                                                     field->null_ptr,
4096
3732
          */
4097
3733
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
4098
3734
          key_part_info->null_bit=field->null_bit;
4099
 
          key_part_info->null_offset= (uint) (field->null_ptr -
 
3735
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
4100
3736
                                              (unsigned char*) table->record[0]);
4101
3737
          cur_group->buff++;                        // Pointer to field data
4102
3738
          group_buff++;                         // Skipp null flag
4158
3794
                                                (uint32_t) key_part_info->length,
4159
3795
                                                0,
4160
3796
                                                (unsigned char*) 0,
4161
 
                                                (uint) 0,
 
3797
                                                (uint32_t) 0,
4162
3798
                                                Field::NONE,
4163
 
                                                NULL, 
 
3799
                                                NULL,
4164
3800
                                                table->s,
4165
3801
                                                &my_charset_bin);
4166
3802
      if (!key_part_info->field)
4191
3827
 
4192
3828
      if ((*reg_field)->real_maybe_null())
4193
3829
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
4194
 
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB || 
 
3830
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB ||
4195
3831
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
4196
3832
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
4197
3833
 
4204
3840
    }
4205
3841
  }
4206
3842
 
4207
 
  if (thd->is_fatal_error)                              // If end of memory
 
3843
  if (session->is_fatal_error)                          // If end of memory
4208
3844
    goto err;                                    /* purecov: inspected */
4209
3845
  share->db_record_offset= 1;
4210
 
  if (share->db_type() == myisam_hton)
 
3846
  if (share->db_type() == myisam_engine)
4211
3847
  {
4212
3848
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
4213
3849
                                       &param->recinfo, select_options))
4216
3852
  if (table->open_tmp_table())
4217
3853
    goto err;
4218
3854
 
4219
 
  thd->mem_root= mem_root_save;
 
3855
  session->mem_root= mem_root_save;
4220
3856
 
4221
3857
  return(table);
4222
3858
 
4223
3859
err:
4224
 
  thd->mem_root= mem_root_save;
4225
 
  table->free_tmp_table(thd);                    /* purecov: inspected */
 
3860
  session->mem_root= mem_root_save;
 
3861
  table->free_tmp_table(session);                    /* purecov: inspected */
4226
3862
  if (temp_pool_slot != MY_BIT_NONE)
4227
3863
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4228
 
  return(NULL);                         /* purecov: inspected */
 
3864
  return NULL;                          /* purecov: inspected */
4229
3865
}
4230
3866
 
4231
3867
/****************************************************************************/
4239
3875
    The sole purpose of this Table object is to use the power of Field
4240
3876
    class to read/write data to/from table->record[0]. Then one can store
4241
3877
    the record in any container (RB tree, hash, etc).
4242
 
    The table is created in THD mem_root, so are the table's fields.
 
3878
    The table is created in Session mem_root, so are the table's fields.
4243
3879
    Consequently, if you don't BLOB fields, you don't need to free it.
4244
3880
 
4245
 
  @param thd         connection handle
 
3881
  @param session         connection handle
4246
3882
  @param field_list  list of column definitions
4247
3883
 
4248
3884
  @return
4249
3885
    0 if out of memory, Table object in case of success
4250
3886
*/
4251
3887
 
4252
 
Table *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
 
3888
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4253
3889
{
4254
3890
  uint32_t field_count= field_list.elements;
4255
3891
  uint32_t blob_count= 0;
4261
3897
  uint32_t *blob_field;
4262
3898
  unsigned char *bitmaps;
4263
3899
  Table *table;
4264
 
  TABLE_SHARE *share;
 
3900
  TableShare *share;
4265
3901
 
4266
 
  if (!multi_alloc_root(thd->mem_root,
 
3902
  if (!multi_alloc_root(session->mem_root,
4267
3903
                        &table, sizeof(*table),
4268
3904
                        &share, sizeof(*share),
4269
3905
                        &field, (field_count + 1) * sizeof(Field*),
4270
 
                        &blob_field, (field_count+1) *sizeof(uint),
 
3906
                        &blob_field, (field_count+1) *sizeof(uint32_t),
4271
3907
                        &bitmaps, bitmap_buffer_size(field_count)*2,
4272
3908
                        NULL))
4273
3909
    return 0;
4285
3921
  List_iterator_fast<Create_field> it(field_list);
4286
3922
  while ((cdef= it++))
4287
3923
  {
4288
 
    *field= make_field(share, 0, cdef->length,
 
3924
    *field= make_field(share, NULL, 0, cdef->length,
4289
3925
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4290
3926
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
4291
3927
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
4299
3935
      null_count++;
4300
3936
 
4301
3937
    if ((*field)->flags & BLOB_FLAG)
4302
 
      share->blob_field[blob_count++]= (uint) (field - table->field);
 
3938
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
4303
3939
 
4304
3940
    field++;
4305
3941
  }
4310
3946
  null_pack_length= (null_count + 7)/8;
4311
3947
  share->reclength= record_length + null_pack_length;
4312
3948
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4313
 
  table->record[0]= (unsigned char*) thd->alloc(share->rec_buff_length);
 
3949
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4314
3950
  if (!table->record[0])
4315
3951
    goto error;
4316
3952
 
4321
3957
    share->null_bytes= null_pack_length;
4322
3958
  }
4323
3959
 
4324
 
  table->in_use= thd;           /* field->reset() may access table->in_use */
 
3960
  table->in_use= session;           /* field->reset() may access table->in_use */
4325
3961
  {
4326
3962
    /* Set up field pointers */
4327
3963
    unsigned char *null_pos= table->record[0];
4380
4016
      start_recinfo   MyISAM's column descriptions
4381
4017
      recinfo INOUT   End of MyISAM's column descriptions
4382
4018
      options         Option bits
4383
 
   
 
4019
 
4384
4020
  DESCRIPTION
4385
4021
    Create a MyISAM temporary table according to passed description. The is
4386
4022
    assumed to have one unique index or constraint.
4391
4027
         when there are many nullable columns)
4392
4028
      2. Table columns
4393
4029
      3. One free MI_COLUMNDEF element (*recinfo points here)
4394
 
   
 
4030
 
4395
4031
    This function may use the free element to create hash column for unique
4396
4032
    constraint.
4397
4033
 
4400
4036
     true  - Error
4401
4037
*/
4402
4038
 
4403
 
bool Table::create_myisam_tmp_table(KEY *keyinfo, 
 
4039
bool Table::create_myisam_tmp_table(KEY *keyinfo,
4404
4040
                                    MI_COLUMNDEF *start_recinfo,
4405
 
                                    MI_COLUMNDEF **recinfo, 
 
4041
                                    MI_COLUMNDEF **recinfo,
4406
4042
                                    uint64_t options)
4407
4043
{
4408
4044
  int error;
4409
4045
  MI_KEYDEF keydef;
4410
4046
  MI_UNIQUEDEF uniquedef;
4411
 
  TABLE_SHARE *share= s;
 
4047
  TableShare *share= s;
4412
4048
 
4413
4049
  if (share->keys)
4414
4050
  {                                             // Get keys for ni_create
4449
4085
    }
4450
4086
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4451
4087
    {
4452
 
      Field *field=keyinfo->key_part[i].field;
 
4088
      Field *key_field=keyinfo->key_part[i].field;
4453
4089
      seg->flag=     0;
4454
 
      seg->language= field->charset()->number;
 
4090
      seg->language= key_field->charset()->number;
4455
4091
      seg->length=   keyinfo->key_part[i].length;
4456
4092
      seg->start=    keyinfo->key_part[i].offset;
4457
 
      if (field->flags & BLOB_FLAG)
 
4093
      if (key_field->flags & BLOB_FLAG)
4458
4094
      {
4459
4095
        seg->type=
4460
4096
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4461
4097
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4462
 
        seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
 
4098
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
4099
                                  - share->blob_ptr_size);
4463
4100
        seg->flag= HA_BLOB_PART;
4464
4101
        seg->length=0;                  // Whole blob in unique constraint
4465
4102
      }
4467
4104
      {
4468
4105
        seg->type= keyinfo->key_part[i].type;
4469
4106
      }
4470
 
      if (!(field->flags & NOT_NULL_FLAG))
 
4107
      if (!(key_field->flags & NOT_NULL_FLAG))
4471
4108
      {
4472
 
        seg->null_bit= field->null_bit;
4473
 
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) record[0]);
 
4109
        seg->null_bit= key_field->null_bit;
 
4110
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
4474
4111
        /*
4475
4112
          We are using a GROUP BY on something that contains NULL
4476
4113
          In this case we have to tell MyISAM that two NULL should
4489
4126
    create_info.data_file_length= ~(uint64_t) 0;
4490
4127
 
4491
4128
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4492
 
                       (uint) (*recinfo-start_recinfo),
 
4129
                       (uint32_t) (*recinfo-start_recinfo),
4493
4130
                       start_recinfo,
4494
4131
                       share->uniques, &uniquedef,
4495
4132
                       &create_info,
4507
4144
}
4508
4145
 
4509
4146
 
4510
 
void Table::free_tmp_table(THD *thd)
 
4147
void Table::free_tmp_table(Session *session)
4511
4148
{
4512
4149
  MEM_ROOT own_root= mem_root;
4513
4150
  const char *save_proc_info;
4514
4151
 
4515
 
  save_proc_info=thd->get_proc_info();
4516
 
  thd_proc_info(thd, "removing tmp table");
 
4152
  save_proc_info=session->get_proc_info();
 
4153
  session->set_proc_info("removing tmp table");
 
4154
 
 
4155
  // Release latches since this can take a long time
 
4156
  ha_release_temporary_latches(session);
4517
4157
 
4518
4158
  if (file)
4519
4159
  {
4532
4172
  if (temp_pool_slot != MY_BIT_NONE)
4533
4173
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4534
4174
 
4535
 
  plugin_unlock(0, s->db_plugin);
4536
 
 
4537
4175
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4538
 
  thd_proc_info(thd, save_proc_info);
 
4176
  session->set_proc_info(save_proc_info);
4539
4177
 
4540
4178
  return;
4541
4179
}
4545
4183
  to this.
4546
4184
*/
4547
4185
 
4548
 
bool create_myisam_from_heap(THD *thd, Table *table,
 
4186
bool create_myisam_from_heap(Session *session, Table *table,
4549
4187
                             MI_COLUMNDEF *start_recinfo,
4550
 
                             MI_COLUMNDEF **recinfo, 
 
4188
                             MI_COLUMNDEF **recinfo,
4551
4189
                             int error, bool ignore_last_dupp_key_error)
4552
4190
{
4553
4191
  Table new_table;
4554
 
  TABLE_SHARE share;
 
4192
  TableShare share;
4555
4193
  const char *save_proc_info;
4556
4194
  int write_err;
4557
4195
 
4558
 
  if (table->s->db_type() != heap_hton || 
 
4196
  if (table->s->db_type() != heap_engine ||
4559
4197
      error != HA_ERR_RECORD_FILE_FULL)
4560
4198
  {
4561
4199
    table->file->print_error(error,MYF(0));
4562
4200
    return(1);
4563
4201
  }
 
4202
 
 
4203
  // Release latches since this can take a long time
 
4204
  ha_release_temporary_latches(session);
 
4205
 
4564
4206
  new_table= *table;
4565
4207
  share= *table->s;
4566
4208
  new_table.s= &share;
4567
 
  new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
 
4209
  new_table.s->storage_engine= myisam_engine;
4568
4210
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4569
4211
                                        new_table.s->db_type())))
4570
4212
    return(1);                          // End of memory
4571
4213
 
4572
 
  save_proc_info=thd->get_proc_info();
4573
 
  thd_proc_info(thd, "converting HEAP to MyISAM");
 
4214
  save_proc_info=session->get_proc_info();
 
4215
  session->set_proc_info("converting HEAP to MyISAM");
4574
4216
 
4575
4217
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4576
 
                                        recinfo, thd->lex->select_lex.options | 
4577
 
                                        thd->options))
 
4218
                                        recinfo, session->lex->select_lex.options |
 
4219
                                        session->options))
4578
4220
    goto err2;
4579
4221
  if (new_table.open_tmp_table())
4580
4222
    goto err1;
4588
4230
    new_table.no_rows=1;
4589
4231
  }
4590
4232
 
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
4233
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4600
4234
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4601
 
#endif
4602
4235
 
4603
4236
  /*
4604
4237
    copy all old rows from heap table to MyISAM table
4624
4257
  (void) table->file->close();                  // This deletes the table !
4625
4258
  delete table->file;
4626
4259
  table->file=0;
4627
 
  plugin_unlock(0, table->s->db_plugin);
4628
 
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
4629
4260
  new_table.s= table->s;                       // Keep old share
4630
4261
  *table= new_table;
4631
4262
  *table->s= share;
4632
 
  
 
4263
 
4633
4264
  table->file->change_table_ptr(table, table->s);
4634
4265
  table->use_all_columns();
4635
4266
  if (save_proc_info)
4637
4268
    const char *new_proc_info=
4638
4269
      (!strcmp(save_proc_info,"Copying to tmp table") ?
4639
4270
      "Copying to tmp table on disk" : save_proc_info);
4640
 
    thd_proc_info(thd, new_proc_info);
 
4271
    session->set_proc_info(new_proc_info);
4641
4272
  }
4642
4273
  return(0);
4643
4274
 
4649
4280
  new_table.file->ha_delete_table(new_table.s->table_name.str);
4650
4281
 err2:
4651
4282
  delete new_table.file;
4652
 
  thd_proc_info(thd, save_proc_info);
 
4283
  session->set_proc_info(save_proc_info);
4653
4284
  table->mem_root= new_table.mem_root;
4654
4285
  return(1);
4655
4286
}
4670
4301
{
4671
4302
  uint32_t min_length= UINT32_MAX;
4672
4303
  uint32_t best= MAX_KEY;
4673
 
  if (!usable_keys->is_clear_all())
 
4304
  if (usable_keys->any())
4674
4305
  {
4675
4306
    for (uint32_t nr=0; nr < s->keys ; nr++)
4676
4307
    {
4677
 
      if (usable_keys->is_set(nr))
 
4308
      if (usable_keys->test(nr))
4678
4309
      {
4679
4310
        if (key_info[nr].key_length < min_length)
4680
4311
        {
4710
4341
bool Table::compare_record()
4711
4342
{
4712
4343
  if (s->blob_fields + s->varchar_fields == 0)
4713
 
    return cmp_record(this, record[1]);
 
4344
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
4714
4345
  /* Compare null bits */
4715
4346
  if (memcmp(null_flags,
4716
4347
             null_flags + s->rec_buff_length,
4719
4350
  /* Compare updated fields */
4720
4351
  for (Field **ptr= field ; *ptr ; ptr++)
4721
4352
  {
4722
 
    if (bitmap_is_set(write_set, (*ptr)->field_index) &&
 
4353
    if (isWriteSet((*ptr)->field_index) &&
4723
4354
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
4724
4355
      return true;
4725
4356
  }
4726
4357
  return false;
4727
4358
}
4728
4359
 
4729
 
 
4730
 
 
4731
 
 
 
4360
/*
 
4361
 * Store a record from previous record into next
 
4362
 *
 
4363
 */
 
4364
void Table::storeRecord()
 
4365
{
 
4366
  memcpy(record[1], record[0], (size_t) s->reclength);
 
4367
}
 
4368
 
 
4369
/*
 
4370
 * Store a record as an insert
 
4371
 *
 
4372
 */
 
4373
void Table::storeRecordAsInsert()
 
4374
{
 
4375
  memcpy(insert_values, record[0], (size_t) s->reclength);
 
4376
}
 
4377
 
 
4378
/*
 
4379
 * Store a record with default values
 
4380
 *
 
4381
 */
 
4382
void Table::storeRecordAsDefault()
 
4383
{
 
4384
  memcpy(s->default_values, record[0], (size_t) s->reclength);
 
4385
}
 
4386
 
 
4387
/*
 
4388
 * Restore a record from previous record into next
 
4389
 *
 
4390
 */
 
4391
void Table::restoreRecord()
 
4392
{
 
4393
  memcpy(record[0], record[1], (size_t) s->reclength);
 
4394
}
 
4395
 
 
4396
/*
 
4397
 * Restore a record with default values
 
4398
 *
 
4399
 */
 
4400
void Table::restoreRecordAsDefault()
 
4401
{
 
4402
  memcpy(record[0], s->default_values, (size_t) s->reclength);
 
4403
}
 
4404
 
 
4405
/*
 
4406
 * Empty a record
 
4407
 *
 
4408
 */
 
4409
void Table::emptyRecord()
 
4410
{
 
4411
  restoreRecordAsDefault();
 
4412
  memset(null_flags, 255, s->null_bytes);
 
4413
}
4732
4414
 
4733
4415
/*****************************************************************************
4734
4416
  The different ways to read a record
4749
4431
    print them to the .err log
4750
4432
  */
4751
4433
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
4752
 
    sql_print_error(_("Got error %d when reading table '%s'"),
 
4434
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
4753
4435
                    error, s->path.str);
4754
4436
  file->print_error(error,MYF(0));
4755
4437
 
4757
4439
}
4758
4440
 
4759
4441
 
 
4442
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
 
4443
{
 
4444
  used_fields= 0;
 
4445
  const_table= 0;
 
4446
  null_row= 0;
 
4447
  status= STATUS_NO_RECORD;
 
4448
  maybe_null= table_list->outer_join;
 
4449
  TableList *embedding= table_list->embedding;
 
4450
  while (!maybe_null && embedding)
 
4451
  {
 
4452
    maybe_null= embedding->outer_join;
 
4453
    embedding= embedding->embedding;
 
4454
  }
 
4455
  tablenr= table_number;
 
4456
  map= (table_map) 1 << table_number;
 
4457
  force_index= table_list->force_index;
 
4458
  covering_keys= s->keys_for_keyread;
 
4459
  merge_keys.reset();
 
4460
}
 
4461
 
 
4462
 
4760
4463
/*****************************************************************************
4761
4464
** Instansiate templates
4762
4465
*****************************************************************************/