~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-10-16 10:27:33 UTC
  • mfrom: (1183.1.4 merge)
  • Revision ID: brian@gaz-20091016102733-b10po5oup0hjlilh
MergeĀ EngineĀ changes.

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
 
/* INFORMATION_SCHEMA name */
23
 
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
24
 
 
25
 
/* DRIZZLE_SCHEMA name */
26
 
LEX_STRING DRIZZLE_SCHEMA_NAME= {C_STRING_WITH_LEN("mysql")};
 
20
#include <drizzled/error.h>
 
21
#include <drizzled/gettext.h>
 
22
 
 
23
#include <drizzled/nested_join.h>
 
24
#include <drizzled/sql_parse.h>
 
25
#include <drizzled/item/sum.h>
 
26
#include <drizzled/table_list.h>
 
27
#include <drizzled/session.h>
 
28
#include <drizzled/sql_base.h>
 
29
#include <drizzled/sql_select.h>
 
30
#include <drizzled/field/blob.h>
 
31
#include <drizzled/field/varstring.h>
 
32
#include <drizzled/field/double.h>
 
33
#include <drizzled/unireg.h>
 
34
#include <drizzled/message/table.pb.h>
 
35
 
 
36
#include <drizzled/item/string.h>
 
37
#include <drizzled/item/int.h>
 
38
#include <drizzled/item/decimal.h>
 
39
#include <drizzled/item/float.h>
 
40
#include <drizzled/item/null.h>
 
41
 
 
42
#include "drizzled/table_proto.h"
 
43
 
 
44
#include <string>
 
45
#include <vector>
 
46
#include <algorithm>
 
47
 
 
48
using namespace drizzled;
 
49
using namespace std;
 
50
using namespace drizzled;
27
51
 
28
52
/* Functions defined in this file */
29
53
 
30
 
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
 
54
void open_table_error(TableShare *share, int error, int db_errno,
31
55
                      myf errortype, int errarg);
32
 
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
33
 
                           uchar *head, File file);
34
 
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
35
 
                              uint types, char **names);
36
 
static uint find_field(Field **fields, uchar *record, uint start, uint length);
37
56
 
38
57
/*************************************************************************/
39
58
 
40
59
/* Get column name from column hash */
41
60
 
42
 
static uchar *get_field_name(Field **buff, size_t *length,
43
 
                             bool not_used __attribute__((unused)))
 
61
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
44
62
{
45
 
  *length= (uint) strlen((*buff)->field_name);
46
 
  return (uchar*) (*buff)->field_name;
 
63
  *length= (uint32_t) strlen((*buff)->field_name);
 
64
  return (unsigned char*) (*buff)->field_name;
47
65
}
48
66
 
49
67
 
56
74
 
57
75
  DESCRIPTION
58
76
    Checks file name part starting with the rightmost '.' character,
59
 
    and returns it if it is equal to '.frm'. 
 
77
    and returns it if it is equal to '.dfe'.
60
78
 
61
79
  TODO
62
80
    It is a good idea to get rid of this function modifying the code
71
89
char *fn_rext(char *name)
72
90
{
73
91
  char *res= strrchr(name, '.');
74
 
  if (res && !strcmp(res, reg_ext))
 
92
  if (res && !strcmp(res, ".dfe"))
75
93
    return res;
76
94
  return name + strlen(name);
77
95
}
78
96
 
79
 
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
 
97
static TABLE_CATEGORY get_table_category(const LEX_STRING *db)
80
98
{
81
99
  assert(db != NULL);
82
 
  assert(name != NULL);
83
100
 
84
 
  if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
 
101
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
85
102
      (my_strcasecmp(system_charset_info,
86
 
                    INFORMATION_SCHEMA_NAME.str,
 
103
                    INFORMATION_SCHEMA_NAME.c_str(),
87
104
                    db->str) == 0))
88
105
  {
89
106
    return TABLE_CATEGORY_INFORMATION;
94
111
 
95
112
 
96
113
/*
97
 
  Allocate a setup TABLE_SHARE structure
 
114
  Allocate a setup TableShare structure
98
115
 
99
116
  SYNOPSIS
100
117
    alloc_table_share()
101
 
    TABLE_LIST          Take database and table name from there
 
118
    TableList           Take database and table name from there
102
119
    key                 Table cache key (db \0 table_name \0...)
103
120
    key_length          Length of key
104
121
 
107
124
    #  Share
108
125
*/
109
126
 
110
 
TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
111
 
                               uint key_length)
 
127
TableShare *alloc_table_share(TableList *table_list, char *key,
 
128
                               uint32_t key_length)
112
129
{
113
130
  MEM_ROOT mem_root;
114
 
  TABLE_SHARE *share;
 
131
  TableShare *share;
115
132
  char *key_buff, *path_buff;
116
133
  char path[FN_REFLEN];
117
 
  uint path_length;
 
134
  uint32_t path_length;
118
135
 
119
136
  path_length= build_table_filename(path, sizeof(path) - 1,
120
137
                                    table_list->db,
121
 
                                    table_list->table_name, "", 0);
 
138
                                    table_list->table_name, false);
122
139
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
123
140
  if (multi_alloc_root(&mem_root,
124
141
                       &share, sizeof(*share),
132
149
 
133
150
    share->path.str= path_buff;
134
151
    share->path.length= path_length;
135
 
    stpcpy(share->path.str, path);
 
152
    strcpy(share->path.str, path);
136
153
    share->normalized_path.str=    share->path.str;
137
154
    share->normalized_path.length= path_length;
138
155
 
139
156
    share->version=       refresh_version;
140
157
 
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_t)0;
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= ~0UL;
156
 
    share->cached_row_logging_check= -1;
157
 
 
158
158
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
159
159
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
160
160
    pthread_cond_init(&share->cond, NULL);
163
163
}
164
164
 
165
165
 
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
 
                          uint 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, uint db_flags)
295
 
{
296
 
  int error, table_type;
297
 
  bool error_given;
298
 
  File file;
299
 
  uchar 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, NullS);
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
 
    uint length;
330
 
    strxnmov(path, sizeof(path)-1,
331
 
             mysql_data_home, "/", share->db.str, "/",
332
 
             share->table_name.str, reg_ext, NullS);
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
 
    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] == (uchar) 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
 
      /* Open view only */
364
 
      if (db_flags & OPEN_VIEW_ONLY)
365
 
      {
366
 
        error_given= 1;
367
 
        goto err;
368
 
      }
369
 
      table_type= 1;
370
 
    }
371
 
    else
372
 
    {
373
 
      error= 6;                                 // Unkown .frm version
374
 
      goto err;
375
 
    }
376
 
  }
377
 
  else
378
 
    goto err;
379
 
 
380
 
  /* No handling of text based files yet */
381
 
  if (table_type == 1)
382
 
  {
383
 
    root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
384
 
    old_root= *root_ptr;
385
 
    *root_ptr= &share->mem_root;
386
 
    error= open_binary_frm(thd, share, head, file);
387
 
    *root_ptr= old_root;
388
 
    error_given= 1;
389
 
  }
390
 
  else
 
166
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
 
167
{
 
168
  enum_field_types field_type;
 
169
 
 
170
  switch(proto_field_type)
 
171
  {
 
172
  case message::Table::Field::INTEGER:
 
173
    field_type= DRIZZLE_TYPE_LONG;
 
174
    break;
 
175
  case message::Table::Field::DOUBLE:
 
176
    field_type= DRIZZLE_TYPE_DOUBLE;
 
177
    break;
 
178
  case message::Table::Field::TIMESTAMP:
 
179
    field_type= DRIZZLE_TYPE_TIMESTAMP;
 
180
    break;
 
181
  case message::Table::Field::BIGINT:
 
182
    field_type= DRIZZLE_TYPE_LONGLONG;
 
183
    break;
 
184
  case message::Table::Field::DATETIME:
 
185
    field_type= DRIZZLE_TYPE_DATETIME;
 
186
    break;
 
187
  case message::Table::Field::DATE:
 
188
    field_type= DRIZZLE_TYPE_DATE;
 
189
    break;
 
190
  case message::Table::Field::VARCHAR:
 
191
    field_type= DRIZZLE_TYPE_VARCHAR;
 
192
    break;
 
193
  case message::Table::Field::DECIMAL:
 
194
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
195
    break;
 
196
  case message::Table::Field::ENUM:
 
197
    field_type= DRIZZLE_TYPE_ENUM;
 
198
    break;
 
199
  case message::Table::Field::BLOB:
 
200
    field_type= DRIZZLE_TYPE_BLOB;
 
201
    break;
 
202
  default:
 
203
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
391
204
    assert(1);
392
 
 
393
 
  share->table_category= get_table_category(& share->db, & share->table_name);
394
 
 
395
 
  if (!error)
396
 
    thd->status_var.opened_shares++;
397
 
 
398
 
err:
399
 
  my_close(file, MYF(MY_WME));
400
 
 
401
 
err_not_open:
402
 
  if (error && !error_given)
403
 
  {
404
 
    share->error= error;
405
 
    open_table_error(share, error, (share->open_errno= my_errno), 0);
406
 
  }
407
 
 
408
 
  return(error);
409
 
}
410
 
 
411
 
 
412
 
/*
413
 
  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
414
 
*/
415
 
 
416
 
static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
417
 
                           File file)
418
 
{
419
 
  int error, errarg= 0;
420
 
  uint new_frm_ver, field_pack_length, new_field_pack_flag;
421
 
  uint interval_count, interval_parts, read_length, int_length;
422
 
  uint db_create_options, keys, key_parts, n_length;
423
 
  uint key_info_length, com_length, null_bit_pos=0;
424
 
  uint extra_rec_buf_length;
425
 
  uint i,j;
426
 
  bool use_hash;
427
 
  uchar forminfo[288];
428
 
  char *keynames, *names, *comment_pos;
429
 
  uchar *record;
430
 
  uchar *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
431
 
  ulong pos, record_offset, *rec_per_key, rec_buff_length;
432
 
  handler *handler_file= 0;
433
 
  KEY   *keyinfo;
434
 
  KEY_PART_INFO *key_part;
435
 
  Field  **field_ptr, *reg_field;
436
 
  const char **interval_array;
437
 
  enum legacy_db_type legacy_db_type;
438
 
  my_bitmap_map *bitmaps;
439
 
  uchar *buff= 0;
440
 
  uchar *field_extra_info= 0;
441
 
 
442
 
  new_field_pack_flag= head[27];
443
 
  new_frm_ver= (head[2] - FRM_VER);
444
 
  field_pack_length= new_frm_ver < 2 ? 11 : 17;
445
 
  disk_buff= 0;
446
 
 
447
 
  error= 3;
448
 
  if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
449
 
    goto err;                                   /* purecov: inspected */
450
 
  VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
451
 
  if (my_read(file,forminfo,288,MYF(MY_NABP)))
452
 
    goto err;
453
 
 
454
 
  share->frm_version= head[2];
455
 
  /*
456
 
    Check if .frm file created by MySQL 5.0. In this case we want to
457
 
    display CHAR fields as CHAR and not as VARCHAR.
458
 
    We do it this way as we want to keep the old frm version to enable
459
 
    MySQL 4.1 to read these files.
460
 
  */
461
 
  if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
462
 
    share->frm_version= FRM_VER_TRUE_VARCHAR;
463
 
 
464
 
  legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
465
 
  assert(share->db_plugin == NULL);
466
 
  /*
467
 
    if the storage engine is dynamic, no point in resolving it by its
468
 
    dynamically allocated legacy_db_type. We will resolve it later by name.
469
 
  */
470
 
  if (legacy_db_type > DB_TYPE_UNKNOWN && 
471
 
      legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
472
 
    share->db_plugin= ha_lock_engine(NULL, 
473
 
                                     ha_checktype(thd, legacy_db_type, 0, 0));
474
 
  share->db_create_options= db_create_options= uint2korr(head+30);
 
205
  }
 
206
 
 
207
  return field_type;
 
208
}
 
209
 
 
210
static Item *default_value_item(enum_field_types field_type,
 
211
                                const CHARSET_INFO *charset,
 
212
                                bool default_null, const string *default_value,
 
213
                                const string *default_bin_value)
 
214
{
 
215
  Item *default_item= NULL;
 
216
  int error= 0;
 
217
 
 
218
  if (default_null)
 
219
  {
 
220
    return new Item_null();
 
221
  }
 
222
 
 
223
  switch(field_type)
 
224
  {
 
225
  case DRIZZLE_TYPE_TINY:
 
226
  case DRIZZLE_TYPE_LONG:
 
227
  case DRIZZLE_TYPE_LONGLONG:
 
228
    default_item= new Item_int(default_value->c_str(),
 
229
                               (int64_t) my_strtoll10(default_value->c_str(),
 
230
                                                      NULL,
 
231
                                                      &error),
 
232
                               default_value->length());
 
233
    break;
 
234
  case DRIZZLE_TYPE_DOUBLE:
 
235
    default_item= new Item_float(default_value->c_str(),
 
236
                                 default_value->length());
 
237
    break;
 
238
  case DRIZZLE_TYPE_NULL:
 
239
    assert(false);
 
240
  case DRIZZLE_TYPE_TIMESTAMP:
 
241
  case DRIZZLE_TYPE_DATETIME:
 
242
  case DRIZZLE_TYPE_DATE:
 
243
    if (default_value->compare("NOW()") == 0)
 
244
      break;
 
245
  case DRIZZLE_TYPE_ENUM:
 
246
    default_item= new Item_string(default_value->c_str(),
 
247
                                  default_value->length(),
 
248
                                  system_charset_info);
 
249
    break;
 
250
  case DRIZZLE_TYPE_VARCHAR:
 
251
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
 
252
    if (charset==&my_charset_bin)
 
253
    {
 
254
      default_item= new Item_string(default_bin_value->c_str(),
 
255
                                    default_bin_value->length(),
 
256
                                    &my_charset_bin);
 
257
    }
 
258
    else
 
259
    {
 
260
      default_item= new Item_string(default_value->c_str(),
 
261
                                    default_value->length(),
 
262
                                    system_charset_info);
 
263
    }
 
264
    break;
 
265
  case DRIZZLE_TYPE_NEWDECIMAL:
 
266
    default_item= new Item_decimal(default_value->c_str(),
 
267
                                   default_value->length(),
 
268
                                   system_charset_info);
 
269
    break;
 
270
  }
 
271
 
 
272
  return default_item;
 
273
}
 
274
 
 
275
int drizzled::parse_table_proto(Session *session,
 
276
                                message::Table &table,
 
277
                                TableShare *share)
 
278
{
 
279
  int error= 0;
 
280
  Cursor *handler_file= NULL;
 
281
 
 
282
  share->setTableProto(new(nothrow) message::Table(table));
 
283
 
 
284
  share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
 
285
 
 
286
  message::Table::TableOptions table_options;
 
287
 
 
288
  if (table.has_options())
 
289
    table_options= table.options();
 
290
 
 
291
  uint32_t db_create_options= 0;
 
292
 
 
293
  if (table_options.has_pack_keys())
 
294
  {
 
295
    if (table_options.pack_keys())
 
296
      db_create_options|= HA_OPTION_PACK_KEYS;
 
297
    else
 
298
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
 
299
  }
 
300
 
 
301
  if (table_options.pack_record())
 
302
    db_create_options|= HA_OPTION_PACK_RECORD;
 
303
 
 
304
  /* db_create_options was stored as 2 bytes in FRM
 
305
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
 
306
   */
 
307
  share->db_create_options= (db_create_options & 0x0000FFFF);
475
308
  share->db_options_in_use= share->db_create_options;
476
 
  share->mysql_version= uint4korr(head+51);
477
 
  share->null_field_first= 0;
478
 
  if (!head[32])                                // New frm file in 3.23
479
 
  {
480
 
    share->avg_row_length= uint4korr(head+34);
481
 
    share->transactional= (ha_choice) (head[39] & 3);
482
 
    share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
483
 
    share->row_type= (row_type) head[40];
484
 
    share->block_size= uint4korr(head+43);
485
 
    share->table_charset= get_charset((uint) head[38],MYF(0));
486
 
    share->null_field_first= 1;
487
 
  }
 
309
 
 
310
  share->row_type= table_options.has_row_type() ?
 
311
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
312
 
 
313
  share->block_size= table_options.has_block_size() ?
 
314
    table_options.block_size() : 0;
 
315
 
 
316
  share->table_charset= get_charset(table_options.has_collation_id()?
 
317
                                    table_options.collation_id() : 0);
 
318
 
488
319
  if (!share->table_charset)
489
320
  {
490
321
    /* unknown charset in head[38] or pre-3.23 frm */
491
322
    if (use_mb(default_charset_info))
492
323
    {
493
324
      /* Warn that we may be changing the size of character columns */
494
 
      sql_print_warning(_("'%s' had no or invalid character set, "
495
 
                        "and default character set is multi-byte, "
496
 
                        "so character column sizes may have changed"),
497
 
                        share->path.str);
 
325
      errmsg_printf(ERRMSG_LVL_WARN,
 
326
                    _("'%s' had no or invalid character set, "
 
327
                      "and default character set is multi-byte, "
 
328
                      "so character column sizes may have changed"),
 
329
                    share->path.str);
498
330
    }
499
331
    share->table_charset= default_charset_info;
500
332
  }
 
333
 
501
334
  share->db_record_offset= 1;
502
 
  if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
503
 
    share->blob_ptr_size= portable_sizeof_char_ptr;
504
 
  /* Set temporarily a good value for db_low_byte_first */
505
 
  share->db_low_byte_first= test(legacy_db_type != DB_TYPE_ISAM);
506
 
  error=4;
507
 
  share->max_rows= uint4korr(head+18);
508
 
  share->min_rows= uint4korr(head+22);
509
 
 
510
 
  /* Read keyinformation */
511
 
  key_info_length= (uint) uint2korr(head+28);
512
 
  VOID(my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0)));
513
 
  if (read_string(file,(uchar**) &disk_buff,key_info_length))
514
 
    goto err;                                   /* purecov: inspected */
515
 
  if (disk_buff[0] & 0x80)
516
 
  {
517
 
    share->keys=      keys=      (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
518
 
    share->key_parts= key_parts= uint2korr(disk_buff+2);
519
 
  }
520
 
  else
521
 
  {
522
 
    share->keys=      keys=      disk_buff[0];
523
 
    share->key_parts= key_parts= disk_buff[1];
524
 
  }
525
 
  share->keys_for_keyread.init(0);
526
 
  share->keys_in_use.init(keys);
527
 
 
528
 
  n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
529
 
  if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
530
 
                                    n_length + uint2korr(disk_buff+4))))
531
 
    goto err;                                   /* purecov: inspected */
532
 
  memset(keyinfo, 0, n_length);
533
 
  share->key_info= keyinfo;
534
 
  key_part= my_reinterpret_cast(KEY_PART_INFO*) (keyinfo+keys);
535
 
  strpos=disk_buff+6;
536
 
 
537
 
  if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
538
 
                                         sizeof(ulong*)*key_parts)))
539
 
    goto err;
540
 
 
541
 
  for (i=0 ; i < keys ; i++, keyinfo++)
542
 
  {
543
 
    keyinfo->table= 0;                           // Updated in open_frm
544
 
    if (new_frm_ver >= 3)
545
 
    {
546
 
      keyinfo->flags=      (uint) uint2korr(strpos) ^ HA_NOSAME;
547
 
      keyinfo->key_length= (uint) uint2korr(strpos+2);
548
 
      keyinfo->key_parts=  (uint) strpos[4];
549
 
      keyinfo->algorithm=  (enum ha_key_alg) strpos[5];
550
 
      keyinfo->block_size= uint2korr(strpos+6);
551
 
      strpos+=8;
552
 
    }
553
 
 
554
 
    keyinfo->key_part=   key_part;
 
335
 
 
336
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
337
 
 
338
  share->db_low_byte_first= true;
 
339
 
 
340
  share->keys= table.indexes_size();
 
341
 
 
342
  share->key_parts= 0;
 
343
  for (int indx= 0; indx < table.indexes_size(); indx++)
 
344
    share->key_parts+= table.indexes(indx).index_part_size();
 
345
 
 
346
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
347
                                     table.indexes_size() * sizeof(KEY)
 
348
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
349
 
 
350
  KEY_PART_INFO *key_part;
 
351
 
 
352
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
353
    (share->key_info+table.indexes_size());
 
354
 
 
355
 
 
356
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
357
                                            sizeof(ulong*)*share->key_parts);
 
358
 
 
359
  share->keynames.count= table.indexes_size();
 
360
  share->keynames.name= NULL;
 
361
  share->keynames.type_names= (const char**)
 
362
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
363
 
 
364
  share->keynames.type_lengths= (unsigned int*)
 
365
    alloc_root(&share->mem_root,
 
366
               sizeof(unsigned int) * (table.indexes_size()+1));
 
367
 
 
368
  share->keynames.type_names[share->keynames.count]= NULL;
 
369
  share->keynames.type_lengths[share->keynames.count]= 0;
 
370
 
 
371
  KEY* keyinfo= share->key_info;
 
372
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
373
  {
 
374
    message::Table::Index indx= table.indexes(keynr);
 
375
 
 
376
    keyinfo->table= 0;
 
377
    keyinfo->flags= 0;
 
378
 
 
379
    if (indx.is_unique())
 
380
      keyinfo->flags|= HA_NOSAME;
 
381
 
 
382
    if (indx.has_options())
 
383
    {
 
384
      message::Table::Index::IndexOptions indx_options= indx.options();
 
385
      if (indx_options.pack_key())
 
386
        keyinfo->flags|= HA_PACK_KEY;
 
387
 
 
388
      if (indx_options.var_length_key())
 
389
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
390
 
 
391
      if (indx_options.null_part_key())
 
392
        keyinfo->flags|= HA_NULL_PART_KEY;
 
393
 
 
394
      if (indx_options.binary_pack_key())
 
395
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
396
 
 
397
      if (indx_options.has_partial_segments())
 
398
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
399
 
 
400
      if (indx_options.auto_generated_key())
 
401
        keyinfo->flags|= HA_GENERATED_KEY;
 
402
 
 
403
      if (indx_options.has_key_block_size())
 
404
      {
 
405
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
406
        keyinfo->block_size= indx_options.key_block_size();
 
407
      }
 
408
      else
 
409
      {
 
410
        keyinfo->block_size= 0;
 
411
      }
 
412
    }
 
413
 
 
414
    switch (indx.type())
 
415
    {
 
416
    case message::Table::Index::UNKNOWN_INDEX:
 
417
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
418
      break;
 
419
    case message::Table::Index::BTREE:
 
420
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
421
      break;
 
422
    case message::Table::Index::RTREE:
 
423
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
424
      break;
 
425
    case message::Table::Index::HASH:
 
426
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
427
      break;
 
428
    case message::Table::Index::FULLTEXT:
 
429
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
430
 
 
431
    default:
 
432
      /* TODO: suitable warning ? */
 
433
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
434
      break;
 
435
    }
 
436
 
 
437
    keyinfo->key_length= indx.key_length();
 
438
 
 
439
    keyinfo->key_parts= indx.index_part_size();
 
440
 
 
441
    keyinfo->key_part= key_part;
555
442
    keyinfo->rec_per_key= rec_per_key;
556
 
    for (j=keyinfo->key_parts ; j-- ; key_part++)
557
 
    {
558
 
      *rec_per_key++=0;
559
 
      key_part->fieldnr=        (uint16_t) (uint2korr(strpos) & FIELD_NR_MASK);
560
 
      key_part->offset= (uint) uint2korr(strpos+2)-1;
561
 
      key_part->key_type=       (uint) uint2korr(strpos+5);
562
 
      // key_part->field=       (Field*) 0;     // Will be fixed later
563
 
      if (new_frm_ver >= 1)
564
 
      {
565
 
        key_part->key_part_flag= *(strpos+4);
566
 
        key_part->length=       (uint) uint2korr(strpos+7);
567
 
        strpos+=9;
568
 
      }
569
 
      else
570
 
      {
571
 
        key_part->length=       *(strpos+4);
572
 
        key_part->key_part_flag=0;
573
 
        if (key_part->length > 128)
574
 
        {
575
 
          key_part->length&=127;                /* purecov: inspected */
576
 
          key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
577
 
        }
578
 
        strpos+=7;
579
 
      }
580
 
      key_part->store_length=key_part->length;
581
 
    }
582
 
  }
583
 
  keynames=(char*) key_part;
584
 
  strpos+= (stpcpy(keynames, (char *) strpos) - keynames)+1;
585
 
 
586
 
  //reading index comments
587
 
  for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
588
 
  {
589
 
    if (keyinfo->flags & HA_USES_COMMENT)
590
 
    {
591
 
      keyinfo->comment.length= uint2korr(strpos);
592
 
      keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
593
 
                                         keyinfo->comment.length);
594
 
      strpos+= 2 + keyinfo->comment.length;
595
 
    } 
596
 
    assert(test(keyinfo->flags & HA_USES_COMMENT) == 
597
 
               (keyinfo->comment.length > 0));
598
 
  }
599
 
 
600
 
  share->reclength = uint2korr((head+16));
601
 
  if (*(head+26) == 1)
602
 
    share->system= 1;                           /* one-record-database */
603
 
 
604
 
  record_offset= (ulong) (uint2korr(head+6)+
605
 
                          ((uint2korr(head+14) == 0xffff ?
606
 
                            uint4korr(head+47) : uint2korr(head+14))));
607
 
 
608
 
  if ((n_length= uint4korr(head+55)))
609
 
  {
610
 
    /* Read extra data segment */
611
 
    uchar *next_chunk, *buff_end;
612
 
    if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
613
 
      goto err;
614
 
    if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
615
 
    {
616
 
      goto err;
617
 
    }
618
 
    share->connect_string.length= uint2korr(buff);
619
 
    if (!(share->connect_string.str= strmake_root(&share->mem_root,
620
 
                                                  (char*) next_chunk + 2,
621
 
                                                  share->connect_string.
622
 
                                                  length)))
623
 
    {
624
 
      goto err;
625
 
    }
626
 
    next_chunk+= share->connect_string.length + 2;
627
 
    buff_end= buff + n_length;
628
 
    if (next_chunk + 2 < buff_end)
629
 
    {
630
 
      uint str_db_type_length= uint2korr(next_chunk);
631
 
      LEX_STRING name;
632
 
      name.str= (char*) next_chunk + 2;
633
 
      name.length= str_db_type_length;
634
 
 
635
 
      plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
636
 
      if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
637
 
      {
638
 
        if (legacy_db_type > DB_TYPE_UNKNOWN &&
639
 
            legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
640
 
            legacy_db_type != ha_legacy_type(
641
 
                plugin_data(tmp_plugin, handlerton *)))
642
 
        {
643
 
          /* bad file, legacy_db_type did not match the name */
644
 
          my_free(buff, MYF(0));
645
 
          goto err;
646
 
        }
647
 
        /*
648
 
          tmp_plugin is locked with a local lock.
649
 
          we unlock the old value of share->db_plugin before
650
 
          replacing it with a globally locked version of tmp_plugin
651
 
        */
652
 
        plugin_unlock(NULL, share->db_plugin);
653
 
        share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
654
 
      }
655
 
      else if (!tmp_plugin)
656
 
      {
657
 
        /* purecov: begin inspected */
658
 
        error= 8;
659
 
        my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
660
 
        my_free(buff, MYF(0));
661
 
        goto err;
662
 
        /* purecov: end */
663
 
      }
664
 
      next_chunk+= str_db_type_length + 2;
665
 
    }
666
 
    if (share->mysql_version >= 50110)
667
 
    {
668
 
      /* New auto_partitioned indicator introduced in 5.1.11 */
669
 
      next_chunk++;
670
 
    }
671
 
    if (forminfo[46] == (uchar)255)
672
 
    {
673
 
      //reading long table comment
674
 
      if (next_chunk + 2 > buff_end)
675
 
      {
676
 
          my_free(buff, MYF(0));
677
 
          goto err;
678
 
      }
679
 
      share->comment.length = uint2korr(next_chunk);
680
 
      if (! (share->comment.str= strmake_root(&share->mem_root,
681
 
                               (char*)next_chunk + 2, share->comment.length)))
682
 
      {
683
 
          my_free(buff, MYF(0));
684
 
          goto err;
685
 
      }
686
 
      next_chunk+= 2 + share->comment.length;
687
 
    }
688
 
    assert(next_chunk <= buff_end);
689
 
    if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
690
 
    {
691
 
      /*
692
 
       New frm format in mysql_version 5.2.5 (originally in
693
 
       mysql-5.1.22-ndb-6.2.5)
694
 
       New column properties added:
695
 
       COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
696
 
       TABLESPACE name is now stored in frm
697
 
      */
698
 
      if (next_chunk >= buff_end)
699
 
      {
700
 
        if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
701
 
        {
702
 
          goto err;
703
 
        }
704
 
      }
705
 
      else
706
 
      {
707
 
        const uint format_section_header_size= 8;
708
 
        uint format_section_len= uint2korr(next_chunk+0);
709
 
 
710
 
        field_extra_info= next_chunk + format_section_header_size + 1;
711
 
        next_chunk+= format_section_len;
712
 
      }
713
 
    }
714
 
    assert (next_chunk <= buff_end);
715
 
    if (next_chunk > buff_end)
716
 
    {
717
 
      goto err;
718
 
    }
719
 
  }
720
 
  share->key_block_size= uint2korr(head+62);
721
 
 
722
 
  error=4;
723
 
  extra_rec_buf_length= uint2korr(head+59);
724
 
  rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
 
443
 
 
444
    for (unsigned int partnr= 0;
 
445
         partnr < keyinfo->key_parts;
 
446
         partnr++, key_part++)
 
447
    {
 
448
      message::Table::Index::IndexPart part;
 
449
      part= indx.index_part(partnr);
 
450
 
 
451
      *rec_per_key++= 0;
 
452
 
 
453
      key_part->field= NULL;
 
454
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
 
455
      key_part->null_bit= 0;
 
456
      /* key_part->null_offset is only set if null_bit (see later) */
 
457
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
458
      /* key_part->type ???? */
 
459
      key_part->key_part_flag= 0;
 
460
      if (part.has_in_reverse_order())
 
461
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
462
 
 
463
      key_part->length= part.compare_length();
 
464
 
 
465
      key_part->store_length= key_part->length;
 
466
 
 
467
      /* key_part->offset is set later */
 
468
      key_part->key_type= part.key_type();
 
469
    }
 
470
 
 
471
    if (! indx.has_comment())
 
472
    {
 
473
      keyinfo->comment.length= 0;
 
474
      keyinfo->comment.str= NULL;
 
475
    }
 
476
    else
 
477
    {
 
478
      keyinfo->flags|= HA_USES_COMMENT;
 
479
      keyinfo->comment.length= indx.comment().length();
 
480
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
481
                                         indx.comment().c_str(),
 
482
                                         keyinfo->comment.length);
 
483
    }
 
484
 
 
485
    keyinfo->name= strmake_root(&share->mem_root,
 
486
                                indx.name().c_str(),
 
487
                                indx.name().length());
 
488
 
 
489
    share->keynames.type_names[keynr]= keyinfo->name;
 
490
    share->keynames.type_lengths[keynr]= indx.name().length();
 
491
  }
 
492
 
 
493
  share->keys_for_keyread.reset();
 
494
  set_prefix(share->keys_in_use, share->keys);
 
495
 
 
496
  share->key_block_size= table_options.has_key_block_size() ?
 
497
    table_options.key_block_size() : 0;
 
498
 
 
499
  share->fields= table.field_size();
 
500
 
 
501
  share->field= (Field**) alloc_root(&share->mem_root,
 
502
                                     ((share->fields+1) * sizeof(Field*)));
 
503
  share->field[share->fields]= NULL;
 
504
 
 
505
  uint32_t null_fields= 0;
 
506
  share->reclength= 0;
 
507
 
 
508
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
 
509
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
 
510
 
 
511
  assert(field_offsets && field_pack_length); // TODO: fixme
 
512
 
 
513
  uint32_t interval_count= 0;
 
514
  uint32_t interval_parts= 0;
 
515
 
 
516
  uint32_t stored_columns_reclength= 0;
 
517
 
 
518
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
519
  {
 
520
    message::Table::Field pfield= table.field(fieldnr);
 
521
    if (pfield.has_constraints() && pfield.constraints().is_nullable())
 
522
      null_fields++;
 
523
 
 
524
    enum_field_types drizzle_field_type=
 
525
      proto_field_type_to_drizzle_type(pfield.type());
 
526
 
 
527
    field_offsets[fieldnr]= stored_columns_reclength;
 
528
 
 
529
    /* the below switch is very similar to
 
530
       CreateField::create_length_to_internal_length in field.cc
 
531
       (which should one day be replace by just this code)
 
532
    */
 
533
    switch(drizzle_field_type)
 
534
    {
 
535
    case DRIZZLE_TYPE_BLOB:
 
536
    case DRIZZLE_TYPE_VARCHAR:
 
537
      {
 
538
        message::Table::Field::StringFieldOptions field_options= pfield.string_options();
 
539
 
 
540
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
 
541
                                            field_options.collation_id() : 0);
 
542
 
 
543
        if (! cs)
 
544
          cs= default_charset_info;
 
545
 
 
546
        field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
 
547
                                                     field_options.length() * cs->mbmaxlen);
 
548
      }
 
549
      break;
 
550
    case DRIZZLE_TYPE_ENUM:
 
551
      {
 
552
        message::Table::Field::SetFieldOptions field_options= pfield.set_options();
 
553
 
 
554
        field_pack_length[fieldnr]=
 
555
          get_enum_pack_length(field_options.field_value_size());
 
556
 
 
557
        interval_count++;
 
558
        interval_parts+= field_options.field_value_size();
 
559
      }
 
560
      break;
 
561
    case DRIZZLE_TYPE_NEWDECIMAL:
 
562
      {
 
563
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
564
 
 
565
        field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
 
566
      }
 
567
      break;
 
568
    default:
 
569
      /* Zero is okay here as length is fixed for other types. */
 
570
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
 
571
    }
 
572
 
 
573
    share->reclength+= field_pack_length[fieldnr];
 
574
    stored_columns_reclength+= field_pack_length[fieldnr];
 
575
  }
 
576
 
 
577
  /* data_offset added to stored_rec_length later */
 
578
  share->stored_rec_length= stored_columns_reclength;
 
579
 
 
580
  share->null_fields= null_fields;
 
581
 
 
582
  ulong null_bits= null_fields;
 
583
  if (! table_options.pack_record())
 
584
    null_bits++;
 
585
  ulong data_offset= (null_bits + 7)/8;
 
586
 
 
587
 
 
588
  share->reclength+= data_offset;
 
589
  share->stored_rec_length+= data_offset;
 
590
 
 
591
  ulong rec_buff_length;
 
592
 
 
593
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
725
594
  share->rec_buff_length= rec_buff_length;
726
 
  if (!(record= (uchar *) alloc_root(&share->mem_root,
727
 
                                     rec_buff_length)))
728
 
    goto err;                                   /* purecov: inspected */
 
595
 
 
596
  unsigned char* record= NULL;
 
597
 
 
598
  if (! (record= (unsigned char *) alloc_root(&share->mem_root,
 
599
                                              rec_buff_length)))
 
600
    abort();
 
601
 
 
602
  memset(record, 0, rec_buff_length);
 
603
 
 
604
  int null_count= 0;
 
605
 
 
606
  if (! table_options.pack_record())
 
607
  {
 
608
    null_count++; // one bit for delete mark.
 
609
    *record|= 1;
 
610
  }
 
611
 
729
612
  share->default_values= record;
730
 
  if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
731
 
    goto err;                                   /* purecov: inspected */
732
 
 
733
 
  VOID(my_seek(file,pos+288,MY_SEEK_SET,MYF(0)));
734
 
 
735
 
  share->fields= uint2korr(forminfo+258);
736
 
  pos= uint2korr(forminfo+260);                 /* Length of all screens */
737
 
  n_length= uint2korr(forminfo+268);
738
 
  interval_count= uint2korr(forminfo+270);
739
 
  interval_parts= uint2korr(forminfo+272);
740
 
  int_length= uint2korr(forminfo+274);
741
 
  share->null_fields= uint2korr(forminfo+282);
742
 
  com_length= uint2korr(forminfo+284);
743
 
  if (forminfo[46] != (uchar)255)
 
613
 
 
614
  if (interval_count)
744
615
  {
745
 
    share->comment.length=  (int) (forminfo[46]);
746
 
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
747
 
                                     share->comment.length);
 
616
    share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
 
617
                                           interval_count*sizeof(TYPELIB));
748
618
  }
749
 
 
750
 
 
751
 
  if (!(field_ptr = (Field **)
752
 
        alloc_root(&share->mem_root,
753
 
                   (uint) ((share->fields+1)*sizeof(Field*)+
754
 
                           interval_count*sizeof(TYPELIB)+
755
 
                           (share->fields+interval_parts+
756
 
                            keys+3)*sizeof(char *)+
757
 
                           (n_length+int_length+com_length)))))
758
 
    goto err;                                   /* purecov: inspected */
759
 
 
760
 
  share->field= field_ptr;
761
 
  read_length=(uint) (share->fields * field_pack_length +
762
 
                      pos+ (uint) (n_length+int_length+com_length));
763
 
  if (read_string(file,(uchar**) &disk_buff,read_length))
764
 
    goto err;                                   /* purecov: inspected */
765
 
  strpos= disk_buff+pos;
766
 
 
767
 
  share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
768
 
  interval_array= (const char **) (share->intervals+interval_count);
769
 
  names= (char*) (interval_array+share->fields+interval_parts+keys+3);
770
 
  if (!interval_count)
771
 
    share->intervals= 0;                        // For better debugging
772
 
  memcpy(names, strpos+(share->fields*field_pack_length),
773
 
         (uint) (n_length+int_length));
774
 
  comment_pos= names+(n_length+int_length);
775
 
  memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
776
 
 
777
 
  fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
778
 
  if (share->fieldnames.count != share->fields)
779
 
    goto err;
780
 
  fix_type_pointers(&interval_array, share->intervals, interval_count,
781
 
                    &names);
782
 
 
 
619
  else
 
620
    share->intervals= NULL;
 
621
 
 
622
  share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
 
623
                                                          (share->fields + 1) * sizeof(char*));
 
624
 
 
625
  share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
 
626
                                                             (share->fields + 1) * sizeof(unsigned int));
 
627
 
 
628
  share->fieldnames.type_names[share->fields]= NULL;
 
629
  share->fieldnames.type_lengths[share->fields]= 0;
 
630
  share->fieldnames.count= share->fields;
 
631
 
 
632
 
 
633
  /* Now fix the TYPELIBs for the intervals (enum values)
 
634
     and field names.
 
635
   */
 
636
 
 
637
  uint32_t interval_nr= 0;
 
638
 
 
639
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
783
640
  {
784
 
    /* Set ENUM and SET lengths */
785
 
    TYPELIB *interval;
786
 
    for (interval= share->intervals;
787
 
         interval < share->intervals + interval_count;
788
 
         interval++)
 
641
    message::Table::Field pfield= table.field(fieldnr);
 
642
 
 
643
    /* field names */
 
644
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
 
645
                                                        pfield.name().c_str(),
 
646
                                                        pfield.name().length());
 
647
 
 
648
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
 
649
 
 
650
    /* enum typelibs */
 
651
    if (pfield.type() != message::Table::Field::ENUM)
 
652
      continue;
 
653
 
 
654
    message::Table::Field::SetFieldOptions field_options= pfield.set_options();
 
655
 
 
656
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
 
657
                                             field_options.collation_id() : 0);
 
658
 
 
659
    if (! charset)
 
660
      charset= default_charset_info;
 
661
 
 
662
    TYPELIB *t= &(share->intervals[interval_nr]);
 
663
 
 
664
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
665
                                            (field_options.field_value_size() + 1) * sizeof(char*));
 
666
 
 
667
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
668
                                                (field_options.field_value_size() + 1) * sizeof(unsigned int));
 
669
 
 
670
    t->type_names[field_options.field_value_size()]= NULL;
 
671
    t->type_lengths[field_options.field_value_size()]= 0;
 
672
 
 
673
    t->count= field_options.field_value_size();
 
674
    t->name= NULL;
 
675
 
 
676
    for (int n= 0; n < field_options.field_value_size(); n++)
789
677
    {
790
 
      uint count= (uint) (interval->count + 1) * sizeof(uint);
791
 
      if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
792
 
                                                        count)))
793
 
        goto err;
794
 
      for (count= 0; count < interval->count; count++)
795
 
      {
796
 
        char *val= (char*) interval->type_names[count];
797
 
        interval->type_lengths[count]= strlen(val);
798
 
      }
799
 
      interval->type_lengths[count]= 0;
 
678
      t->type_names[n]= strmake_root(&share->mem_root,
 
679
                                     field_options.field_value(n).c_str(),
 
680
                                     field_options.field_value(n).length());
 
681
 
 
682
      /* 
 
683
       * Go ask the charset what the length is as for "" length=1
 
684
       * and there's stripping spaces or some other crack going on.
 
685
       */
 
686
      uint32_t lengthsp;
 
687
      lengthsp= charset->cset->lengthsp(charset,
 
688
                                        t->type_names[n],
 
689
                                        field_options.field_value(n).length());
 
690
      t->type_lengths[n]= lengthsp;
800
691
    }
801
 
  }
802
 
 
803
 
  if (keynames)
804
 
    fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
805
 
 
806
 
 /* Allocate handler */
807
 
  if (!(handler_file= get_new_handler(share, thd->mem_root,
808
 
                                      share->db_type())))
809
 
    goto err;
810
 
 
811
 
  record= share->default_values-1;              /* Fieldstart = 1 */
812
 
  if (share->null_field_first)
813
 
  {
814
 
    null_flags= null_pos= (uchar*) record+1;
815
 
    null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
816
 
    /*
817
 
      null_bytes below is only correct under the condition that
818
 
      there are no bit fields.  Correct values is set below after the
819
 
      table struct is initialized
820
 
    */
821
 
    share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
822
 
  }
823
 
 
824
 
  use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
692
    interval_nr++;
 
693
  }
 
694
 
 
695
 
 
696
  /* and read the fields */
 
697
  interval_nr= 0;
 
698
 
 
699
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
700
 
825
701
  if (use_hash)
826
 
    use_hash= !hash_init(&share->name_hash,
827
 
                         system_charset_info,
828
 
                         share->fields,0,0,
829
 
                         (hash_get_key) get_field_name,0,0);
830
 
 
831
 
  for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
 
702
    use_hash= ! hash_init(&share->name_hash,
 
703
                          system_charset_info,
 
704
                          share->fields,
 
705
                          0,
 
706
                          0,
 
707
                          (hash_get_key) get_field_name,
 
708
                          0,
 
709
                          0);
 
710
 
 
711
  unsigned char* null_pos= record;;
 
712
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
 
713
 
 
714
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
832
715
  {
833
 
    uint pack_flag, interval_nr, unireg_type, recpos, field_length;
834
 
    enum_field_types field_type;
 
716
    message::Table::Field pfield= table.field(fieldnr);
 
717
 
835
718
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
836
 
    const CHARSET_INFO *charset= NULL;
 
719
 
 
720
    switch (pfield.format())
 
721
    {
 
722
    case message::Table::Field::DefaultFormat:
 
723
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
724
      break;
 
725
    case message::Table::Field::FixedFormat:
 
726
      column_format= COLUMN_FORMAT_TYPE_FIXED;
 
727
      break;
 
728
    case message::Table::Field::DynamicFormat:
 
729
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
 
730
      break;
 
731
    default:
 
732
      assert(1);
 
733
    }
 
734
 
 
735
    Field::utype unireg_type= Field::NONE;
 
736
 
 
737
    if (pfield.has_numeric_options() &&
 
738
        pfield.numeric_options().is_autoincrement())
 
739
    {
 
740
      unireg_type= Field::NEXT_NUMBER;
 
741
    }
 
742
 
 
743
    if (pfield.has_options() &&
 
744
        pfield.options().has_default_value() &&
 
745
        pfield.options().default_value().compare("NOW()") == 0)
 
746
    {
 
747
      if (pfield.options().has_update_value() &&
 
748
          pfield.options().update_value().compare("NOW()") == 0)
 
749
      {
 
750
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
751
      }
 
752
      else if (! pfield.options().has_update_value())
 
753
      {
 
754
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
755
      }
 
756
      else
 
757
        assert(1); // Invalid update value.
 
758
    }
 
759
    else if (pfield.has_options() &&
 
760
             pfield.options().has_update_value() &&
 
761
             pfield.options().update_value().compare("NOW()") == 0)
 
762
    {
 
763
      unireg_type= Field::TIMESTAMP_UN_FIELD;
 
764
    }
 
765
 
837
766
    LEX_STRING comment;
838
 
 
839
 
    if (field_extra_info)
840
 
    {
841
 
      char tmp= field_extra_info[i];
842
 
      column_format= (enum column_format_type)
843
 
                    ((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
844
 
    }
845
 
    if (new_frm_ver >= 3)
846
 
    {
847
 
      /* new frm file in 4.1 */
848
 
      field_length= uint2korr(strpos+3);
849
 
      recpos=       uint3korr(strpos+5);
850
 
      pack_flag=    uint2korr(strpos+8);
851
 
      unireg_type=  (uint) strpos[10];
852
 
      interval_nr=  (uint) strpos[12];
853
 
      uint comment_length=uint2korr(strpos+15);
854
 
      field_type=(enum_field_types) (uint) strpos[13];
855
 
 
856
 
      {
857
 
        if (!strpos[14])
858
 
          charset= &my_charset_bin;
859
 
        else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
860
 
        {
861
 
          error= 5; // Unknown or unavailable charset
862
 
          errarg= (int) strpos[14];
863
 
          goto err;
864
 
        }
865
 
      }
866
 
      if (!comment_length)
867
 
      {
868
 
        comment.str= (char*) "";
869
 
        comment.length=0;
870
 
      }
871
 
      else
872
 
      {
873
 
        comment.str=    (char*) comment_pos;
874
 
        comment.length= comment_length;
875
 
        comment_pos+=   comment_length;
876
 
      }
 
767
    if (!pfield.has_comment())
 
768
    {
 
769
      comment.str= (char*)"";
 
770
      comment.length= 0;
877
771
    }
878
772
    else
879
773
    {
880
 
      field_length= (uint) strpos[3];
881
 
      recpos=       uint2korr(strpos+4),
882
 
      pack_flag=    uint2korr(strpos+6);
883
 
      pack_flag&=   ~FIELDFLAG_NO_DEFAULT;     // Safety for old files
884
 
      unireg_type=  (uint) strpos[8];
885
 
      interval_nr=  (uint) strpos[10];
886
 
 
887
 
      /* old frm file */
888
 
      field_type= (enum_field_types) f_packtype(pack_flag);
889
 
      if (f_is_binary(pack_flag))
 
774
      size_t len= pfield.comment().length();
 
775
      const char* str= pfield.comment().c_str();
 
776
 
 
777
      comment.str= strmake_root(&share->mem_root, str, len);
 
778
      comment.length= len;
 
779
    }
 
780
 
 
781
    enum_field_types field_type;
 
782
 
 
783
    field_type= proto_field_type_to_drizzle_type(pfield.type());
 
784
 
 
785
    const CHARSET_INFO *charset= &my_charset_bin;
 
786
 
 
787
    if (field_type == DRIZZLE_TYPE_BLOB ||
 
788
        field_type == DRIZZLE_TYPE_VARCHAR)
 
789
    {
 
790
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
 
791
 
 
792
      charset= get_charset(field_options.has_collation_id() ?
 
793
                           field_options.collation_id() : 0);
 
794
 
 
795
      if (! charset)
 
796
        charset= default_charset_info;
 
797
    }
 
798
 
 
799
    if (field_type == DRIZZLE_TYPE_ENUM)
 
800
    {
 
801
      message::Table::Field::SetFieldOptions field_options= pfield.set_options();
 
802
 
 
803
      charset= get_charset(field_options.has_collation_id()?
 
804
                           field_options.collation_id() : 0);
 
805
 
 
806
      if (! charset)
 
807
              charset= default_charset_info;
 
808
    }
 
809
 
 
810
    uint8_t decimals= 0;
 
811
    if (field_type == DRIZZLE_TYPE_NEWDECIMAL
 
812
        || field_type == DRIZZLE_TYPE_DOUBLE)
 
813
    {
 
814
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
815
 
 
816
      if (! pfield.has_numeric_options() || ! fo.has_scale())
890
817
      {
891
818
        /*
892
 
          Try to choose the best 4.1 type:
893
 
          - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" 
894
 
            try to find a binary collation for character set.
895
 
          - for other types (e.g. BLOB) just use my_charset_bin. 
 
819
          We don't write the default to table proto so
 
820
          if no decimals specified for DOUBLE, we use the default.
896
821
        */
897
 
        if (!f_is_blob(pack_flag))
 
822
        decimals= NOT_FIXED_DEC;
 
823
      }
 
824
      else
 
825
      {
 
826
        if (fo.scale() > DECIMAL_MAX_SCALE)
898
827
        {
899
 
          // 3.23 or 4.0 string
900
 
          if (!(charset= get_charset_by_csname(share->table_charset->csname,
901
 
                                               MY_CS_BINSORT, MYF(0))))
902
 
            charset= &my_charset_bin;
 
828
          error= 4;
 
829
          goto err;
903
830
        }
904
 
        else
905
 
          charset= &my_charset_bin;
 
831
        decimals= static_cast<uint8_t>(fo.scale());
906
832
      }
907
 
      else
908
 
        charset= share->table_charset;
909
 
      memset(&comment, 0, sizeof(comment));
910
 
    }
911
 
 
912
 
    if (interval_nr && charset->mbminlen > 1)
913
 
    {
914
 
      /* Unescape UCS2 intervals from HEX notation */
915
 
      TYPELIB *interval= share->intervals + interval_nr - 1;
916
 
      unhex_type2(interval);
917
 
    }
918
 
 
919
 
    *field_ptr= reg_field=
920
 
      make_field(share, record+recpos,
921
 
                 (uint32_t) field_length,
922
 
                 null_pos, null_bit_pos,
923
 
                 pack_flag,
924
 
                 field_type,
925
 
                 charset,
926
 
                 (Field::utype) MTYP_TYPENR(unireg_type),
927
 
                 (interval_nr ?
928
 
                  share->intervals+interval_nr-1 :
929
 
                  (TYPELIB*) 0),
930
 
                 share->fieldnames.type_names[i]);
931
 
    if (!reg_field)                             // Not supported field type
932
 
    {
933
 
      error= 4;
934
 
      goto err;                 /* purecov: inspected */
935
 
    }
936
 
 
937
 
    reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
938
 
    reg_field->field_index= i;
939
 
    reg_field->comment=comment;
940
 
    if (!(reg_field->flags & NOT_NULL_FLAG))
941
 
    {
942
 
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
 
833
    }
 
834
 
 
835
    Item *default_value= NULL;
 
836
 
 
837
    if (pfield.options().has_default_value() ||
 
838
        pfield.options().has_default_null()  ||
 
839
        pfield.options().has_default_bin_value())
 
840
    {
 
841
      default_value= default_value_item(field_type,
 
842
                                        charset,
 
843
                                        pfield.options().default_null(),
 
844
                                        &pfield.options().default_value(),
 
845
                                        &pfield.options().default_bin_value());
 
846
    }
 
847
 
 
848
 
 
849
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
850
    memset(&temp_table, 0, sizeof(temp_table));
 
851
    temp_table.s= share;
 
852
    temp_table.in_use= session;
 
853
    temp_table.s->db_low_byte_first= 1; //Cursor->low_byte_first();
 
854
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
855
 
 
856
    Field* f= make_field(share,
 
857
                         &share->mem_root,
 
858
                         record + field_offsets[fieldnr] + data_offset,
 
859
                         pfield.options().length(),
 
860
                         pfield.has_constraints() && pfield.constraints().is_nullable() ? true : false,
 
861
                         null_pos,
 
862
                         null_bit_pos,
 
863
                         decimals,
 
864
                         field_type,
 
865
                         charset,
 
866
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
867
                         ((field_type == DRIZZLE_TYPE_ENUM) ?
 
868
                          share->intervals + (interval_nr++)
 
869
                          : (TYPELIB*) 0),
 
870
                         share->fieldnames.type_names[fieldnr]);
 
871
 
 
872
    share->field[fieldnr]= f;
 
873
 
 
874
    f->init(&temp_table); /* blob default values need table obj */
 
875
 
 
876
    if (! (f->flags & NOT_NULL_FLAG))
 
877
    {
 
878
      *f->null_ptr|= f->null_bit;
 
879
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
943
880
        null_pos++;
944
 
    }
945
 
    if (f_no_default(pack_flag))
946
 
      reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
947
 
 
948
 
    if (reg_field->unireg_check == Field::NEXT_NUMBER)
949
 
      share->found_next_number_field= field_ptr;
950
 
    if (share->timestamp_field == reg_field)
951
 
      share->timestamp_field_offset= i;
952
 
 
953
 
    if (use_hash)
 
881
      null_count++;
 
882
    }
 
883
 
 
884
    if (default_value)
 
885
    {
 
886
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
887
      session->count_cuted_fields= CHECK_FIELD_WARN;
 
888
      int res= default_value->save_in_field(f, 1);
 
889
      session->count_cuted_fields= old_count_cuted_fields;
 
890
      if (res != 0 && res != 3) /* @TODO Huh? */
 
891
      {
 
892
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
 
893
        error= 1;
 
894
        goto err;
 
895
      }
 
896
    }
 
897
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
 
898
             (f->flags & NOT_NULL_FLAG))
 
899
    {
 
900
      f->set_notnull();
 
901
      f->store((int64_t) 1, true);
 
902
    }
 
903
    else
 
904
      f->reset();
 
905
 
 
906
    /* hack to undo f->init() */
 
907
    f->table= NULL;
 
908
    f->orig_table= NULL;
 
909
 
 
910
    f->field_index= fieldnr;
 
911
    f->comment= comment;
 
912
    if (! default_value &&
 
913
        ! (f->unireg_check==Field::NEXT_NUMBER) &&
 
914
        (f->flags & NOT_NULL_FLAG) &&
 
915
        (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
 
916
    {
 
917
      f->flags|= NO_DEFAULT_VALUE_FLAG;
 
918
    }
 
919
 
 
920
    if (f->unireg_check == Field::NEXT_NUMBER)
 
921
      share->found_next_number_field= &(share->field[fieldnr]);
 
922
 
 
923
    if (share->timestamp_field == f)
 
924
      share->timestamp_field_offset= fieldnr;
 
925
 
 
926
    if (use_hash) /* supposedly this never fails... but comments lie */
954
927
      (void) my_hash_insert(&share->name_hash,
955
 
                            (uchar*) field_ptr); // never fail
956
 
  }
957
 
  *field_ptr=0;                                 // End marker
958
 
 
959
 
  /* Fix key->name and key_part->field */
960
 
  if (key_parts)
961
 
  {
962
 
    uint primary_key=(uint) (find_type((char*) primary_key_name,
963
 
                                       &share->keynames, 3) - 1);
 
928
                            (unsigned char*)&(share->field[fieldnr]));
 
929
 
 
930
  }
 
931
 
 
932
  keyinfo= share->key_info;
 
933
  for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
 
934
  {
 
935
    key_part= keyinfo->key_part;
 
936
 
 
937
    for (unsigned int partnr= 0;
 
938
         partnr < keyinfo->key_parts;
 
939
         partnr++, key_part++)
 
940
    {
 
941
      /* 
 
942
       * Fix up key_part->offset by adding data_offset.
 
943
       * We really should compute offset as well.
 
944
       * But at least this way we are a little better.
 
945
       */
 
946
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
947
    }
 
948
  }
 
949
 
 
950
  /*
 
951
    We need to set the unused bits to 1. If the number of bits is a multiple
 
952
    of 8 there are no unused bits.
 
953
  */
 
954
 
 
955
  if (null_count & 7)
 
956
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
957
 
 
958
  share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
 
959
 
 
960
  share->last_null_bit_pos= null_bit_pos;
 
961
 
 
962
  free(field_offsets);
 
963
  free(field_pack_length);
 
964
 
 
965
  if (! (handler_file= share->db_type()->getCursor(share, session->mem_root)))
 
966
    abort(); // FIXME
 
967
 
 
968
  /* Fix key stuff */
 
969
  if (share->key_parts)
 
970
  {
 
971
    uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
 
972
                                                &share->keynames, 3) - 1); /* @TODO Huh? */
 
973
 
964
974
    int64_t ha_option= handler_file->ha_table_flags();
 
975
 
965
976
    keyinfo= share->key_info;
966
977
    key_part= keyinfo->key_part;
967
978
 
968
 
    for (uint key=0 ; key < share->keys ; key++,keyinfo++)
 
979
    for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
969
980
    {
970
 
      uint usable_parts= 0;
971
 
      keyinfo->name=(char*) share->keynames.type_names[key];
 
981
      uint32_t usable_parts= 0;
972
982
 
973
983
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
974
984
      {
975
 
        /*
976
 
          If the UNIQUE key doesn't have NULL columns and is not a part key
977
 
          declare this as a primary key.
978
 
        */
979
 
        primary_key=key;
980
 
        for (i=0 ; i < keyinfo->key_parts ;i++)
981
 
        {
982
 
          uint fieldnr= key_part[i].fieldnr;
983
 
          if (!fieldnr ||
984
 
              share->field[fieldnr-1]->null_ptr ||
985
 
              share->field[fieldnr-1]->key_length() !=
986
 
              key_part[i].length)
987
 
          {
988
 
            primary_key=MAX_KEY;                // Can't be used
989
 
            break;
990
 
          }
991
 
        }
 
985
        /*
 
986
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
987
          declare this as a primary key.
 
988
        */
 
989
        primary_key=key;
 
990
        for (uint32_t i= 0; i < keyinfo->key_parts; i++)
 
991
        {
 
992
          uint32_t fieldnr= key_part[i].fieldnr;
 
993
          if (! fieldnr ||
 
994
              share->field[fieldnr-1]->null_ptr ||
 
995
              share->field[fieldnr-1]->key_length() != key_part[i].length)
 
996
          {
 
997
            primary_key= MAX_KEY; // Can't be used
 
998
            break;
 
999
          }
 
1000
        }
992
1001
      }
993
1002
 
994
 
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1003
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
995
1004
      {
996
1005
        Field *field;
997
 
        if (new_field_pack_flag <= 1)
998
 
          key_part->fieldnr= (uint16_t) find_field(share->field,
999
 
                                                 share->default_values,
1000
 
                                                 (uint) key_part->offset,
1001
 
                                                 (uint) key_part->length);
1002
 
        if (!key_part->fieldnr)
 
1006
        if (! key_part->fieldnr)
1003
1007
        {
1004
 
          error= 4;                             // Wrong file
1005
 
          goto err;
 
1008
          abort(); // goto err;
1006
1009
        }
1007
1010
        field= key_part->field= share->field[key_part->fieldnr-1];
1008
1011
        key_part->type= field->key_type();
1009
1012
        if (field->null_ptr)
1010
1013
        {
1011
 
          key_part->null_offset=(uint) ((uchar*) field->null_ptr -
 
1014
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1012
1015
                                        share->default_values);
1013
1016
          key_part->null_bit= field->null_bit;
1014
1017
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1032
1035
                           (keyinfo->key_parts == 1)) ?
1033
1036
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1034
1037
        if (i == 0)
1035
 
          field->key_start.set_bit(key);
 
1038
          field->key_start.set(key);
1036
1039
        if (field->key_length() == key_part->length &&
1037
1040
            !(field->flags & BLOB_FLAG))
1038
1041
        {
1039
1042
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1040
1043
          {
1041
 
            share->keys_for_keyread.set_bit(key);
1042
 
            field->part_of_key.set_bit(key);
1043
 
            field->part_of_key_not_clustered.set_bit(key);
 
1044
            share->keys_for_keyread.set(key);
 
1045
            field->part_of_key.set(key);
 
1046
            field->part_of_key_not_clustered.set(key);
1044
1047
          }
1045
1048
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1046
 
            field->part_of_sortkey.set_bit(key);
 
1049
            field->part_of_sortkey.set(key);
1047
1050
        }
1048
1051
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1049
1052
            usable_parts == i)
1059
1062
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1060
1063
          {
1061
1064
            field->part_of_key= share->keys_in_use;
1062
 
            if (field->part_of_sortkey.is_set(key))
 
1065
            if (field->part_of_sortkey.test(key))
1063
1066
              field->part_of_sortkey= share->keys_in_use;
1064
1067
          }
1065
1068
        }
1082
1085
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1083
1086
    }
1084
1087
    if (primary_key < MAX_KEY &&
1085
 
        (share->keys_in_use.is_set(primary_key)))
 
1088
        (share->keys_in_use.test(primary_key)))
1086
1089
    {
1087
1090
      share->primary_key= primary_key;
1088
1091
      /*
1089
 
        If we are using an integer as the primary key then allow the user to
1090
 
        refer to it as '_rowid'
 
1092
        If we are using an integer as the primary key then allow the user to
 
1093
        refer to it as '_rowid'
1091
1094
      */
1092
1095
      if (share->key_info[primary_key].key_parts == 1)
1093
1096
      {
1094
 
        Field *field= share->key_info[primary_key].key_part[0].field;
1095
 
        if (field && field->result_type() == INT_RESULT)
 
1097
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1098
        if (field && field->result_type() == INT_RESULT)
1096
1099
        {
1097
1100
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1098
 
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1101
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1099
1102
                                      fieldnr);
1100
1103
        }
1101
1104
      }
1105
1108
  }
1106
1109
  else
1107
1110
    share->primary_key= MAX_KEY;
1108
 
  x_free((uchar*) disk_buff);
1109
 
  disk_buff=0;
1110
 
  if (new_field_pack_flag <= 1)
1111
 
  {
1112
 
    /* Old file format with default as not null */
1113
 
    uint null_length= (share->null_fields+7)/8;
1114
 
    memset(share->default_values + (null_flags - (uchar*) record), 
1115
 
          null_length, 255);
1116
 
  }
1117
1111
 
1118
1112
  if (share->found_next_number_field)
1119
1113
  {
1120
 
    reg_field= *share->found_next_number_field;
1121
 
    if ((int) (share->next_number_index= (uint)
 
1114
    Field *reg_field= *share->found_next_number_field;
 
1115
    if ((int) (share->next_number_index= (uint32_t)
1122
1116
               find_ref_key(share->key_info, share->keys,
1123
1117
                            share->default_values, reg_field,
1124
1118
                            &share->next_number_key_offset,
1135
1129
  if (share->blob_fields)
1136
1130
  {
1137
1131
    Field **ptr;
1138
 
    uint k, *save;
 
1132
    uint32_t k, *save;
1139
1133
 
1140
1134
    /* Store offsets to blob fields to find them fast */
1141
1135
    if (!(share->blob_field= save=
1142
1136
          (uint*) alloc_root(&share->mem_root,
1143
 
                             (uint) (share->blob_fields* sizeof(uint)))))
 
1137
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1144
1138
      goto err;
1145
 
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
 
1139
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1146
1140
    {
1147
1141
      if ((*ptr)->flags & BLOB_FLAG)
1148
 
        (*save++)= k;
 
1142
        (*save++)= k;
1149
1143
    }
1150
1144
  }
1151
1145
 
1152
 
  /*
1153
 
    the correct null_bytes can now be set, since bitfields have been taken
1154
 
    into account
1155
 
  */
1156
 
  share->null_bytes= (null_pos - (uchar*) null_flags +
1157
 
                      (null_bit_pos + 7) / 8);
1158
 
  share->last_null_bit_pos= null_bit_pos;
1159
 
 
1160
1146
  share->db_low_byte_first= handler_file->low_byte_first();
1161
1147
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1162
1148
 
 
1149
  my_bitmap_map *bitmaps;
 
1150
 
1163
1151
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1164
1152
                                             share->column_bitmap_size)))
1165
1153
    goto err;
1166
 
  bitmap_init(&share->all_set, bitmaps, share->fields, false);
1167
 
  bitmap_set_all(&share->all_set);
 
1154
  share->all_set.init(bitmaps, share->fields);
 
1155
  share->all_set.setAll();
1168
1156
 
1169
 
  delete handler_file;
1170
 
  if (buff)
1171
 
    my_free(buff, MYF(0));
 
1157
  if (handler_file)
 
1158
    delete handler_file;
1172
1159
  return (0);
1173
1160
 
1174
 
 err:
1175
 
  if (buff)
1176
 
    my_free(buff, MYF(0));
 
1161
err:
1177
1162
  share->error= error;
1178
1163
  share->open_errno= my_errno;
1179
 
  share->errarg= errarg;
1180
 
  x_free((uchar*) disk_buff);
1181
 
  delete handler_file;
 
1164
  share->errarg= 0;
1182
1165
  hash_free(&share->name_hash);
1183
 
 
1184
 
  open_table_error(share, error, share->open_errno, errarg);
 
1166
  if (handler_file)
 
1167
    delete handler_file;
 
1168
  share->open_table_error(error, share->open_errno, 0);
 
1169
 
 
1170
  return error;
 
1171
}
 
1172
 
 
1173
/*
 
1174
  Read table definition from a binary / text based .frm file
 
1175
 
 
1176
  SYNOPSIS
 
1177
  open_table_def()
 
1178
  session               Thread Cursor
 
1179
  share         Fill this with table definition
 
1180
 
 
1181
  NOTES
 
1182
    This function is called when the table definition is not cached in
 
1183
    table_def_cache
 
1184
    The data is returned in 'share', which is alloced by
 
1185
    alloc_table_share().. The code assumes that share is initialized.
 
1186
 
 
1187
  RETURN VALUES
 
1188
   0    ok
 
1189
   1    Error (see open_table_error)
 
1190
   2    Error (see open_table_error)
 
1191
   3    Wrong data in .frm file
 
1192
   4    Error (see open_table_error)
 
1193
   5    Error (see open_table_error: charset unavailable)
 
1194
   6    Unknown .frm version
 
1195
*/
 
1196
 
 
1197
int open_table_def(Session *session, TableShare *share)
 
1198
{
 
1199
  int error;
 
1200
  bool error_given;
 
1201
 
 
1202
  error= 1;
 
1203
  error_given= 0;
 
1204
 
 
1205
  message::Table table;
 
1206
 
 
1207
  error= plugin::StorageEngine::getTableProto(share->normalized_path.str,
 
1208
                                              &table);
 
1209
 
 
1210
  if (error != EEXIST)
 
1211
  {
 
1212
    if (error>0)
 
1213
    {
 
1214
      my_errno= error;
 
1215
      error= 1;
 
1216
    }
 
1217
    else
 
1218
    {
 
1219
      if (!table.IsInitialized())
 
1220
      {
 
1221
        error= 4;
 
1222
      }
 
1223
    }
 
1224
    goto err_not_open;
 
1225
  }
 
1226
 
 
1227
  error= parse_table_proto(session, table, share);
 
1228
 
 
1229
  share->table_category= get_table_category(& share->db);
 
1230
 
 
1231
  if (!error)
 
1232
    session->status_var.opened_shares++;
 
1233
 
 
1234
err_not_open:
 
1235
  if (error && !error_given)
 
1236
  {
 
1237
    share->error= error;
 
1238
    share->open_table_error(error, (share->open_errno= my_errno), 0);
 
1239
  }
 
1240
 
1185
1241
  return(error);
1186
 
} /* open_binary_frm */
 
1242
}
1187
1243
 
1188
1244
 
1189
1245
/*
1190
 
  Open a table based on a TABLE_SHARE
 
1246
  Open a table based on a TableShare
1191
1247
 
1192
1248
  SYNOPSIS
1193
1249
    open_table_from_share()
1194
 
    thd                 Thread handler
 
1250
    session                     Thread Cursor
1195
1251
    share               Table definition
1196
1252
    alias               Alias for table
1197
1253
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1214
1270
   7    Table definition has changed in engine
1215
1271
*/
1216
1272
 
1217
 
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
1218
 
                          uint db_stat, uint prgflag, uint ha_open_flags,
1219
 
                          TABLE *outparam, open_table_mode open_mode)
 
1273
int open_table_from_share(Session *session, TableShare *share, const char *alias,
 
1274
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
 
1275
                          Table *outparam, open_table_mode open_mode)
1220
1276
{
1221
1277
  int error;
1222
 
  uint records, i, bitmap_size;
 
1278
  uint32_t records, i, bitmap_size;
1223
1279
  bool error_reported= false;
1224
 
  uchar *record, *bitmaps;
 
1280
  unsigned char *record, *bitmaps;
1225
1281
  Field **field_ptr;
1226
1282
 
1227
 
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
1228
 
  assert(thd->lex->is_lex_started);
 
1283
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1284
  assert(session->lex->is_lex_started);
1229
1285
 
1230
1286
  error= 1;
1231
 
  memset(outparam, 0, sizeof(*outparam));
1232
 
  outparam->in_use= thd;
1233
 
  outparam->s= share;
1234
 
  outparam->db_stat= db_stat;
1235
 
  outparam->write_row_record= NULL;
1236
 
 
1237
 
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1238
 
 
1239
 
  if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
 
1287
  outparam->resetTable(session, share, db_stat);
 
1288
 
 
1289
 
 
1290
  if (!(outparam->alias= strdup(alias)))
1240
1291
    goto err;
1241
 
  outparam->quick_keys.init();
1242
 
  outparam->covering_keys.init();
1243
 
  outparam->keys_in_use_for_query.init();
1244
1292
 
1245
 
  /* Allocate handler */
1246
 
  outparam->file= 0;
 
1293
  /* Allocate Cursor */
1247
1294
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
1248
1295
  {
1249
 
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1250
 
                                          share->db_type())))
 
1296
    if (!(outparam->file= share->db_type()->getCursor(share, &outparam->mem_root)))
1251
1297
      goto err;
1252
1298
  }
1253
1299
  else
1256
1302
  }
1257
1303
 
1258
1304
  error= 4;
1259
 
  outparam->reginfo.lock_type= TL_UNLOCK;
1260
 
  outparam->current_lock= F_UNLCK;
1261
 
  records=0;
 
1305
  records= 0;
1262
1306
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1263
1307
    records=1;
1264
1308
  if (prgflag & (READ_ALL+EXTRA_RECORD))
1265
1309
    records++;
1266
1310
 
1267
 
  if (!(record= (uchar*) alloc_root(&outparam->mem_root,
 
1311
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1268
1312
                                   share->rec_buff_length * records)))
1269
 
    goto err;                                   /* purecov: inspected */
 
1313
    goto err;
1270
1314
 
1271
1315
  if (records == 0)
1272
1316
  {
1298
1342
#endif
1299
1343
 
1300
1344
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1301
 
                                          (uint) ((share->fields+1)*
 
1345
                                          (uint32_t) ((share->fields+1)*
1302
1346
                                                  sizeof(Field*)))))
1303
 
    goto err;                                   /* purecov: inspected */
 
1347
    goto err;
1304
1348
 
1305
1349
  outparam->field= field_ptr;
1306
1350
 
1307
 
  record= (uchar*) outparam->record[0]-1;       /* Fieldstart = 1 */
1308
 
  if (share->null_field_first)
1309
 
    outparam->null_flags= (uchar*) record+1;
1310
 
  else
1311
 
    outparam->null_flags= (uchar*) (record+ 1+ share->reclength -
1312
 
                                    share->null_bytes);
 
1351
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
 
1352
 
 
1353
  outparam->null_flags= (unsigned char*) record+1;
1313
1354
 
1314
1355
  /* Setup copy of fields from share, but use the right alias and record */
1315
 
  for (i=0 ; i < share->fields; i++, field_ptr++)
 
1356
  for (i= 0 ; i < share->fields; i++, field_ptr++)
1316
1357
  {
1317
1358
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1318
1359
      goto err;
1321
1362
 
1322
1363
  if (share->found_next_number_field)
1323
1364
    outparam->found_next_number_field=
1324
 
      outparam->field[(uint) (share->found_next_number_field - share->field)];
 
1365
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1325
1366
  if (share->timestamp_field)
1326
1367
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1327
1368
 
1331
1372
  {
1332
1373
    KEY *key_info, *key_info_end;
1333
1374
    KEY_PART_INFO *key_part;
1334
 
    uint n_length;
 
1375
    uint32_t n_length;
1335
1376
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1336
1377
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1337
1378
      goto err;
1338
1379
    outparam->key_info= key_info;
1339
 
    key_part= (my_reinterpret_cast(KEY_PART_INFO*) (key_info+share->keys));
1340
 
    
 
1380
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
 
1381
 
1341
1382
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1342
1383
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1343
1384
                                                   share->key_parts));
1375
1416
  /* Allocate bitmaps */
1376
1417
 
1377
1418
  bitmap_size= share->column_bitmap_size;
1378
 
  if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*3)))
 
1419
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1379
1420
    goto err;
1380
 
  bitmap_init(&outparam->def_read_set,
1381
 
              (my_bitmap_map*) bitmaps, share->fields, false);
1382
 
  bitmap_init(&outparam->def_write_set,
1383
 
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1384
 
  bitmap_init(&outparam->tmp_set,
1385
 
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
 
1421
  outparam->def_read_set.init((my_bitmap_map*) bitmaps, share->fields);
 
1422
  outparam->def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
 
1423
  outparam->tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
1386
1424
  outparam->default_column_bitmaps();
1387
1425
 
1388
1426
  /* The table struct is now initialized;  Open the table */
1394
1432
                  ha_open(outparam, share->normalized_path.str,
1395
1433
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1396
1434
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1397
 
                           ((db_stat & HA_WAIT_IF_LOCKED) ||
1398
 
                            (specialflag & SPECIAL_WAIT_IF_LOCKED)) ?
1399
 
                           HA_OPEN_WAIT_IF_LOCKED :
 
1435
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
1400
1436
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1401
1437
                          HA_OPEN_ABORT_IF_LOCKED :
1402
1438
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1431
1467
            error= 7;
1432
1468
          break;
1433
1469
      }
1434
 
      goto err;                                 /* purecov: inspected */
 
1470
      goto err;
1435
1471
    }
1436
1472
  }
1437
1473
 
1438
 
#if defined(HAVE_purify) 
 
1474
#if defined(HAVE_purify)
1439
1475
  memset(bitmaps, 0, bitmap_size*3);
1440
1476
#endif
1441
1477
 
1442
 
  outparam->no_replicate= outparam->file &&
1443
 
                          test(outparam->file->ha_table_flags() &
1444
 
                               HA_HAS_OWN_BINLOGGING);
1445
 
  thd->status_var.opened_tables++;
 
1478
  session->status_var.opened_tables++;
1446
1479
 
1447
1480
  return (0);
1448
1481
 
1449
1482
 err:
1450
1483
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1451
 
    open_table_error(share, error, my_errno, 0);
 
1484
    share->open_table_error(error, my_errno, 0);
1452
1485
  delete outparam->file;
1453
1486
  outparam->file= 0;                            // For easier error checking
1454
 
  outparam->db_stat=0;
 
1487
  outparam->db_stat= 0;
1455
1488
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1456
 
  my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR));
 
1489
  free((char*) outparam->alias);
1457
1490
  return (error);
1458
1491
}
1459
1492
 
1460
 
 
1461
1493
/*
1462
1494
  Free information allocated by openfrm
1463
1495
 
1464
1496
  SYNOPSIS
1465
1497
    closefrm()
1466
 
    table               TABLE object to free
 
1498
    table               Table object to free
1467
1499
    free_share          Is 1 if we also want to free table_share
1468
1500
*/
1469
1501
 
1470
 
int closefrm(register TABLE *table, bool free_share)
 
1502
int Table::closefrm(bool free_share)
1471
1503
{
1472
 
  int error=0;
 
1504
  int error= 0;
1473
1505
 
1474
 
  if (table->db_stat)
1475
 
    error=table->file->close();
1476
 
  my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
1477
 
  table->alias= 0;
1478
 
  if (table->field)
 
1506
  if (db_stat)
 
1507
    error= file->close();
 
1508
  free((char*) alias);
 
1509
  alias= NULL;
 
1510
  if (field)
1479
1511
  {
1480
 
    for (Field **ptr=table->field ; *ptr ; ptr++)
 
1512
    for (Field **ptr=field ; *ptr ; ptr++)
1481
1513
      delete *ptr;
1482
 
    table->field= 0;
 
1514
    field= 0;
1483
1515
  }
1484
 
  delete table->file;
1485
 
  table->file= 0;                               /* For easier errorchecking */
 
1516
  delete file;
 
1517
  file= 0;                              /* For easier errorchecking */
1486
1518
  if (free_share)
1487
1519
  {
1488
 
    if (table->s->tmp_table == NO_TMP_TABLE)
1489
 
      release_table_share(table->s, RELEASE_NORMAL);
 
1520
    if (s->tmp_table == NO_TMP_TABLE)
 
1521
      TableShare::release(s);
1490
1522
    else
1491
 
      free_table_share(table->s);
 
1523
      s->free_table_share();
1492
1524
  }
1493
 
  free_root(&table->mem_root, MYF(0));
1494
 
  return(error);
 
1525
  free_root(&mem_root, MYF(0));
 
1526
 
 
1527
  return error;
1495
1528
}
1496
1529
 
1497
1530
 
1498
1531
/* Deallocate temporary blob storage */
1499
1532
 
1500
 
void free_blobs(register TABLE *table)
 
1533
void free_blobs(register Table *table)
1501
1534
{
1502
 
  uint *ptr, *end;
1503
 
  for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
 
1535
  uint32_t *ptr, *end;
 
1536
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
1504
1537
       ptr != end ;
1505
1538
       ptr++)
1506
1539
    ((Field_blob*) table->field[*ptr])->free();
1507
1540
}
1508
1541
 
1509
1542
 
1510
 
        /* Find where a form starts */
1511
 
        /* if formname is NullS then only formnames is read */
1512
 
 
1513
 
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
1514
 
{
1515
 
  uint a_length,names,length;
1516
 
  uchar *pos,*buf;
1517
 
  ulong ret_value=0;
1518
 
 
1519
 
  names=uint2korr(head+8);
1520
 
  a_length=(names+2)*sizeof(char *);            /* Room for two extra */
1521
 
 
1522
 
  if (!save_names)
1523
 
    a_length=0;
1524
 
  else
1525
 
    save_names->type_names=0;                   /* Clear if error */
1526
 
 
1527
 
  if (names)
1528
 
  {
1529
 
    length=uint2korr(head+4);
1530
 
    VOID(my_seek(file,64L,MY_SEEK_SET,MYF(0)));
1531
 
    if (!(buf= (uchar*) my_malloc((size_t) length+a_length+names*4,
1532
 
                                  MYF(MY_WME))) ||
1533
 
        my_read(file, buf+a_length, (size_t) (length+names*4),
1534
 
                MYF(MY_NABP)))
1535
 
    {                                           /* purecov: inspected */
1536
 
      x_free((uchar*) buf);                     /* purecov: inspected */
1537
 
      return(0L);                               /* purecov: inspected */
1538
 
    }
1539
 
    pos= buf+a_length+length;
1540
 
    ret_value=uint4korr(pos);
1541
 
  }
1542
 
  if (! save_names)
1543
 
  {
1544
 
    if (names)
1545
 
      my_free((uchar*) buf,MYF(0));
1546
 
  }
1547
 
  else if (!names)
1548
 
    memset(save_names, 0, sizeof(save_names));
1549
 
  else
1550
 
  {
1551
 
    char *str;
1552
 
    str=(char *) (buf+a_length);
1553
 
    fix_type_pointers((const char ***) &buf,save_names,1,&str);
1554
 
  }
1555
 
  return(ret_value);
1556
 
}
1557
 
 
1558
 
 
1559
 
/*
1560
 
  Read string from a file with malloc
1561
 
 
1562
 
  NOTES:
1563
 
    We add an \0 at end of the read string to make reading of C strings easier
1564
 
*/
1565
 
 
1566
 
int read_string(File file, uchar**to, size_t length)
1567
 
{
1568
 
 
1569
 
  x_free(*to);
1570
 
  if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
1571
 
      my_read(file, *to, length,MYF(MY_NABP)))
1572
 
  {
1573
 
    x_free(*to);                              /* purecov: inspected */
1574
 
    *to= 0;                                   /* purecov: inspected */
1575
 
    return(1);                           /* purecov: inspected */
1576
 
  }
1577
 
  *((char*) *to+length)= '\0';
1578
 
  return (0);
1579
 
} /* read_string */
1580
 
 
1581
 
 
1582
 
        /* Add a new form to a form file */
1583
 
 
1584
 
ulong make_new_entry(File file, uchar *fileinfo, TYPELIB *formnames,
1585
 
                     const char *newname)
1586
 
{
1587
 
  uint i,bufflength,maxlength,n_length,length,names;
1588
 
  ulong endpos,newpos;
1589
 
  uchar buff[IO_SIZE];
1590
 
  uchar *pos;
1591
 
 
1592
 
  length=(uint) strlen(newname)+1;
1593
 
  n_length=uint2korr(fileinfo+4);
1594
 
  maxlength=uint2korr(fileinfo+6);
1595
 
  names=uint2korr(fileinfo+8);
1596
 
  newpos=uint4korr(fileinfo+10);
1597
 
 
1598
 
  if (64+length+n_length+(names+1)*4 > maxlength)
1599
 
  {                                             /* Expand file */
1600
 
    newpos+=IO_SIZE;
1601
 
    int4store(fileinfo+10,newpos);
1602
 
    endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */
1603
 
    bufflength= (uint) (endpos & (IO_SIZE-1));  /* IO_SIZE is a power of 2 */
1604
 
 
1605
 
    while (endpos > maxlength)
1606
 
    {
1607
 
      VOID(my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0)));
1608
 
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
1609
 
        return(0L);
1610
 
      VOID(my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1611
 
                   MYF(0)));
1612
 
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1613
 
        return(0);
1614
 
      endpos-=bufflength; bufflength=IO_SIZE;
1615
 
    }
1616
 
    memset(buff, 0, IO_SIZE);                   /* Null new block */
1617
 
    VOID(my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0)));
1618
 
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1619
 
        return(0L);
1620
 
    maxlength+=IO_SIZE;                         /* Fix old ref */
1621
 
    int2store(fileinfo+6,maxlength);
1622
 
    for (i=names, pos= (uchar*) *formnames->type_names+n_length-1; i-- ;
1623
 
         pos+=4)
1624
 
    {
1625
 
      endpos=uint4korr(pos)+IO_SIZE;
1626
 
      int4store(pos,endpos);
1627
 
    }
1628
 
  }
1629
 
 
1630
 
  if (n_length == 1 )
1631
 
  {                                             /* First name */
1632
 
    length++;
1633
 
    VOID(strxmov((char*) buff,"/",newname,"/",NullS));
1634
 
  }
1635
 
  else
1636
 
    VOID(strxmov((char*) buff,newname,"/",NullS)); /* purecov: inspected */
1637
 
  VOID(my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0)));
1638
 
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
1639
 
      (names && my_write(file,(uchar*) (*formnames->type_names+n_length-1),
1640
 
                         names*4, MYF(MY_NABP+MY_WME))) ||
1641
 
      my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
1642
 
    return(0L); /* purecov: inspected */
1643
 
 
1644
 
  int2store(fileinfo+8,names+1);
1645
 
  int2store(fileinfo+4,n_length+length);
1646
 
  (void)ftruncate(file, newpos);/* Append file with '\0' */
1647
 
  return(newpos);
1648
 
} /* make_new_entry */
1649
 
 
1650
 
 
1651
1543
        /* error message when opening a form file */
1652
1544
 
1653
 
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
 
1545
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
1654
1546
{
1655
1547
  int err_no;
1656
1548
  char buff[FN_REFLEN];
1657
1549
  myf errortype= ME_ERROR+ME_WAITTANG;
1658
1550
 
1659
 
  switch (error) {
 
1551
  switch (pass_error) {
1660
1552
  case 7:
1661
1553
  case 1:
1662
1554
    if (db_errno == ENOENT)
1663
 
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
 
1555
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
1664
1556
    else
1665
1557
    {
1666
 
      strxmov(buff, share->normalized_path.str, reg_ext, NullS);
 
1558
      sprintf(buff,"%s",normalized_path.str);
1667
1559
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1668
1560
               errortype, buff, db_errno);
1669
1561
    }
1670
1562
    break;
1671
1563
  case 2:
1672
1564
  {
1673
 
    handler *file= 0;
 
1565
    Cursor *file= 0;
1674
1566
    const char *datext= "";
1675
 
    
1676
 
    if (share->db_type() != NULL)
 
1567
 
 
1568
    if (db_type() != NULL)
1677
1569
    {
1678
 
      if ((file= get_new_handler(share, current_thd->mem_root,
1679
 
                                 share->db_type())))
 
1570
      if ((file= db_type()->getCursor(this, current_session->mem_root)))
1680
1571
      {
1681
 
        if (!(datext= *file->bas_ext()))
 
1572
        if (!(datext= *db_type()->bas_ext()))
1682
1573
          datext= "";
1683
1574
      }
1684
1575
    }
1685
1576
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1686
1577
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1687
 
    strxmov(buff, share->normalized_path.str, datext, NullS);
 
1578
    sprintf(buff,"%s%s", normalized_path.str,datext);
1688
1579
    my_error(err_no,errortype, buff, db_errno);
1689
1580
    delete file;
1690
1581
    break;
1691
1582
  }
1692
1583
  case 5:
1693
1584
  {
1694
 
    const char *csname= get_charset_name((uint) errarg);
 
1585
    const char *csname= get_charset_name((uint32_t) pass_errarg);
1695
1586
    char tmp[10];
1696
1587
    if (!csname || csname[0] =='?')
1697
1588
    {
1698
 
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
 
1589
      snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
1699
1590
      csname= tmp;
1700
1591
    }
1701
1592
    my_printf_error(ER_UNKNOWN_COLLATION,
1702
 
                    _("Unknown collation '%s' in table '%-.64s' definition"), 
1703
 
                    MYF(0), csname, share->table_name.str);
 
1593
                    _("Unknown collation '%s' in table '%-.64s' definition"),
 
1594
                    MYF(0), csname, table_name.str);
1704
1595
    break;
1705
1596
  }
1706
1597
  case 6:
1707
 
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
 
1598
    sprintf(buff,"%s", normalized_path.str);
1708
1599
    my_printf_error(ER_NOT_FORM_FILE,
1709
1600
                    _("Table '%-.64s' was created with a different version "
1710
 
                    "of MySQL and cannot be read"), 
 
1601
                    "of Drizzle and cannot be read"),
1711
1602
                    MYF(0), buff);
1712
1603
    break;
1713
1604
  case 8:
1714
1605
    break;
1715
1606
  default:                              /* Better wrong error than none */
1716
1607
  case 4:
1717
 
    strxmov(buff, share->normalized_path.str, reg_ext, NullS);
 
1608
    sprintf(buff,"%s", normalized_path.str);
1718
1609
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1719
1610
    break;
1720
1611
  }
1722
1613
} /* open_table_error */
1723
1614
 
1724
1615
 
1725
 
        /*
1726
 
        ** fix a str_type to a array type
1727
 
        ** typeparts separated with some char. differents types are separated
1728
 
        ** with a '\0'
1729
 
        */
1730
 
 
1731
 
static void
1732
 
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
1733
 
                  char **names)
1734
 
{
1735
 
  char *type_name, *ptr;
1736
 
  char chr;
1737
 
 
1738
 
  ptr= *names;
1739
 
  while (types--)
1740
 
  {
1741
 
    point_to_type->name=0;
1742
 
    point_to_type->type_names= *array;
1743
 
 
1744
 
    if ((chr= *ptr))                    /* Test if empty type */
1745
 
    {
1746
 
      while ((type_name=strchr(ptr+1,chr)) != NullS)
1747
 
      {
1748
 
        *((*array)++) = ptr+1;
1749
 
        *type_name= '\0';               /* End string */
1750
 
        ptr=type_name;
1751
 
      }
1752
 
      ptr+=2;                           /* Skip end mark and last 0 */
1753
 
    }
1754
 
    else
1755
 
      ptr++;
1756
 
    point_to_type->count= (uint) (*array - point_to_type->type_names);
1757
 
    point_to_type++;
1758
 
    *((*array)++)= NullS;               /* End of type */
1759
 
  }
1760
 
  *names=ptr;                           /* Update end */
1761
 
  return;
1762
 
} /* fix_type_pointers */
1763
 
 
1764
 
 
1765
1616
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1766
1617
{
1767
1618
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
1768
1619
  if (!result)
1769
1620
    return 0;
1770
 
  result->count=strings.elements;
1771
 
  result->name="";
1772
 
  uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
 
1621
  result->count= strings.elements;
 
1622
  result->name= "";
 
1623
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
 
1624
  
1773
1625
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1774
1626
    return 0;
 
1627
    
1775
1628
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
 
1629
 
1776
1630
  List_iterator<String> it(strings);
1777
1631
  String *tmp;
1778
 
  for (uint i=0; (tmp=it++) ; i++)
 
1632
  for (uint32_t i= 0; (tmp= it++); i++)
1779
1633
  {
1780
1634
    result->type_names[i]= tmp->ptr();
1781
1635
    result->type_lengths[i]= tmp->length();
1782
1636
  }
1783
 
  result->type_names[result->count]= 0;         // End marker
 
1637
 
 
1638
  result->type_names[result->count]= 0;   // End marker
1784
1639
  result->type_lengths[result->count]= 0;
 
1640
 
1785
1641
  return result;
1786
1642
}
1787
1643
 
1788
 
 
1789
 
/*
1790
 
 Search after a field with given start & length
1791
 
 If an exact field isn't found, return longest field with starts
1792
 
 at right position.
1793
 
 
1794
 
 NOTES
1795
 
   This is needed because in some .frm fields 'fieldnr' was saved wrong
1796
 
 
1797
 
 RETURN
1798
 
   0  error
1799
 
   #  field number +1
1800
 
*/
1801
 
 
1802
 
static uint find_field(Field **fields, uchar *record, uint start, uint length)
1803
 
{
1804
 
  Field **field;
1805
 
  uint i, pos;
1806
 
 
1807
 
  pos= 0;
1808
 
  for (field= fields, i=1 ; *field ; i++,field++)
1809
 
  {
1810
 
    if ((*field)->offset(record) == start)
1811
 
    {
1812
 
      if ((*field)->key_length() == length)
1813
 
        return (i);
1814
 
      if (!pos || fields[pos-1]->pack_length() <
1815
 
          (*field)->pack_length())
1816
 
        pos= i;
1817
 
    }
1818
 
  }
1819
 
  return (pos);
1820
 
}
1821
 
 
1822
 
 
1823
1644
        /* Check that the integer is in the internal */
1824
1645
 
1825
1646
int set_zone(register int nr, int min_zone, int max_zone)
1845
1666
/*
1846
1667
  Store an SQL quoted string.
1847
1668
 
1848
 
  SYNOPSIS  
 
1669
  SYNOPSIS
1849
1670
    append_unescaped()
1850
1671
    res         result String
1851
1672
    pos         string to be quoted
1856
1677
    May fail with some multibyte charsets though.
1857
1678
*/
1858
1679
 
1859
 
void append_unescaped(String *res, const char *pos, uint length)
 
1680
void append_unescaped(String *res, const char *pos, uint32_t length)
1860
1681
{
1861
1682
  const char *end= pos+length;
1862
1683
  res->append('\'');
1863
1684
 
1864
1685
  for (; pos != end ; pos++)
1865
1686
  {
1866
 
#if defined(USE_MB)
1867
 
    uint mblen;
 
1687
    uint32_t mblen;
1868
1688
    if (use_mb(default_charset_info) &&
1869
1689
        (mblen= my_ismbchar(default_charset_info, pos, end)))
1870
1690
    {
1871
1691
      res->append(pos, mblen);
1872
1692
      pos+= mblen;
 
1693
      if (pos >= end)
 
1694
        break;
1873
1695
      continue;
1874
1696
    }
1875
 
#endif
1876
1697
 
1877
1698
    switch (*pos) {
1878
1699
    case 0:                             /* Must be escaped for 'mysql' */
1904
1725
}
1905
1726
 
1906
1727
 
1907
 
        /* Create a .frm file */
1908
 
 
1909
 
File create_frm(THD *thd, const char *name, const char *db,
1910
 
                const char *table, uint reclength, uchar *fileinfo,
1911
 
                HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
1912
 
{
1913
 
  register File file;
1914
 
  ulong length;
1915
 
  uchar fill[IO_SIZE];
1916
 
  int create_flags= O_RDWR | O_TRUNC;
1917
 
  ulong key_comment_total_bytes= 0;
1918
 
  uint i;
1919
 
 
1920
 
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
1921
 
    create_flags|= O_EXCL | O_NOFOLLOW;
1922
 
 
1923
 
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
1924
 
  if (create_info->max_rows > UINT32_MAX)
1925
 
    create_info->max_rows= UINT32_MAX;
1926
 
  if (create_info->min_rows > UINT32_MAX)
1927
 
    create_info->min_rows= UINT32_MAX;
1928
 
 
1929
 
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
1930
 
  {
1931
 
    uint key_length, tmp_key_length;
1932
 
    uint tmp;
1933
 
    memset(fileinfo, 0, 64);
1934
 
    /* header */
1935
 
    fileinfo[0]=(uchar) 254;
1936
 
    fileinfo[1]= 1;
1937
 
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
1938
 
 
1939
 
    fileinfo[3]= (uchar) ha_legacy_type(
1940
 
          ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
1941
 
    fileinfo[4]=1;
1942
 
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
1943
 
    for (i= 0; i < keys; i++)
1944
 
    {
1945
 
      assert(test(key_info[i].flags & HA_USES_COMMENT) == 
1946
 
                 (key_info[i].comment.length > 0));
1947
 
      if (key_info[i].flags & HA_USES_COMMENT)
1948
 
        key_comment_total_bytes += 2 + key_info[i].comment.length;
1949
 
    }
1950
 
    /*
1951
 
      Keep in sync with pack_keys() in unireg.cc
1952
 
      For each key:
1953
 
      8 bytes for the key header
1954
 
      9 bytes for each key-part (MAX_REF_PARTS)
1955
 
      NAME_LEN bytes for the name
1956
 
      1 byte for the NAMES_SEP_CHAR (before the name)
1957
 
      For all keys:
1958
 
      6 bytes for the header
1959
 
      1 byte for the NAMES_SEP_CHAR (after the last name)
1960
 
      9 extra bytes (padding for safety? alignment?)
1961
 
      comments
1962
 
    */
1963
 
    key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
1964
 
                 key_comment_total_bytes);
1965
 
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
1966
 
                                  create_info->extra_size));
1967
 
    int4store(fileinfo+10,length);
1968
 
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
1969
 
    int2store(fileinfo+14,tmp_key_length);
1970
 
    int2store(fileinfo+16,reclength);
1971
 
    int4store(fileinfo+18,create_info->max_rows);
1972
 
    int4store(fileinfo+22,create_info->min_rows);
1973
 
    /* fileinfo[26] is set in mysql_create_frm() */
1974
 
    fileinfo[27]=2;                             // Use long pack-fields
1975
 
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
1976
 
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
1977
 
    int2store(fileinfo+30,create_info->table_options);
1978
 
    fileinfo[32]=0;                             // No filename anymore
1979
 
    fileinfo[33]=5;                             // Mark for 5.0 frm file
1980
 
    int4store(fileinfo+34,create_info->avg_row_length);
1981
 
    fileinfo[38]= (create_info->default_table_charset ?
1982
 
                   create_info->default_table_charset->number : 0);
1983
 
    fileinfo[39]= (uchar) ((uint) create_info->transactional |
1984
 
                           ((uint) create_info->page_checksum << 2));
1985
 
    fileinfo[40]= (uchar) create_info->row_type;
1986
 
    /* Next few bytes where for RAID support */
1987
 
    fileinfo[41]= 0;
1988
 
    fileinfo[42]= 0;
1989
 
    int4store(fileinfo+43,create_info->block_size);
1990
 
 
1991
 
    fileinfo[44]= 0;
1992
 
    fileinfo[45]= 0;
1993
 
    fileinfo[46]= 0;
1994
 
    int4store(fileinfo+47, key_length);
1995
 
    tmp= DRIZZLE_VERSION_ID;          // Store to avoid warning from int4store
1996
 
    int4store(fileinfo+51, tmp);
1997
 
    int4store(fileinfo+55, create_info->extra_size);
1998
 
    /*
1999
 
      59-60 is reserved for extra_rec_buf_length,
2000
 
      61 for default_part_db_type
2001
 
    */
2002
 
    int2store(fileinfo+62, create_info->key_block_size);
2003
 
    memset(fill, 0, IO_SIZE);
2004
 
    for (; length > IO_SIZE ; length-= IO_SIZE)
2005
 
    {
2006
 
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
2007
 
      {
2008
 
        VOID(my_close(file,MYF(0)));
2009
 
        VOID(my_delete(name,MYF(0)));
2010
 
        return(-1);
2011
 
      }
2012
 
    }
2013
 
  }
2014
 
  else
2015
 
  {
2016
 
    if (my_errno == ENOENT)
2017
 
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
2018
 
    else
2019
 
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
2020
 
  }
2021
 
  return (file);
2022
 
} /* create_frm */
2023
 
 
2024
 
 
2025
 
void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table)
2026
 
{
2027
 
  TABLE_SHARE *share= table->s;
2028
 
 
2029
 
  create_info->max_rows= share->max_rows;
2030
 
  create_info->min_rows= share->min_rows;
2031
 
  create_info->table_options= share->db_create_options;
2032
 
  create_info->avg_row_length= share->avg_row_length;
2033
 
  create_info->block_size= share->block_size;
2034
 
  create_info->row_type= share->row_type;
2035
 
  create_info->default_table_charset= share->table_charset;
 
1728
/*
 
1729
  Set up column usage bitmaps for a temporary table
 
1730
 
 
1731
  IMPLEMENTATION
 
1732
    For temporary tables, we need one bitmap with all columns set and
 
1733
    a tmp_set bitmap to be used by things like filesort.
 
1734
*/
 
1735
 
 
1736
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
1737
{
 
1738
  uint32_t field_count= s->fields;
 
1739
 
 
1740
  this->def_read_set.init((my_bitmap_map*) bitmaps, field_count);
 
1741
  this->tmp_set.init((my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
 
1742
 
 
1743
  /* write_set and all_set are copies of read_set */
 
1744
  def_write_set= def_read_set;
 
1745
  s->all_set= def_read_set;
 
1746
  this->s->all_set.setAll();
 
1747
  default_column_bitmaps();
 
1748
}
 
1749
 
 
1750
 
 
1751
 
 
1752
void Table::updateCreateInfo(HA_CREATE_INFO *create_info,
 
1753
                             message::Table *table_proto)
 
1754
{
 
1755
  message::Table::TableOptions *table_options= table_proto->mutable_options();
 
1756
  create_info->table_options= s->db_create_options;
 
1757
  table_options->set_block_size(s->block_size);
 
1758
  create_info->row_type= s->row_type;
 
1759
  create_info->default_table_charset= s->table_charset;
2036
1760
  create_info->table_charset= 0;
2037
 
  create_info->comment= share->comment;
2038
 
 
2039
 
  return;
2040
 
}
2041
 
 
2042
 
int
2043
 
rename_file_ext(const char * from,const char * to,const char * ext)
2044
 
{
2045
 
  char from_b[FN_REFLEN],to_b[FN_REFLEN];
2046
 
  VOID(strxmov(from_b,from,ext,NullS));
2047
 
  VOID(strxmov(to_b,to,ext,NullS));
2048
 
  return (my_rename(from_b,to_b,MYF(MY_WME)));
2049
 
}
2050
 
 
2051
 
 
2052
 
/*
2053
 
  Allocate string field in MEM_ROOT and return it as String
2054
 
 
2055
 
  SYNOPSIS
2056
 
    get_field()
2057
 
    mem         MEM_ROOT for allocating
2058
 
    field       Field for retrieving of string
2059
 
    res         result String
2060
 
 
2061
 
  RETURN VALUES
2062
 
    1   string is empty
2063
 
    0   all ok
2064
 
*/
2065
 
 
2066
 
bool get_field(MEM_ROOT *mem, Field *field, String *res)
2067
 
{
2068
 
  char buff[MAX_FIELD_WIDTH], *to;
2069
 
  String str(buff,sizeof(buff),&my_charset_bin);
2070
 
  uint length;
2071
 
 
2072
 
  field->val_str(&str);
2073
 
  if (!(length= str.length()))
2074
 
  {
2075
 
    res->length(0);
2076
 
    return 1;
2077
 
  }
2078
 
  if (!(to= strmake_root(mem, str.ptr(), length)))
2079
 
    length= 0;                                  // Safety fix
2080
 
  res->set(to, length, ((Field_str*)field)->charset());
2081
 
  return 0;
2082
 
}
2083
 
 
2084
 
 
2085
 
/*
2086
 
  Allocate string field in MEM_ROOT and return it as NULL-terminated string
2087
 
 
2088
 
  SYNOPSIS
2089
 
    get_field()
2090
 
    mem         MEM_ROOT for allocating
2091
 
    field       Field for retrieving of string
2092
 
 
2093
 
  RETURN VALUES
2094
 
    NullS  string is empty
2095
 
    #      pointer to NULL-terminated string value of field
2096
 
*/
2097
 
 
2098
 
char *get_field(MEM_ROOT *mem, Field *field)
2099
 
{
2100
 
  char buff[MAX_FIELD_WIDTH], *to;
2101
 
  String str(buff,sizeof(buff),&my_charset_bin);
2102
 
  uint length;
2103
 
 
2104
 
  field->val_str(&str);
2105
 
  length= str.length();
2106
 
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
2107
 
    return NullS;
2108
 
  memcpy(to,str.ptr(),(uint) length);
2109
 
  to[length]=0;
2110
 
  return to;
 
1761
  table_options->set_comment(s->getComment());
 
1762
}
 
1763
 
 
1764
int rename_file_ext(const char * from,const char * to,const char * ext)
 
1765
{
 
1766
  string from_s, to_s;
 
1767
 
 
1768
  from_s.append(from);
 
1769
  from_s.append(ext);
 
1770
  to_s.append(to);
 
1771
  to_s.append(ext);
 
1772
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
2111
1773
}
2112
1774
 
2113
1775
/*
2115
1777
    given a buffer with a key value, and a map of keyparts
2116
1778
    that are present in this value, returns the length of the value
2117
1779
*/
2118
 
uint calculate_key_len(TABLE *table, uint key,
2119
 
                       const uchar *buf __attribute__((unused)),
 
1780
uint32_t calculate_key_len(Table *table, uint32_t key,
 
1781
                       const unsigned char *,
2120
1782
                       key_part_map keypart_map)
2121
1783
{
2122
1784
  /* works only with key prefixes */
2125
1787
  KEY *key_info= table->s->key_info+key;
2126
1788
  KEY_PART_INFO *key_part= key_info->key_part;
2127
1789
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
2128
 
  uint length= 0;
 
1790
  uint32_t length= 0;
2129
1791
 
2130
1792
  while (key_part < end_key_part && keypart_map)
2131
1793
  {
2143
1805
    check_db_name()
2144
1806
    org_name            Name of database and length
2145
1807
 
2146
 
  NOTES
2147
 
    If lower_case_table_names is set then database is converted to lower case
2148
 
 
2149
1808
  RETURN
2150
1809
    0   ok
2151
1810
    1   error
2154
1813
bool check_db_name(LEX_STRING *org_name)
2155
1814
{
2156
1815
  char *name= org_name->str;
2157
 
  uint name_length= org_name->length;
 
1816
  uint32_t name_length= org_name->length;
2158
1817
 
2159
1818
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
2160
1819
    return 1;
2161
1820
 
2162
 
  if (lower_case_table_names && name != any_db)
 
1821
  if (name != any_db)
2163
1822
    my_casedn_str(files_charset_info, name);
2164
1823
 
2165
1824
  return check_identifier_name(org_name);
2171
1830
  ' ' at the end
2172
1831
  returns 1 on error
2173
1832
*/
2174
 
 
2175
 
 
2176
 
bool check_table_name(const char *name, uint length)
 
1833
bool check_table_name(const char *name, uint32_t length)
2177
1834
{
2178
1835
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
2179
1836
    return 1;
2191
1848
*/
2192
1849
bool check_column_name(const char *name)
2193
1850
{
2194
 
  uint name_length= 0;  // name length in symbols
 
1851
  uint32_t name_length= 0;  // name length in symbols
2195
1852
  bool last_char_is_space= true;
2196
 
  
 
1853
 
2197
1854
  while (*name)
2198
1855
  {
2199
 
#if defined(USE_MB) && defined(USE_MB_IDENT)
2200
1856
    last_char_is_space= my_isspace(system_charset_info, *name);
2201
1857
    if (use_mb(system_charset_info))
2202
1858
    {
2203
 
      int len=my_ismbchar(system_charset_info, name, 
 
1859
      int len=my_ismbchar(system_charset_info, name,
2204
1860
                          name+system_charset_info->mbmaxlen);
2205
1861
      if (len)
2206
1862
      {
2211
1867
        continue;
2212
1868
      }
2213
1869
    }
2214
 
#else
2215
 
    last_char_is_space= *name==' ';
2216
 
#endif
2217
1870
    /*
2218
1871
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
2219
1872
      It is defined as 0xFF, which is a not valid byte in utf8.
2225
1878
    name_length++;
2226
1879
  }
2227
1880
  /* Error if empty or too long column name */
2228
 
  return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
2229
 
}
2230
 
 
2231
 
 
2232
 
/**
2233
 
  Checks whether a table is intact. Should be done *just* after the table has
2234
 
  been opened.
2235
 
 
2236
 
  @param[in] table             The table to check
2237
 
  @param[in] table_f_count     Expected number of columns in the table
2238
 
  @param[in] table_def         Expected structure of the table (column name
2239
 
                               and type)
2240
 
 
2241
 
  @retval  false  OK
2242
 
  @retval  TRUE   There was an error. An error message is output
2243
 
                  to the error log.  We do not push an error
2244
 
                  message into the error stack because this
2245
 
                  function is currently only called at start up,
2246
 
                  and such errors never reach the user.
2247
 
*/
2248
 
 
2249
 
bool
2250
 
table_check_intact(TABLE *table, const uint table_f_count,
2251
 
                   const TABLE_FIELD_W_TYPE *table_def)
2252
 
{
2253
 
  uint i;
2254
 
  bool error= false;
2255
 
  bool fields_diff_count;
2256
 
 
2257
 
  fields_diff_count= (table->s->fields != table_f_count);
2258
 
  if (fields_diff_count)
2259
 
  {
2260
 
 
2261
 
    /* previous MySQL version */
2262
 
    if (DRIZZLE_VERSION_ID > table->s->mysql_version)
2263
 
    {
2264
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2265
 
                      table->alias, table_f_count, table->s->fields,
2266
 
                      table->s->mysql_version, DRIZZLE_VERSION_ID);
2267
 
      return(true);
2268
 
    }
2269
 
    else if (DRIZZLE_VERSION_ID == table->s->mysql_version)
2270
 
    {
2271
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), table->alias,
2272
 
                      table_f_count, table->s->fields);
2273
 
      return(true);
2274
 
    }
2275
 
    /*
2276
 
      Something has definitely changed, but we're running an older
2277
 
      version of MySQL with new system tables.
2278
 
      Let's check column definitions. If a column was added at
2279
 
      the end of the table, then we don't care much since such change
2280
 
      is backward compatible.
2281
 
    */
2282
 
  }
2283
 
  char buffer[STRING_BUFFER_USUAL_SIZE];
2284
 
  for (i=0 ; i < table_f_count; i++, table_def++)
2285
 
  {
2286
 
    String sql_type(buffer, sizeof(buffer), system_charset_info);
2287
 
    sql_type.length(0);
2288
 
    if (i < table->s->fields)
2289
 
    {
2290
 
      Field *field= table->field[i];
2291
 
 
2292
 
      if (strncmp(field->field_name, table_def->name.str,
2293
 
                  table_def->name.length))
2294
 
      {
2295
 
        /*
2296
 
          Name changes are not fatal, we use ordinal numbers to access columns.
2297
 
          Still this can be a sign of a tampered table, output an error
2298
 
          to the error log.
2299
 
        */
2300
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
2301
 
                        "expected column '%s' at position %d, found '%s'."),
2302
 
                        table->s->db.str, table->alias, table_def->name.str, i,
2303
 
                        field->field_name);
2304
 
      }
2305
 
      field->sql_type(sql_type);
2306
 
      /*
2307
 
        Generally, if column types don't match, then something is
2308
 
        wrong.
2309
 
 
2310
 
        However, we only compare column definitions up to the
2311
 
        length of the original definition, since we consider the
2312
 
        following definitions compatible:
2313
 
 
2314
 
        1. DATETIME and DATETIM
2315
 
        2. INT(11) and INT(11
2316
 
        3. SET('one', 'two') and SET('one', 'two', 'more')
2317
 
 
2318
 
        For SETs or ENUMs, if the same prefix is there it's OK to
2319
 
        add more elements - they will get higher ordinal numbers and
2320
 
        the new table definition is backward compatible with the
2321
 
        original one.
2322
 
       */
2323
 
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2324
 
                  table_def->type.length - 1))
2325
 
      {
2326
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
2327
 
                        "expected column '%s' at position %d to have type "
2328
 
                        "%s, found type %s."), table->s->db.str, table->alias,
2329
 
                        table_def->name.str, i, table_def->type.str,
2330
 
                        sql_type.c_ptr_safe());
2331
 
        error= true;
2332
 
      }
2333
 
      else if (table_def->cset.str && !field->has_charset())
2334
 
      {
2335
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
2336
 
                        "expected the type of column '%s' at position %d "
2337
 
                        "to have character set '%s' but the type has no "
2338
 
                        "character set."), table->s->db.str, table->alias,
2339
 
                        table_def->name.str, i, table_def->cset.str);
2340
 
        error= true;
2341
 
      }
2342
 
      else if (table_def->cset.str &&
2343
 
               strcmp(field->charset()->csname, table_def->cset.str))
2344
 
      {
2345
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
2346
 
                        "expected the type of column '%s' at position %d "
2347
 
                        "to have character set '%s' but found "
2348
 
                        "character set '%s'."), table->s->db.str, table->alias,
2349
 
                        table_def->name.str, i, table_def->cset.str,
2350
 
                        field->charset()->csname);
2351
 
        error= true;
2352
 
      }
2353
 
    }
2354
 
    else
2355
 
    {
2356
 
      sql_print_error(_("Incorrect definition of table %s.%s: "
2357
 
                      "expected column '%s' at position %d to have type %s "
2358
 
                      " but the column is not found."),
2359
 
                      table->s->db.str, table->alias,
2360
 
                      table_def->name.str, i, table_def->type.str);
2361
 
      error= true;
2362
 
    }
2363
 
  }
2364
 
  return(error);
2365
 
}
2366
 
 
2367
 
 
2368
 
/*
2369
 
  Create Item_field for each column in the table.
2370
 
 
2371
 
  SYNPOSIS
2372
 
    st_table::fill_item_list()
2373
 
      item_list          a pointer to an empty list used to store items
2374
 
 
2375
 
  DESCRIPTION
2376
 
    Create Item_field object for each column in the table and
2377
 
    initialize it with the corresponding Field. New items are
2378
 
    created in the current THD memory root.
2379
 
 
2380
 
  RETURN VALUE
2381
 
    0                    success
2382
 
    1                    out of memory
2383
 
*/
2384
 
 
2385
 
bool st_table::fill_item_list(List<Item> *item_list) const
2386
 
{
2387
 
  /*
2388
 
    All Item_field's created using a direct pointer to a field
2389
 
    are fixed in Item_field constructor.
2390
 
  */
2391
 
  for (Field **ptr= field; *ptr; ptr++)
2392
 
  {
2393
 
    Item_field *item= new Item_field(*ptr);
2394
 
    if (!item || item_list->push_back(item))
2395
 
      return true;
2396
 
  }
2397
 
  return false;
2398
 
}
2399
 
 
2400
 
/*
2401
 
  Reset an existing list of Item_field items to point to the
2402
 
  Fields of this table.
2403
 
 
2404
 
  SYNPOSIS
2405
 
    st_table::fill_item_list()
2406
 
      item_list          a non-empty list with Item_fields
2407
 
 
2408
 
  DESCRIPTION
2409
 
    This is a counterpart of fill_item_list used to redirect
2410
 
    Item_fields to the fields of a newly created table.
2411
 
    The caller must ensure that number of items in the item_list
2412
 
    is the same as the number of columns in the table.
2413
 
*/
2414
 
 
2415
 
void st_table::reset_item_list(List<Item> *item_list) const
2416
 
{
2417
 
  List_iterator_fast<Item> it(*item_list);
2418
 
  for (Field **ptr= field; *ptr; ptr++)
2419
 
  {
2420
 
    Item_field *item_field= (Item_field*) it++;
2421
 
    assert(item_field != 0);
2422
 
    item_field->reset_field(*ptr);
2423
 
  }
2424
 
}
2425
 
 
2426
 
 
2427
 
/*
2428
 
  Merge ON expressions for a view
2429
 
 
2430
 
  SYNOPSIS
2431
 
    merge_on_conds()
2432
 
    thd             thread handle
2433
 
    table           table for the VIEW
2434
 
    is_cascaded     TRUE <=> merge ON expressions from underlying views
2435
 
 
2436
 
  DESCRIPTION
2437
 
    This function returns the result of ANDing the ON expressions
2438
 
    of the given view and all underlying views. The ON expressions
2439
 
    of the underlying views are added only if is_cascaded is TRUE.
2440
 
 
2441
 
  RETURN
2442
 
    Pointer to the built expression if there is any.
2443
 
    Otherwise and in the case of a failure NULL is returned.
2444
 
*/
2445
 
 
2446
 
static Item *
2447
 
merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
2448
 
{
2449
 
 
2450
 
  Item *cond= NULL;
2451
 
  if (table->on_expr)
2452
 
    cond= table->on_expr->copy_andor_structure(thd);
2453
 
  if (!table->nested_join)
2454
 
    return(cond);
2455
 
  List_iterator<TABLE_LIST> li(table->nested_join->join_list);
2456
 
  while (TABLE_LIST *tbl= li++)
2457
 
  {
2458
 
    cond= and_conds(cond, merge_on_conds(thd, tbl, is_cascaded));
2459
 
  }
2460
 
  return(cond);
2461
 
}
2462
 
 
2463
 
 
2464
 
/*
2465
 
  Find underlying base tables (TABLE_LIST) which represent given
2466
 
  table_to_find (TABLE)
2467
 
 
2468
 
  SYNOPSIS
2469
 
    TABLE_LIST::find_underlying_table()
2470
 
    table_to_find table to find
2471
 
 
2472
 
  RETURN
2473
 
    0  table is not found
2474
 
    found table reference
2475
 
*/
2476
 
 
2477
 
TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
2478
 
{
2479
 
  /* is this real table and table which we are looking for? */
2480
 
  if (table == table_to_find && merge_underlying_list == 0)
2481
 
    return this;
2482
 
 
2483
 
  for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
2484
 
  {
2485
 
    TABLE_LIST *result;
2486
 
    if ((result= tbl->find_underlying_table(table_to_find)))
2487
 
      return result;
2488
 
  }
2489
 
  return 0;
2490
 
}
2491
 
 
2492
 
/*
2493
 
  cleunup items belonged to view fields translation table
2494
 
 
2495
 
  SYNOPSIS
2496
 
    TABLE_LIST::cleanup_items()
2497
 
*/
2498
 
 
2499
 
void TABLE_LIST::cleanup_items()
2500
 
{
2501
 
  if (!field_translation)
2502
 
    return;
2503
 
 
2504
 
  for (Field_translator *transl= field_translation;
2505
 
       transl < field_translation_end;
2506
 
       transl++)
2507
 
    transl->item->walk(&Item::cleanup_processor, 0, 0);
2508
 
}
2509
 
 
2510
 
 
2511
 
/*
2512
 
  Set insert_values buffer
2513
 
 
2514
 
  SYNOPSIS
2515
 
    set_insert_values()
2516
 
    mem_root   memory pool for allocating
2517
 
 
2518
 
  RETURN
2519
 
    false - OK
2520
 
    TRUE  - out of memory
2521
 
*/
2522
 
 
2523
 
bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
2524
 
{
2525
 
  if (table)
2526
 
  {
2527
 
    if (!table->insert_values &&
2528
 
        !(table->insert_values= (uchar *)alloc_root(mem_root,
2529
 
                                                   table->s->rec_buff_length)))
2530
 
      return true;
2531
 
  }
2532
 
 
2533
 
  return false;
2534
 
}
2535
 
 
2536
 
 
2537
 
/*
2538
 
  Test if this is a leaf with respect to name resolution.
2539
 
 
2540
 
  SYNOPSIS
2541
 
    TABLE_LIST::is_leaf_for_name_resolution()
2542
 
 
2543
 
  DESCRIPTION
2544
 
    A table reference is a leaf with respect to name resolution if
2545
 
    it is either a leaf node in a nested join tree (table, view,
2546
 
    schema table, subquery), or an inner node that represents a
2547
 
    NATURAL/USING join, or a nested join with materialized join
2548
 
    columns.
2549
 
 
2550
 
  RETURN
2551
 
    TRUE if a leaf, false otherwise.
2552
 
*/
2553
 
bool TABLE_LIST::is_leaf_for_name_resolution()
2554
 
{
2555
 
  return (is_natural_join || is_join_columns_complete || !nested_join);
2556
 
}
2557
 
 
2558
 
 
2559
 
/*
2560
 
  Retrieve the first (left-most) leaf in a nested join tree with
2561
 
  respect to name resolution.
2562
 
 
2563
 
  SYNOPSIS
2564
 
    TABLE_LIST::first_leaf_for_name_resolution()
2565
 
 
2566
 
  DESCRIPTION
2567
 
    Given that 'this' is a nested table reference, recursively walk
2568
 
    down the left-most children of 'this' until we reach a leaf
2569
 
    table reference with respect to name resolution.
2570
 
 
2571
 
  IMPLEMENTATION
2572
 
    The left-most child of a nested table reference is the last element
2573
 
    in the list of children because the children are inserted in
2574
 
    reverse order.
2575
 
 
2576
 
  RETURN
2577
 
    If 'this' is a nested table reference - the left-most child of
2578
 
      the tree rooted in 'this',
2579
 
    else return 'this'
2580
 
*/
2581
 
 
2582
 
TABLE_LIST *TABLE_LIST::first_leaf_for_name_resolution()
2583
 
{
2584
 
  TABLE_LIST *cur_table_ref= NULL;
2585
 
  NESTED_JOIN *cur_nested_join;
2586
 
 
2587
 
  if (is_leaf_for_name_resolution())
2588
 
    return this;
2589
 
  assert(nested_join);
2590
 
 
2591
 
  for (cur_nested_join= nested_join;
2592
 
       cur_nested_join;
2593
 
       cur_nested_join= cur_table_ref->nested_join)
2594
 
  {
2595
 
    List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
2596
 
    cur_table_ref= it++;
2597
 
    /*
2598
 
      If the current nested join is a RIGHT JOIN, the operands in
2599
 
      'join_list' are in reverse order, thus the first operand is
2600
 
      already at the front of the list. Otherwise the first operand
2601
 
      is in the end of the list of join operands.
2602
 
    */
2603
 
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2604
 
    {
2605
 
      TABLE_LIST *next;
2606
 
      while ((next= it++))
2607
 
        cur_table_ref= next;
2608
 
    }
2609
 
    if (cur_table_ref->is_leaf_for_name_resolution())
2610
 
      break;
2611
 
  }
2612
 
  return cur_table_ref;
2613
 
}
2614
 
 
2615
 
 
2616
 
/*
2617
 
  Retrieve the last (right-most) leaf in a nested join tree with
2618
 
  respect to name resolution.
2619
 
 
2620
 
  SYNOPSIS
2621
 
    TABLE_LIST::last_leaf_for_name_resolution()
2622
 
 
2623
 
  DESCRIPTION
2624
 
    Given that 'this' is a nested table reference, recursively walk
2625
 
    down the right-most children of 'this' until we reach a leaf
2626
 
    table reference with respect to name resolution.
2627
 
 
2628
 
  IMPLEMENTATION
2629
 
    The right-most child of a nested table reference is the first
2630
 
    element in the list of children because the children are inserted
2631
 
    in reverse order.
2632
 
 
2633
 
  RETURN
2634
 
    - If 'this' is a nested table reference - the right-most child of
2635
 
      the tree rooted in 'this',
2636
 
    - else - 'this'
2637
 
*/
2638
 
 
2639
 
TABLE_LIST *TABLE_LIST::last_leaf_for_name_resolution()
2640
 
{
2641
 
  TABLE_LIST *cur_table_ref= this;
2642
 
  NESTED_JOIN *cur_nested_join;
2643
 
 
2644
 
  if (is_leaf_for_name_resolution())
2645
 
    return this;
2646
 
  assert(nested_join);
2647
 
 
2648
 
  for (cur_nested_join= nested_join;
2649
 
       cur_nested_join;
2650
 
       cur_nested_join= cur_table_ref->nested_join)
2651
 
  {
2652
 
    cur_table_ref= cur_nested_join->join_list.head();
2653
 
    /*
2654
 
      If the current nested is a RIGHT JOIN, the operands in
2655
 
      'join_list' are in reverse order, thus the last operand is in the
2656
 
      end of the list.
2657
 
    */
2658
 
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2659
 
    {
2660
 
      List_iterator_fast<TABLE_LIST> it(cur_nested_join->join_list);
2661
 
      TABLE_LIST *next;
2662
 
      cur_table_ref= it++;
2663
 
      while ((next= it++))
2664
 
        cur_table_ref= next;
2665
 
    }
2666
 
    if (cur_table_ref->is_leaf_for_name_resolution())
2667
 
      break;
2668
 
  }
2669
 
  return cur_table_ref;
2670
 
}
2671
 
 
2672
 
 
2673
 
Natural_join_column::Natural_join_column(Field_translator *field_param,
2674
 
                                         TABLE_LIST *tab)
2675
 
{
2676
 
  assert(tab->field_translation);
2677
 
  view_field= field_param;
2678
 
  table_field= NULL;
2679
 
  table_ref= tab;
2680
 
  is_common= false;
2681
 
}
2682
 
 
2683
 
 
2684
 
Natural_join_column::Natural_join_column(Field *field_param,
2685
 
                                         TABLE_LIST *tab)
2686
 
{
2687
 
  assert(tab->table == field_param->table);
2688
 
  table_field= field_param;
2689
 
  view_field= NULL;
2690
 
  table_ref= tab;
2691
 
  is_common= false;
2692
 
}
2693
 
 
2694
 
 
2695
 
const char *Natural_join_column::name()
2696
 
{
2697
 
  if (view_field)
2698
 
  {
2699
 
    assert(table_field == NULL);
2700
 
    return view_field->name;
2701
 
  }
2702
 
 
2703
 
  return table_field->field_name;
2704
 
}
2705
 
 
2706
 
 
2707
 
Item *Natural_join_column::create_item(THD *thd)
2708
 
{
2709
 
  if (view_field)
2710
 
  {
2711
 
    assert(table_field == NULL);
2712
 
    return create_view_field(thd, table_ref, &view_field->item,
2713
 
                             view_field->name);
2714
 
  }
2715
 
  return new Item_field(thd, &thd->lex->current_select->context, table_field);
2716
 
}
2717
 
 
2718
 
 
2719
 
Field *Natural_join_column::field()
2720
 
{
2721
 
  if (view_field)
2722
 
  {
2723
 
    assert(table_field == NULL);
2724
 
    return NULL;
2725
 
  }
2726
 
  return table_field;
2727
 
}
2728
 
 
2729
 
 
2730
 
const char *Natural_join_column::table_name()
2731
 
{
2732
 
  assert(table_ref);
2733
 
  return table_ref->alias;
2734
 
}
2735
 
 
2736
 
 
2737
 
const char *Natural_join_column::db_name()
2738
 
{
2739
 
  /*
2740
 
    Test that TABLE_LIST::db is the same as st_table_share::db to
2741
 
    ensure consistency. An exception are I_S schema tables, which
2742
 
    are inconsistent in this respect.
2743
 
  */
2744
 
  assert(!strcmp(table_ref->db,
2745
 
                      table_ref->table->s->db.str) ||
2746
 
              (table_ref->schema_table &&
2747
 
               table_ref->table->s->db.str[0] == 0));
2748
 
  return table_ref->db;
2749
 
}
2750
 
 
2751
 
 
2752
 
void Field_iterator_view::set(TABLE_LIST *table)
2753
 
{
2754
 
  assert(table->field_translation);
2755
 
  view= table;
2756
 
  ptr= table->field_translation;
2757
 
  array_end= table->field_translation_end;
2758
 
}
2759
 
 
2760
 
 
2761
 
const char *Field_iterator_table::name()
2762
 
{
2763
 
  return (*ptr)->field_name;
2764
 
}
2765
 
 
2766
 
 
2767
 
Item *Field_iterator_table::create_item(THD *thd)
2768
 
{
2769
 
  SELECT_LEX *select= thd->lex->current_select;
2770
 
 
2771
 
  Item_field *item= new Item_field(thd, &select->context, *ptr);
2772
 
  if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
2773
 
      !thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS)
2774
 
  {
2775
 
    select->non_agg_fields.push_back(item);
2776
 
    item->marker= select->cur_pos_in_select_list;
2777
 
  }
2778
 
  return item;
2779
 
}
2780
 
 
2781
 
 
2782
 
const char *Field_iterator_view::name()
2783
 
{
2784
 
  return ptr->name;
2785
 
}
2786
 
 
2787
 
 
2788
 
Item *Field_iterator_view::create_item(THD *thd)
2789
 
{
2790
 
  return create_view_field(thd, view, &ptr->item, ptr->name);
2791
 
}
2792
 
 
2793
 
Item *create_view_field(THD *thd __attribute__((unused)),
2794
 
                        TABLE_LIST *view, Item **field_ref,
2795
 
                        const char *name __attribute__((unused)))
2796
 
{
2797
 
  if (view->schema_table_reformed)
2798
 
  {
2799
 
    Item *field= *field_ref;
2800
 
 
2801
 
    /*
2802
 
      Translation table items are always Item_fields and already fixed
2803
 
      ('mysql_schema_table' function). So we can return directly the
2804
 
      field. This case happens only for 'show & where' commands.
2805
 
    */
2806
 
    assert(field && field->fixed);
2807
 
    return(field);
2808
 
  }
2809
 
 
2810
 
  return(NULL);
2811
 
}
2812
 
 
2813
 
 
2814
 
void Field_iterator_natural_join::set(TABLE_LIST *table_ref)
2815
 
{
2816
 
  assert(table_ref->join_columns);
2817
 
  column_ref_it.init(*(table_ref->join_columns));
2818
 
  cur_column_ref= column_ref_it++;
2819
 
}
2820
 
 
2821
 
 
2822
 
void Field_iterator_natural_join::next()
2823
 
{
2824
 
  cur_column_ref= column_ref_it++;
2825
 
  assert(!cur_column_ref || ! cur_column_ref->table_field ||
2826
 
              cur_column_ref->table_ref->table ==
2827
 
              cur_column_ref->table_field->table);
2828
 
}
2829
 
 
2830
 
 
2831
 
void Field_iterator_table_ref::set_field_iterator()
2832
 
{
2833
 
  /*
2834
 
    If the table reference we are iterating over is a natural join, or it is
2835
 
    an operand of a natural join, and TABLE_LIST::join_columns contains all
2836
 
    the columns of the join operand, then we pick the columns from
2837
 
    TABLE_LIST::join_columns, instead of the  orginial container of the
2838
 
    columns of the join operator.
2839
 
  */
2840
 
  if (table_ref->is_join_columns_complete)
2841
 
  {
2842
 
    /* Necesary, but insufficient conditions. */
2843
 
    assert(table_ref->is_natural_join ||
2844
 
                table_ref->nested_join ||
2845
 
                ((table_ref->join_columns && /* This is a merge view. */ (table_ref->field_translation && table_ref->join_columns->elements == (ulong)(table_ref->field_translation_end - table_ref->field_translation))) ||
2846
 
                 /* This is stored table or a tmptable view. */
2847
 
                 (!table_ref->field_translation && table_ref->join_columns->elements == table_ref->table->s->fields)));
2848
 
    field_it= &natural_join_it;
2849
 
  }
2850
 
  /* This is a base table or stored view. */
2851
 
  else
2852
 
  {
2853
 
    assert(table_ref->table);
2854
 
    field_it= &table_field_it;
2855
 
  }
2856
 
  field_it->set(table_ref);
2857
 
  return;
2858
 
}
2859
 
 
2860
 
 
2861
 
void Field_iterator_table_ref::set(TABLE_LIST *table)
2862
 
{
2863
 
  assert(table);
2864
 
  first_leaf= table->first_leaf_for_name_resolution();
2865
 
  last_leaf=  table->last_leaf_for_name_resolution();
2866
 
  assert(first_leaf && last_leaf);
2867
 
  table_ref= first_leaf;
2868
 
  set_field_iterator();
2869
 
}
2870
 
 
2871
 
 
2872
 
void Field_iterator_table_ref::next()
2873
 
{
2874
 
  /* Move to the next field in the current table reference. */
2875
 
  field_it->next();
2876
 
  /*
2877
 
    If all fields of the current table reference are exhausted, move to
2878
 
    the next leaf table reference.
2879
 
  */
2880
 
  if (field_it->end_of_fields() && table_ref != last_leaf)
2881
 
  {
2882
 
    table_ref= table_ref->next_name_resolution_table;
2883
 
    assert(table_ref);
2884
 
    set_field_iterator();
2885
 
  }
2886
 
}
2887
 
 
2888
 
 
2889
 
const char *Field_iterator_table_ref::table_name()
2890
 
{
2891
 
  if (table_ref->is_natural_join)
2892
 
    return natural_join_it.column_ref()->table_name();
2893
 
 
2894
 
  assert(!strcmp(table_ref->table_name,
2895
 
                      table_ref->table->s->table_name.str));
2896
 
  return table_ref->table_name;
2897
 
}
2898
 
 
2899
 
 
2900
 
const char *Field_iterator_table_ref::db_name()
2901
 
{
2902
 
  if (table_ref->is_natural_join)
2903
 
    return natural_join_it.column_ref()->db_name();
2904
 
 
2905
 
  /*
2906
 
    Test that TABLE_LIST::db is the same as st_table_share::db to
2907
 
    ensure consistency. An exception are I_S schema tables, which
2908
 
    are inconsistent in this respect.
2909
 
  */
2910
 
  assert(!strcmp(table_ref->db, table_ref->table->s->db.str) ||
2911
 
              (table_ref->schema_table &&
2912
 
               table_ref->table->s->db.str[0] == 0));
2913
 
 
2914
 
  return table_ref->db;
2915
 
}
2916
 
 
2917
 
 
2918
 
/*
2919
 
  Create new or return existing column reference to a column of a
2920
 
  natural/using join.
2921
 
 
2922
 
  SYNOPSIS
2923
 
    Field_iterator_table_ref::get_or_create_column_ref()
2924
 
    parent_table_ref  the parent table reference over which the
2925
 
                      iterator is iterating
2926
 
 
2927
 
  DESCRIPTION
2928
 
    Create a new natural join column for the current field of the
2929
 
    iterator if no such column was created, or return an already
2930
 
    created natural join column. The former happens for base tables or
2931
 
    views, and the latter for natural/using joins. If a new field is
2932
 
    created, then the field is added to 'parent_table_ref' if it is
2933
 
    given, or to the original table referene of the field if
2934
 
    parent_table_ref == NULL.
2935
 
 
2936
 
  NOTES
2937
 
    This method is designed so that when a Field_iterator_table_ref
2938
 
    walks through the fields of a table reference, all its fields
2939
 
    are created and stored as follows:
2940
 
    - If the table reference being iterated is a stored table, view or
2941
 
      natural/using join, store all natural join columns in a list
2942
 
      attached to that table reference.
2943
 
    - If the table reference being iterated is a nested join that is
2944
 
      not natural/using join, then do not materialize its result
2945
 
      fields. This is OK because for such table references
2946
 
      Field_iterator_table_ref iterates over the fields of the nested
2947
 
      table references (recursively). In this way we avoid the storage
2948
 
      of unnecessay copies of result columns of nested joins.
2949
 
 
2950
 
  RETURN
2951
 
    #     Pointer to a column of a natural join (or its operand)
2952
 
    NULL  No memory to allocate the column
2953
 
*/
2954
 
 
2955
 
Natural_join_column *
2956
 
Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
2957
 
{
2958
 
  Natural_join_column *nj_col;
2959
 
  bool is_created= true;
2960
 
  uint field_count=0;
2961
 
  TABLE_LIST *add_table_ref= parent_table_ref ?
2962
 
                             parent_table_ref : table_ref;
2963
 
 
2964
 
  if (field_it == &table_field_it)
2965
 
  {
2966
 
    /* The field belongs to a stored table. */
2967
 
    Field *tmp_field= table_field_it.field();
2968
 
    nj_col= new Natural_join_column(tmp_field, table_ref);
2969
 
    field_count= table_ref->table->s->fields;
2970
 
  }
2971
 
  else if (field_it == &view_field_it)
2972
 
  {
2973
 
    /* The field belongs to a merge view or information schema table. */
2974
 
    Field_translator *translated_field= view_field_it.field_translator();
2975
 
    nj_col= new Natural_join_column(translated_field, table_ref);
2976
 
    field_count= table_ref->field_translation_end -
2977
 
                 table_ref->field_translation;
2978
 
  }
2979
 
  else
2980
 
  {
2981
 
    /*
2982
 
      The field belongs to a NATURAL join, therefore the column reference was
2983
 
      already created via one of the two constructor calls above. In this case
2984
 
      we just return the already created column reference.
2985
 
    */
2986
 
    assert(table_ref->is_join_columns_complete);
2987
 
    is_created= false;
2988
 
    nj_col= natural_join_it.column_ref();
2989
 
    assert(nj_col);
2990
 
  }
2991
 
  assert(!nj_col->table_field ||
2992
 
              nj_col->table_ref->table == nj_col->table_field->table);
2993
 
 
2994
 
  /*
2995
 
    If the natural join column was just created add it to the list of
2996
 
    natural join columns of either 'parent_table_ref' or to the table
2997
 
    reference that directly contains the original field.
2998
 
  */
2999
 
  if (is_created)
3000
 
  {
3001
 
    /* Make sure not all columns were materialized. */
3002
 
    assert(!add_table_ref->is_join_columns_complete);
3003
 
    if (!add_table_ref->join_columns)
3004
 
    {
3005
 
      /* Create a list of natural join columns on demand. */
3006
 
      if (!(add_table_ref->join_columns= new List<Natural_join_column>))
3007
 
        return NULL;
3008
 
      add_table_ref->is_join_columns_complete= false;
3009
 
    }
3010
 
    add_table_ref->join_columns->push_back(nj_col);
3011
 
    /*
3012
 
      If new fields are added to their original table reference, mark if
3013
 
      all fields were added. We do it here as the caller has no easy way
3014
 
      of knowing when to do it.
3015
 
      If the fields are being added to parent_table_ref, then the caller
3016
 
      must take care to mark when all fields are created/added.
3017
 
    */
3018
 
    if (!parent_table_ref &&
3019
 
        add_table_ref->join_columns->elements == field_count)
3020
 
      add_table_ref->is_join_columns_complete= true;
3021
 
  }
3022
 
 
3023
 
  return nj_col;
3024
 
}
3025
 
 
3026
 
 
3027
 
/*
3028
 
  Return an existing reference to a column of a natural/using join.
3029
 
 
3030
 
  SYNOPSIS
3031
 
    Field_iterator_table_ref::get_natural_column_ref()
3032
 
 
3033
 
  DESCRIPTION
3034
 
    The method should be called in contexts where it is expected that
3035
 
    all natural join columns are already created, and that the column
3036
 
    being retrieved is a Natural_join_column.
3037
 
 
3038
 
  RETURN
3039
 
    #     Pointer to a column of a natural join (or its operand)
3040
 
    NULL  No memory to allocate the column
3041
 
*/
3042
 
 
3043
 
Natural_join_column *
3044
 
Field_iterator_table_ref::get_natural_column_ref()
3045
 
{
3046
 
  Natural_join_column *nj_col;
3047
 
 
3048
 
  assert(field_it == &natural_join_it);
3049
 
  /*
3050
 
    The field belongs to a NATURAL join, therefore the column reference was
3051
 
    already created via one of the two constructor calls above. In this case
3052
 
    we just return the already created column reference.
3053
 
  */
3054
 
  nj_col= natural_join_it.column_ref();
3055
 
  assert(nj_col &&
3056
 
              (!nj_col->table_field ||
3057
 
               nj_col->table_ref->table == nj_col->table_field->table));
3058
 
  return nj_col;
3059
 
}
 
1881
  return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
 
1882
}
 
1883
 
3060
1884
 
3061
1885
/*****************************************************************************
3062
1886
  Functions to handle column usage bitmaps (read_set, write_set etc...)
3064
1888
 
3065
1889
/* Reset all columns bitmaps */
3066
1890
 
3067
 
void st_table::clear_column_bitmaps()
 
1891
void Table::clear_column_bitmaps()
3068
1892
{
3069
1893
  /*
3070
1894
    Reset column read/write usage. It's identical to:
3071
1895
    bitmap_clear_all(&table->def_read_set);
3072
1896
    bitmap_clear_all(&table->def_write_set);
3073
1897
  */
3074
 
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
 
1898
  def_read_set.clearAll();
 
1899
  def_write_set.clearAll();
3075
1900
  column_bitmaps_set(&def_read_set, &def_write_set);
3076
1901
}
3077
1902
 
3078
1903
 
3079
1904
/*
3080
 
  Tell handler we are going to call position() and rnd_pos() later.
3081
 
  
 
1905
  Tell Cursor we are going to call position() and rnd_pos() later.
 
1906
 
3082
1907
  NOTES:
3083
1908
  This is needed for handlers that uses the primary key to find the
3084
1909
  row. In this case we have to extend the read bitmap with the primary
3085
1910
  key fields.
3086
1911
*/
3087
1912
 
3088
 
void st_table::prepare_for_position()
 
1913
void Table::prepare_for_position()
3089
1914
{
3090
1915
 
3091
1916
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
3092
1917
      s->primary_key < MAX_KEY)
3093
1918
  {
3094
 
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3095
 
    /* signal change */
3096
 
    file->column_bitmaps_signal();
 
1919
    mark_columns_used_by_index_no_reset(s->primary_key);
3097
1920
  }
3098
1921
  return;
3099
1922
}
3105
1928
  NOTE:
3106
1929
    This changes the bitmap to use the tmp bitmap
3107
1930
    After this, you can't access any other columns in the table until
3108
 
    bitmaps are reset, for example with st_table::clear_column_bitmaps()
3109
 
    or st_table::restore_column_maps_after_mark_index()
 
1931
    bitmaps are reset, for example with Table::clear_column_bitmaps()
 
1932
    or Table::restore_column_maps_after_mark_index()
3110
1933
*/
3111
1934
 
3112
 
void st_table::mark_columns_used_by_index(uint index)
 
1935
void Table::mark_columns_used_by_index(uint32_t index)
3113
1936
{
3114
 
  MY_BITMAP *bitmap= &tmp_set;
 
1937
  MyBitmap *bitmap= &tmp_set;
3115
1938
 
3116
1939
  (void) file->extra(HA_EXTRA_KEYREAD);
3117
 
  bitmap_clear_all(bitmap);
 
1940
  bitmap->clearAll();
3118
1941
  mark_columns_used_by_index_no_reset(index, bitmap);
3119
1942
  column_bitmaps_set(bitmap, bitmap);
3120
1943
  return;
3132
1955
    when calling mark_columns_used_by_index
3133
1956
*/
3134
1957
 
3135
 
void st_table::restore_column_maps_after_mark_index()
 
1958
void Table::restore_column_maps_after_mark_index()
3136
1959
{
3137
1960
 
3138
1961
  key_read= 0;
3139
1962
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
3140
1963
  default_column_bitmaps();
3141
 
  file->column_bitmaps_signal();
3142
1964
  return;
3143
1965
}
3144
1966
 
3147
1969
  mark columns used by key, but don't reset other fields
3148
1970
*/
3149
1971
 
3150
 
void st_table::mark_columns_used_by_index_no_reset(uint index,
3151
 
                                                   MY_BITMAP *bitmap)
 
1972
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
 
1973
{
 
1974
    mark_columns_used_by_index_no_reset(index, read_set);
 
1975
}
 
1976
 
 
1977
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
 
1978
                                                MyBitmap *bitmap)
3152
1979
{
3153
1980
  KEY_PART_INFO *key_part= key_info[index].key_part;
3154
1981
  KEY_PART_INFO *key_part_end= (key_part +
3155
1982
                                key_info[index].key_parts);
3156
1983
  for (;key_part != key_part_end; key_part++)
3157
 
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
 
1984
    bitmap->setBit(key_part->fieldnr-1);
3158
1985
}
3159
1986
 
3160
1987
 
3166
1993
    always set and sometimes read.
3167
1994
*/
3168
1995
 
3169
 
void st_table::mark_auto_increment_column()
 
1996
void Table::mark_auto_increment_column()
3170
1997
{
3171
1998
  assert(found_next_number_field);
3172
1999
  /*
3173
2000
    We must set bit in read set as update_auto_increment() is using the
3174
2001
    store() to check overflow of auto_increment values
3175
2002
  */
3176
 
  bitmap_set_bit(read_set, found_next_number_field->field_index);
3177
 
  bitmap_set_bit(write_set, found_next_number_field->field_index);
 
2003
  setReadSet(found_next_number_field->field_index);
 
2004
  setWriteSet(found_next_number_field->field_index);
3178
2005
  if (s->next_number_keypart)
3179
 
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
3180
 
  file->column_bitmaps_signal();
 
2006
    mark_columns_used_by_index_no_reset(s->next_number_index);
3181
2007
}
3182
2008
 
3183
2009
 
3199
2025
    retrieve the row again.
3200
2026
*/
3201
2027
 
3202
 
void st_table::mark_columns_needed_for_delete()
 
2028
void Table::mark_columns_needed_for_delete()
3203
2029
{
 
2030
  /*
 
2031
    If the Cursor has no cursor capabilites, or we have row-based
 
2032
    replication active for the current statement, we have to read
 
2033
    either the primary key, the hidden primary key or all columns to
 
2034
    be able to do an delete
 
2035
 
 
2036
  */
 
2037
  if (s->primary_key == MAX_KEY)
 
2038
  {
 
2039
    /* fallback to use all columns in the table to identify row */
 
2040
    use_all_columns();
 
2041
    return;
 
2042
  }
 
2043
  else
 
2044
    mark_columns_used_by_index_no_reset(s->primary_key);
 
2045
 
 
2046
  /* If we the engine wants all predicates we mark all keys */
3204
2047
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
3205
2048
  {
3206
2049
    Field **reg_field;
3207
2050
    for (reg_field= field ; *reg_field ; reg_field++)
3208
2051
    {
3209
2052
      if ((*reg_field)->flags & PART_KEY_FLAG)
3210
 
        bitmap_set_bit(read_set, (*reg_field)->field_index);
3211
 
    }
3212
 
    file->column_bitmaps_signal();
3213
 
  }
3214
 
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
3215
 
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
3216
 
  {
3217
 
    /*
3218
 
      If the handler has no cursor capabilites, or we have row-based
3219
 
      replication active for the current statement, we have to read
3220
 
      either the primary key, the hidden primary key or all columns to
3221
 
      be able to do an delete
3222
 
    */
3223
 
    if (s->primary_key == MAX_KEY)
3224
 
      file->use_hidden_primary_key();
3225
 
    else
3226
 
    {
3227
 
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3228
 
      file->column_bitmaps_signal();
 
2053
        setReadSet((*reg_field)->field_index);
3229
2054
    }
3230
2055
  }
3231
2056
}
3249
2074
    retrieve the row again.
3250
2075
*/
3251
2076
 
3252
 
void st_table::mark_columns_needed_for_update()
 
2077
void Table::mark_columns_needed_for_update()
3253
2078
{
 
2079
  /*
 
2080
    If the Cursor has no cursor capabilites, or we have row-based
 
2081
    logging active for the current statement, we have to read either
 
2082
    the primary key, the hidden primary key or all columns to be
 
2083
    able to do an update
 
2084
  */
 
2085
  if (s->primary_key == MAX_KEY)
 
2086
  {
 
2087
    /* fallback to use all columns in the table to identify row */
 
2088
    use_all_columns();
 
2089
    return;
 
2090
  }
 
2091
  else
 
2092
    mark_columns_used_by_index_no_reset(s->primary_key);
 
2093
 
3254
2094
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
3255
2095
  {
3256
2096
    /* Mark all used key columns for read */
3258
2098
    for (reg_field= field ; *reg_field ; reg_field++)
3259
2099
    {
3260
2100
      /* Merge keys is all keys that had a column refered to in the query */
3261
 
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
3262
 
        bitmap_set_bit(read_set, (*reg_field)->field_index);
3263
 
    }
3264
 
    file->column_bitmaps_signal();
3265
 
  }
3266
 
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) ||
3267
 
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
3268
 
  {
3269
 
    /*
3270
 
      If the handler has no cursor capabilites, or we have row-based
3271
 
      logging active for the current statement, we have to read either
3272
 
      the primary key, the hidden primary key or all columns to be
3273
 
      able to do an update
3274
 
    */
3275
 
    if (s->primary_key == MAX_KEY)
3276
 
      file->use_hidden_primary_key();
3277
 
    else
3278
 
    {
3279
 
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3280
 
      file->column_bitmaps_signal();
3281
 
    }
3282
 
  }
3283
 
  return;
 
2101
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
 
2102
        setReadSet((*reg_field)->field_index);
 
2103
    }
 
2104
  }
 
2105
 
3284
2106
}
3285
2107
 
3286
2108
 
3287
2109
/*
3288
 
  Mark columns the handler needs for doing an insert
 
2110
  Mark columns the Cursor needs for doing an insert
3289
2111
 
3290
2112
  For now, this is used to mark fields used by the trigger
3291
2113
  as changed.
3292
2114
*/
3293
2115
 
3294
 
void st_table::mark_columns_needed_for_insert()
 
2116
void Table::mark_columns_needed_for_insert()
3295
2117
{
3296
2118
  if (found_next_number_field)
3297
2119
    mark_auto_increment_column();
3298
2120
}
3299
2121
 
3300
 
/*
3301
 
  Cleanup this table for re-execution.
3302
 
 
3303
 
  SYNOPSIS
3304
 
    TABLE_LIST::reinit_before_use()
3305
 
*/
3306
 
 
3307
 
void TABLE_LIST::reinit_before_use(THD *thd)
3308
 
{
3309
 
  /*
3310
 
    Reset old pointers to TABLEs: they are not valid since the tables
3311
 
    were closed in the end of previous prepare or execute call.
3312
 
  */
3313
 
  table= 0;
3314
 
  /* Reset is_schema_table_processed value(needed for I_S tables */
3315
 
  schema_table_state= NOT_PROCESSED;
3316
 
 
3317
 
  TABLE_LIST *embedded; /* The table at the current level of nesting. */
3318
 
  TABLE_LIST *parent_embedding= this; /* The parent nested table reference. */
3319
 
  do
3320
 
  {
3321
 
    embedded= parent_embedding;
3322
 
    if (embedded->prep_on_expr)
3323
 
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
3324
 
    parent_embedding= embedded->embedding;
3325
 
  }
3326
 
  while (parent_embedding &&
3327
 
         parent_embedding->nested_join->join_list.head() == embedded);
3328
 
}
3329
 
 
3330
 
/*
3331
 
  Return subselect that contains the FROM list this table is taken from
3332
 
 
3333
 
  SYNOPSIS
3334
 
    TABLE_LIST::containing_subselect()
3335
 
 
3336
 
  RETURN
3337
 
    Subselect item for the subquery that contains the FROM list
3338
 
    this table is taken from if there is any
3339
 
    0 - otherwise
3340
 
 
3341
 
*/
3342
 
 
3343
 
Item_subselect *TABLE_LIST::containing_subselect()
3344
 
{    
3345
 
  return (select_lex ? select_lex->master_unit()->item : 0);
3346
 
}
3347
 
 
3348
 
/*
3349
 
  Compiles the tagged hints list and fills up the bitmasks.
3350
 
 
3351
 
  SYNOPSIS
3352
 
    process_index_hints()
3353
 
      table         the TABLE to operate on.
3354
 
 
3355
 
  DESCRIPTION
3356
 
    The parser collects the index hints for each table in a "tagged list" 
3357
 
    (TABLE_LIST::index_hints). Using the information in this tagged list
3358
 
    this function sets the members st_table::keys_in_use_for_query, 
3359
 
    st_table::keys_in_use_for_group_by, st_table::keys_in_use_for_order_by,
3360
 
    st_table::force_index and st_table::covering_keys.
3361
 
 
3362
 
    Current implementation of the runtime does not allow mixing FORCE INDEX
3363
 
    and USE INDEX, so this is checked here. Then the FORCE INDEX list 
3364
 
    (if non-empty) is appended to the USE INDEX list and a flag is set.
3365
 
 
3366
 
    Multiple hints of the same kind are processed so that each clause 
3367
 
    is applied to what is computed in the previous clause.
3368
 
    For example:
3369
 
        USE INDEX (i1) USE INDEX (i2)
3370
 
    is equivalent to
3371
 
        USE INDEX (i1,i2)
3372
 
    and means "consider only i1 and i2".
3373
 
        
3374
 
    Similarly
3375
 
        USE INDEX () USE INDEX (i1)
3376
 
    is equivalent to
3377
 
        USE INDEX (i1)
3378
 
    and means "consider only the index i1"
3379
 
 
3380
 
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
3381
 
    not an error.
3382
 
        
3383
 
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
3384
 
    order:
3385
 
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
3386
 
      2. All IGNORE INDEX
3387
 
 
3388
 
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
3389
 
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
3390
 
 
3391
 
    As an optimization if there is a covering index, and we have 
3392
 
    IGNORE INDEX FOR GROUP/ORDER, and this index is used for the JOIN part, 
3393
 
    then we have to ignore the IGNORE INDEX FROM GROUP/ORDER.
3394
 
 
3395
 
  RETURN VALUE
3396
 
    false                no errors found
3397
 
    TRUE                 found and reported an error.
3398
 
*/
3399
 
bool TABLE_LIST::process_index_hints(TABLE *tbl)
3400
 
{
3401
 
  /* initialize the result variables */
3402
 
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
3403
 
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
3404
 
 
3405
 
  /* index hint list processing */
3406
 
  if (index_hints)
3407
 
  {
3408
 
    key_map index_join[INDEX_HINT_FORCE + 1];
3409
 
    key_map index_order[INDEX_HINT_FORCE + 1];
3410
 
    key_map index_group[INDEX_HINT_FORCE + 1];
3411
 
    Index_hint *hint;
3412
 
    int type;
3413
 
    bool have_empty_use_join= false, have_empty_use_order= false, 
3414
 
         have_empty_use_group= false;
3415
 
    List_iterator <Index_hint> iter(*index_hints);
3416
 
 
3417
 
    /* initialize temporary variables used to collect hints of each kind */
3418
 
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
3419
 
    {
3420
 
      index_join[type].clear_all();
3421
 
      index_order[type].clear_all();
3422
 
      index_group[type].clear_all();
3423
 
    }
3424
 
 
3425
 
    /* iterate over the hints list */
3426
 
    while ((hint= iter++))
3427
 
    {
3428
 
      uint pos;
3429
 
 
3430
 
      /* process empty USE INDEX () */
3431
 
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
3432
 
      {
3433
 
        if (hint->clause & INDEX_HINT_MASK_JOIN)
3434
 
        {
3435
 
          index_join[hint->type].clear_all();
3436
 
          have_empty_use_join= true;
3437
 
        }
3438
 
        if (hint->clause & INDEX_HINT_MASK_ORDER)
3439
 
        {
3440
 
          index_order[hint->type].clear_all();
3441
 
          have_empty_use_order= true;
3442
 
        }
3443
 
        if (hint->clause & INDEX_HINT_MASK_GROUP)
3444
 
        {
3445
 
          index_group[hint->type].clear_all();
3446
 
          have_empty_use_group= true;
3447
 
        }
3448
 
        continue;
3449
 
      }
3450
 
 
3451
 
      /* 
3452
 
        Check if an index with the given name exists and get his offset in 
3453
 
        the keys bitmask for the table 
3454
 
      */
3455
 
      if (tbl->s->keynames.type_names == 0 ||
3456
 
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
3457
 
                          hint->key_name.length, 1)) <= 0)
3458
 
      {
3459
 
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
3460
 
        return 1;
3461
 
      }
3462
 
 
3463
 
      pos--;
3464
 
 
3465
 
      /* add to the appropriate clause mask */
3466
 
      if (hint->clause & INDEX_HINT_MASK_JOIN)
3467
 
        index_join[hint->type].set_bit (pos);
3468
 
      if (hint->clause & INDEX_HINT_MASK_ORDER)
3469
 
        index_order[hint->type].set_bit (pos);
3470
 
      if (hint->clause & INDEX_HINT_MASK_GROUP)
3471
 
        index_group[hint->type].set_bit (pos);
3472
 
    }
3473
 
 
3474
 
    /* cannot mix USE INDEX and FORCE INDEX */
3475
 
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3476
 
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3477
 
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
3478
 
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
3479
 
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
3480
 
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
3481
 
    {
3482
 
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
3483
 
               index_hint_type_name[INDEX_HINT_FORCE]);
3484
 
      return 1;
3485
 
    }
3486
 
 
3487
 
    /* process FORCE INDEX as USE INDEX with a flag */
3488
 
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3489
 
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3490
 
        !index_group[INDEX_HINT_FORCE].is_clear_all())
3491
 
    {
3492
 
      tbl->force_index= true;
3493
 
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
3494
 
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
3495
 
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
3496
 
    }
3497
 
 
3498
 
    /* apply USE INDEX */
3499
 
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
3500
 
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
3501
 
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
3502
 
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
3503
 
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
3504
 
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
3505
 
 
3506
 
    /* apply IGNORE INDEX */
3507
 
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
3508
 
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
3509
 
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
3510
 
  }
3511
 
 
3512
 
  /* make sure covering_keys don't include indexes disabled with a hint */
3513
 
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
3514
 
  return 0;
3515
 
}
3516
 
 
3517
 
 
3518
 
size_t max_row_length(TABLE *table, const uchar *data)
3519
 
{
3520
 
  TABLE_SHARE *table_s= table->s;
3521
 
  size_t length= table_s->reclength + 2 * table_s->fields;
3522
 
  uint *const beg= table_s->blob_field;
3523
 
  uint *const end= beg + table_s->blob_fields;
3524
 
 
3525
 
  for (uint *ptr= beg ; ptr != end ; ++ptr)
3526
 
  {
3527
 
    Field_blob* const blob= (Field_blob*) table->field[*ptr];
3528
 
    length+= blob->get_length((const uchar*)
3529
 
                              (data + blob->offset(table->record[0]))) +
 
2122
 
 
2123
 
 
2124
size_t Table::max_row_length(const unsigned char *data)
 
2125
{
 
2126
  size_t length= getRecordLength() + 2 * sizeFields();
 
2127
  uint32_t *const beg= getBlobField();
 
2128
  uint32_t *const end= beg + sizeBlobFields();
 
2129
 
 
2130
  for (uint32_t *ptr= beg ; ptr != end ; ++ptr)
 
2131
  {
 
2132
    Field_blob* const blob= (Field_blob*) field[*ptr];
 
2133
    length+= blob->get_length((const unsigned char*)
 
2134
                              (data + blob->offset(record[0]))) +
3530
2135
      HA_KEY_BLOB_LENGTH;
3531
2136
  }
3532
2137
  return length;
3533
2138
}
3534
2139
 
 
2140
/****************************************************************************
 
2141
 Functions for creating temporary tables.
 
2142
****************************************************************************/
 
2143
 
 
2144
 
 
2145
/* Prototypes */
 
2146
void free_tmp_table(Session *session, Table *entry);
 
2147
 
 
2148
/**
 
2149
  Create field for temporary table from given field.
 
2150
 
 
2151
  @param session               Thread Cursor
 
2152
  @param org_field    field from which new field will be created
 
2153
  @param name         New field name
 
2154
  @param table         Temporary table
 
2155
  @param item          !=NULL if item->result_field should point to new field.
 
2156
                      This is relevant for how fill_record() is going to work:
 
2157
                      If item != NULL then fill_record() will update
 
2158
                      the record in the original table.
 
2159
                      If item == NULL then fill_record() will update
 
2160
                      the temporary table
 
2161
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
 
2162
                               field instead of blob.
 
2163
 
 
2164
  @retval
 
2165
    NULL                on error
 
2166
  @retval
 
2167
    new_created field
 
2168
*/
 
2169
 
 
2170
Field *create_tmp_field_from_field(Session *session, Field *org_field,
 
2171
                                   const char *name, Table *table,
 
2172
                                   Item_field *item, uint32_t convert_blob_length)
 
2173
{
 
2174
  Field *new_field;
 
2175
 
 
2176
  /*
 
2177
    Make sure that the blob fits into a Field_varstring which has
 
2178
    2-byte lenght.
 
2179
  */
 
2180
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
 
2181
      (org_field->flags & BLOB_FLAG))
 
2182
    new_field= new Field_varstring(convert_blob_length,
 
2183
                                   org_field->maybe_null(),
 
2184
                                   org_field->field_name, table->s,
 
2185
                                   org_field->charset());
 
2186
  else
 
2187
    new_field= org_field->new_field(session->mem_root, table,
 
2188
                                    table == org_field->table);
 
2189
  if (new_field)
 
2190
  {
 
2191
    new_field->init(table);
 
2192
    new_field->orig_table= org_field->orig_table;
 
2193
    if (item)
 
2194
      item->result_field= new_field;
 
2195
    else
 
2196
      new_field->field_name= name;
 
2197
    new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
 
2198
    if (org_field->maybe_null() || (item && item->maybe_null))
 
2199
      new_field->flags&= ~NOT_NULL_FLAG;        // Because of outer join
 
2200
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
 
2201
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
 
2202
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
 
2203
      ((Field_double *) new_field)->not_fixed= true;
 
2204
  }
 
2205
  return new_field;
 
2206
}
 
2207
 
 
2208
 
 
2209
/**
 
2210
  Create field for information schema table.
 
2211
 
 
2212
  @param session                Thread Cursor
 
2213
  @param table          Temporary table
 
2214
  @param item           Item to create a field for
 
2215
 
 
2216
  @retval
 
2217
    0                   on error
 
2218
  @retval
 
2219
    new_created field
 
2220
*/
 
2221
 
 
2222
static Field *create_tmp_field_for_schema(Item *item, Table *table)
 
2223
{
 
2224
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
2225
  {
 
2226
    Field *field;
 
2227
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
2228
      field= new Field_blob(item->max_length, item->maybe_null,
 
2229
                            item->name, item->collation.collation);
 
2230
    else
 
2231
      field= new Field_varstring(item->max_length, item->maybe_null,
 
2232
                                 item->name,
 
2233
                                 table->s, item->collation.collation);
 
2234
    if (field)
 
2235
      field->init(table);
 
2236
    return field;
 
2237
  }
 
2238
  return item->tmp_table_field_from_field_type(table, 0);
 
2239
}
 
2240
 
 
2241
 
 
2242
/**
 
2243
  Create a temp table according to a field list.
 
2244
 
 
2245
  Given field pointers are changed to point at tmp_table for
 
2246
  send_fields. The table object is self contained: it's
 
2247
  allocated in its own memory root, as well as Field objects
 
2248
  created for table columns.
 
2249
  This function will replace Item_sum items in 'fields' list with
 
2250
  corresponding Item_field items, pointing at the fields in the
 
2251
  temporary table, unless this was prohibited by true
 
2252
  value of argument save_sum_fields. The Item_field objects
 
2253
  are created in Session memory root.
 
2254
 
 
2255
  @param session                  thread handle
 
2256
  @param param                a description used as input to create the table
 
2257
  @param fields               list of items that will be used to define
 
2258
                              column types of the table (also see NOTES)
 
2259
  @param group                TODO document
 
2260
  @param distinct             should table rows be distinct
 
2261
  @param save_sum_fields      see NOTES
 
2262
  @param select_options
 
2263
  @param rows_limit
 
2264
  @param table_alias          possible name of the temporary table that can
 
2265
                              be used for name resolving; can be "".
 
2266
*/
 
2267
 
 
2268
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
 
2269
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
 
2270
#define RATIO_TO_PACK_ROWS             2
 
2271
 
 
2272
Table *
 
2273
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
 
2274
                 order_st *group, bool distinct, bool save_sum_fields,
 
2275
                 uint64_t select_options, ha_rows rows_limit,
 
2276
                 const char *table_alias)
 
2277
{
 
2278
  MEM_ROOT *mem_root_save, own_root;
 
2279
  Table *table;
 
2280
  TableShare *share;
 
2281
  uint  i,field_count,null_count,null_pack_length;
 
2282
  uint32_t  copy_func_count= param->func_count;
 
2283
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
 
2284
  uint32_t  blob_count,group_null_items, string_count;
 
2285
  uint32_t fieldnr= 0;
 
2286
  ulong reclength, string_total_length;
 
2287
  bool  using_unique_constraint= 0;
 
2288
  bool  use_packed_rows= 0;
 
2289
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
 
2290
  char  *tmpname,path[FN_REFLEN];
 
2291
  unsigned char *pos, *group_buff, *bitmaps;
 
2292
  unsigned char *null_flags;
 
2293
  Field **reg_field, **from_field, **default_field;
 
2294
  uint32_t *blob_field;
 
2295
  CopyField *copy= 0;
 
2296
  KEY *keyinfo;
 
2297
  KEY_PART_INFO *key_part_info;
 
2298
  Item **copy_func;
 
2299
  MI_COLUMNDEF *recinfo;
 
2300
  uint32_t total_uneven_bit_length= 0;
 
2301
  bool force_copy_fields= param->force_copy_fields;
 
2302
  uint64_t max_rows= 0;
 
2303
 
 
2304
  status_var_increment(session->status_var.created_tmp_tables);
 
2305
 
 
2306
  /* if we run out of slots or we are not using tempool */
 
2307
  sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
2308
          session->thread_id, session->tmp_table++);
 
2309
 
 
2310
  /*
 
2311
    No need to change table name to lower case as we are only creating
 
2312
    MyISAM or HEAP tables here
 
2313
  */
 
2314
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
2315
 
 
2316
 
 
2317
  if (group)
 
2318
  {
 
2319
    if (!param->quick_group)
 
2320
      group= 0;                                 // Can't use group key
 
2321
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
 
2322
    {
 
2323
      /*
 
2324
        marker == 4 means two things:
 
2325
        - store NULLs in the key, and
 
2326
        - convert BIT fields to 64-bit long, needed because MEMORY tables
 
2327
          can't index BIT fields.
 
2328
      */
 
2329
      (*tmp->item)->marker= 4;
 
2330
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
 
2331
        using_unique_constraint=1;
 
2332
    }
 
2333
    if (param->group_length >= MAX_BLOB_WIDTH)
 
2334
      using_unique_constraint=1;
 
2335
    if (group)
 
2336
      distinct= 0;                              // Can't use distinct
 
2337
  }
 
2338
 
 
2339
  field_count=param->field_count+param->func_count+param->sum_func_count;
 
2340
  hidden_field_count=param->hidden_field_count;
 
2341
 
 
2342
  /*
 
2343
    When loose index scan is employed as access method, it already
 
2344
    computes all groups and the result of all aggregate functions. We
 
2345
    make space for the items of the aggregate function in the list of
 
2346
    functions Tmp_Table_Param::items_to_copy, so that the values of
 
2347
    these items are stored in the temporary table.
 
2348
  */
 
2349
  if (param->precomputed_group_by)
 
2350
    copy_func_count+= param->sum_func_count;
 
2351
 
 
2352
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
2353
 
 
2354
  if (!multi_alloc_root(&own_root,
 
2355
                        &table, sizeof(*table),
 
2356
                        &share, sizeof(*share),
 
2357
                        &reg_field, sizeof(Field*) * (field_count+1),
 
2358
                        &default_field, sizeof(Field*) * (field_count),
 
2359
                        &blob_field, sizeof(uint32_t)*(field_count+1),
 
2360
                        &from_field, sizeof(Field*)*field_count,
 
2361
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
 
2362
                        &param->keyinfo, sizeof(*param->keyinfo),
 
2363
                        &key_part_info,
 
2364
                        sizeof(*key_part_info)*(param->group_parts+1),
 
2365
                        &param->start_recinfo,
 
2366
                        sizeof(*param->recinfo)*(field_count*2+4),
 
2367
                        &tmpname, (uint32_t) strlen(path)+1,
 
2368
                        &group_buff, (group && ! using_unique_constraint ?
 
2369
                                      param->group_length : 0),
 
2370
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
2371
                        NULL))
 
2372
  {
 
2373
    return NULL;
 
2374
  }
 
2375
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
 
2376
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
 
2377
  {
 
2378
    free_root(&own_root, MYF(0));
 
2379
    return NULL;
 
2380
  }
 
2381
  param->items_to_copy= copy_func;
 
2382
  strcpy(tmpname,path);
 
2383
  /* make table according to fields */
 
2384
 
 
2385
  memset(table, 0, sizeof(*table));
 
2386
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
 
2387
  memset(default_field, 0, sizeof(Field*) * (field_count));
 
2388
  memset(from_field, 0, sizeof(Field*)*field_count);
 
2389
 
 
2390
  table->mem_root= own_root;
 
2391
  mem_root_save= session->mem_root;
 
2392
  session->mem_root= &table->mem_root;
 
2393
 
 
2394
  table->field=reg_field;
 
2395
  table->alias= table_alias;
 
2396
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
 
2397
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
 
2398
  table->map=1;
 
2399
  table->copy_blobs= 1;
 
2400
  table->in_use= session;
 
2401
  table->quick_keys.reset();
 
2402
  table->covering_keys.reset();
 
2403
  table->keys_in_use_for_query.reset();
 
2404
 
 
2405
  table->setShare(share);
 
2406
  share->init(tmpname, tmpname);
 
2407
  share->blob_field= blob_field;
 
2408
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
2409
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
2410
  share->table_charset= param->table_charset;
 
2411
  share->primary_key= MAX_KEY;               // Indicate no primary key
 
2412
  share->keys_for_keyread.reset();
 
2413
  share->keys_in_use.reset();
 
2414
 
 
2415
  /* Calculate which type of fields we will store in the temporary table */
 
2416
 
 
2417
  reclength= string_total_length= 0;
 
2418
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
 
2419
  param->using_indirect_summary_function= 0;
 
2420
 
 
2421
  List_iterator_fast<Item> li(fields);
 
2422
  Item *item;
 
2423
  Field **tmp_from_field=from_field;
 
2424
  while ((item=li++))
 
2425
  {
 
2426
    Item::Type type=item->type();
 
2427
    if (not_all_columns)
 
2428
    {
 
2429
      if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
 
2430
      {
 
2431
        if (item->used_tables() & OUTER_REF_TABLE_BIT)
 
2432
          item->update_used_tables();
 
2433
        if (type == Item::SUBSELECT_ITEM ||
 
2434
            (item->used_tables() & ~OUTER_REF_TABLE_BIT))
 
2435
        {
 
2436
          /*
 
2437
            Mark that the we have ignored an item that refers to a summary
 
2438
            function. We need to know this if someone is going to use
 
2439
            DISTINCT on the result.
 
2440
          */
 
2441
          param->using_indirect_summary_function=1;
 
2442
          continue;
 
2443
        }
 
2444
      }
 
2445
      if (item->const_item() && (int) hidden_field_count <= 0)
 
2446
        continue; // We don't have to store this
 
2447
    }
 
2448
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
 
2449
    {                                           /* Can't calc group yet */
 
2450
      ((Item_sum*) item)->result_field= 0;
 
2451
      for (i= 0 ; i < ((Item_sum*) item)->arg_count ; i++)
 
2452
      {
 
2453
        Item **argp= ((Item_sum*) item)->args + i;
 
2454
        Item *arg= *argp;
 
2455
        if (!arg->const_item())
 
2456
        {
 
2457
          Field *new_field=
 
2458
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
 
2459
                             tmp_from_field, &default_field[fieldnr],
 
2460
                             group != 0,not_all_columns,
 
2461
                             distinct, 0,
 
2462
                             param->convert_blob_length);
 
2463
          if (!new_field)
 
2464
            goto err;                                   // Should be OOM
 
2465
          tmp_from_field++;
 
2466
          reclength+=new_field->pack_length();
 
2467
          if (new_field->flags & BLOB_FLAG)
 
2468
          {
 
2469
            *blob_field++= fieldnr;
 
2470
            blob_count++;
 
2471
          }
 
2472
          *(reg_field++)= new_field;
 
2473
          if (new_field->real_type() == DRIZZLE_TYPE_VARCHAR)
 
2474
          {
 
2475
            string_count++;
 
2476
            string_total_length+= new_field->pack_length();
 
2477
          }
 
2478
          session->mem_root= mem_root_save;
 
2479
          session->change_item_tree(argp, new Item_field(new_field));
 
2480
          session->mem_root= &table->mem_root;
 
2481
          if (!(new_field->flags & NOT_NULL_FLAG))
 
2482
          {
 
2483
            null_count++;
 
2484
            /*
 
2485
              new_field->maybe_null() is still false, it will be
 
2486
              changed below. But we have to setup Item_field correctly
 
2487
            */
 
2488
            (*argp)->maybe_null=1;
 
2489
          }
 
2490
          new_field->field_index= fieldnr++;
 
2491
        }
 
2492
      }
 
2493
    }
 
2494
    else
 
2495
    {
 
2496
      /*
 
2497
        The last parameter to create_tmp_field() is a bit tricky:
 
2498
 
 
2499
        We need to set it to 0 in union, to get fill_record() to modify the
 
2500
        temporary table.
 
2501
        We need to set it to 1 on multi-table-update and in select to
 
2502
        write rows to the temporary table.
 
2503
        We here distinguish between UNION and multi-table-updates by the fact
 
2504
        that in the later case group is set to the row pointer.
 
2505
      */
 
2506
      Field *new_field= (param->schema_table) ?
 
2507
        create_tmp_field_for_schema(item, table) :
 
2508
        create_tmp_field(session, table, item, type, &copy_func,
 
2509
                         tmp_from_field, &default_field[fieldnr],
 
2510
                         group != 0,
 
2511
                         !force_copy_fields &&
 
2512
                           (not_all_columns || group != 0),
 
2513
                         /*
 
2514
                           If item->marker == 4 then we force create_tmp_field
 
2515
                           to create a 64-bit longs for BIT fields because HEAP
 
2516
                           tables can't index BIT fields directly. We do the same
 
2517
                           for distinct, as we want the distinct index to be
 
2518
                           usable in this case too.
 
2519
                         */
 
2520
                         item->marker == 4 || param->bit_fields_as_long,
 
2521
                         force_copy_fields,
 
2522
                         param->convert_blob_length);
 
2523
 
 
2524
      if (!new_field)
 
2525
      {
 
2526
        if (session->is_fatal_error)
 
2527
          goto err;                             // Got OOM
 
2528
        continue;                               // Some kindf of const item
 
2529
      }
 
2530
      if (type == Item::SUM_FUNC_ITEM)
 
2531
        ((Item_sum *) item)->result_field= new_field;
 
2532
      tmp_from_field++;
 
2533
      reclength+=new_field->pack_length();
 
2534
      if (!(new_field->flags & NOT_NULL_FLAG))
 
2535
        null_count++;
 
2536
      if (new_field->flags & BLOB_FLAG)
 
2537
      {
 
2538
        *blob_field++= fieldnr;
 
2539
        blob_count++;
 
2540
      }
 
2541
      if (item->marker == 4 && item->maybe_null)
 
2542
      {
 
2543
        group_null_items++;
 
2544
        new_field->flags|= GROUP_FLAG;
 
2545
      }
 
2546
      new_field->field_index= fieldnr++;
 
2547
      *(reg_field++)= new_field;
 
2548
    }
 
2549
    if (!--hidden_field_count)
 
2550
    {
 
2551
      /*
 
2552
        This was the last hidden field; Remember how many hidden fields could
 
2553
        have null
 
2554
      */
 
2555
      hidden_null_count=null_count;
 
2556
      /*
 
2557
        We need to update hidden_field_count as we may have stored group
 
2558
        functions with constant arguments
 
2559
      */
 
2560
      param->hidden_field_count= fieldnr;
 
2561
      null_count= 0;
 
2562
    }
 
2563
  }
 
2564
  assert(fieldnr == (uint32_t) (reg_field - table->field));
 
2565
  assert(field_count >= (uint32_t) (reg_field - table->field));
 
2566
  field_count= fieldnr;
 
2567
  *reg_field= 0;
 
2568
  *blob_field= 0;                               // End marker
 
2569
  share->fields= field_count;
 
2570
 
 
2571
  /* If result table is small; use a heap */
 
2572
  /* future: storage engine selection can be made dynamic? */
 
2573
  if (blob_count || using_unique_constraint ||
 
2574
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
2575
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
 
2576
  {
 
2577
    share->storage_engine= myisam_engine;
 
2578
    table->file= share->db_type()->getCursor(share, &table->mem_root);
 
2579
    if (group &&
 
2580
        (param->group_parts > table->file->max_key_parts() ||
 
2581
         param->group_length > table->file->max_key_length()))
 
2582
      using_unique_constraint=1;
 
2583
  }
 
2584
  else
 
2585
  {
 
2586
    share->storage_engine= heap_engine;
 
2587
    table->file= share->db_type()->getCursor(share, &table->mem_root);
 
2588
  }
 
2589
  if (!table->file)
 
2590
    goto err;
 
2591
 
 
2592
 
 
2593
  if (!using_unique_constraint)
 
2594
    reclength+= group_null_items;       // null flag is stored separately
 
2595
 
 
2596
  share->blob_fields= blob_count;
 
2597
  if (blob_count == 0)
 
2598
  {
 
2599
    /* We need to ensure that first byte is not 0 for the delete link */
 
2600
    if (param->hidden_field_count)
 
2601
      hidden_null_count++;
 
2602
    else
 
2603
      null_count++;
 
2604
  }
 
2605
  hidden_null_pack_length=(hidden_null_count+7)/8;
 
2606
  null_pack_length= (hidden_null_pack_length +
 
2607
                     (null_count + total_uneven_bit_length + 7) / 8);
 
2608
  reclength+=null_pack_length;
 
2609
  if (!reclength)
 
2610
    reclength=1;                                // Dummy select
 
2611
  /* Use packed rows if there is blobs or a lot of space to gain */
 
2612
  if (blob_count || ((string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS) && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || (string_total_length / string_count) >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
 
2613
    use_packed_rows= 1;
 
2614
 
 
2615
  share->reclength= reclength;
 
2616
  {
 
2617
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
 
2618
    share->rec_buff_length= alloc_length;
 
2619
    if (!(table->record[0]= (unsigned char*)
 
2620
                            alloc_root(&table->mem_root, alloc_length*3)))
 
2621
      goto err;
 
2622
    table->record[1]= table->record[0]+alloc_length;
 
2623
    share->default_values= table->record[1]+alloc_length;
 
2624
  }
 
2625
  copy_func[0]= 0;                              // End marker
 
2626
  param->func_count= copy_func - param->items_to_copy;
 
2627
 
 
2628
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
2629
 
 
2630
  recinfo=param->start_recinfo;
 
2631
  null_flags=(unsigned char*) table->record[0];
 
2632
  pos=table->record[0]+ null_pack_length;
 
2633
  if (null_pack_length)
 
2634
  {
 
2635
    memset(recinfo, 0, sizeof(*recinfo));
 
2636
    recinfo->type=FIELD_NORMAL;
 
2637
    recinfo->length=null_pack_length;
 
2638
    recinfo++;
 
2639
    memset(null_flags, 255, null_pack_length);  // Set null fields
 
2640
 
 
2641
    table->null_flags= (unsigned char*) table->record[0];
 
2642
    share->null_fields= null_count+ hidden_null_count;
 
2643
    share->null_bytes= null_pack_length;
 
2644
  }
 
2645
  null_count= (blob_count == 0) ? 1 : 0;
 
2646
  hidden_field_count=param->hidden_field_count;
 
2647
  for (i= 0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
 
2648
  {
 
2649
    Field *field= *reg_field;
 
2650
    uint32_t length;
 
2651
    memset(recinfo, 0, sizeof(*recinfo));
 
2652
 
 
2653
    if (!(field->flags & NOT_NULL_FLAG))
 
2654
    {
 
2655
      if (field->flags & GROUP_FLAG && !using_unique_constraint)
 
2656
      {
 
2657
        /*
 
2658
          We have to reserve one byte here for NULL bits,
 
2659
          as this is updated by 'end_update()'
 
2660
        */
 
2661
        *pos++= '\0';                           // Null is stored here
 
2662
        recinfo->length= 1;
 
2663
        recinfo->type=FIELD_NORMAL;
 
2664
        recinfo++;
 
2665
        memset(recinfo, 0, sizeof(*recinfo));
 
2666
      }
 
2667
      else
 
2668
      {
 
2669
        recinfo->null_bit= 1 << (null_count & 7);
 
2670
        recinfo->null_pos= null_count/8;
 
2671
      }
 
2672
      field->move_field(pos,null_flags+null_count/8,
 
2673
                        1 << (null_count & 7));
 
2674
      null_count++;
 
2675
    }
 
2676
    else
 
2677
      field->move_field(pos,(unsigned char*) 0,0);
 
2678
    field->reset();
 
2679
 
 
2680
    /*
 
2681
      Test if there is a default field value. The test for ->ptr is to skip
 
2682
      'offset' fields generated by initalize_tables
 
2683
    */
 
2684
    if (default_field[i] && default_field[i]->ptr)
 
2685
    {
 
2686
      /*
 
2687
         default_field[i] is set only in the cases  when 'field' can
 
2688
         inherit the default value that is defined for the field referred
 
2689
         by the Item_field object from which 'field' has been created.
 
2690
      */
 
2691
      ptrdiff_t diff;
 
2692
      Field *orig_field= default_field[i];
 
2693
      /* Get the value from default_values */
 
2694
      diff= (ptrdiff_t) (orig_field->table->s->default_values-
 
2695
                            orig_field->table->record[0]);
 
2696
      orig_field->move_field_offset(diff);      // Points now at default_values
 
2697
      if (orig_field->is_real_null())
 
2698
        field->set_null();
 
2699
      else
 
2700
      {
 
2701
        field->set_notnull();
 
2702
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
 
2703
      }
 
2704
      orig_field->move_field_offset(-diff);     // Back to record[0]
 
2705
    }
 
2706
 
 
2707
    if (from_field[i])
 
2708
    {                                           /* Not a table Item */
 
2709
      copy->set(field,from_field[i],save_sum_fields);
 
2710
      copy++;
 
2711
    }
 
2712
    length=field->pack_length();
 
2713
    pos+= length;
 
2714
 
 
2715
    /* Make entry for create table */
 
2716
    recinfo->length=length;
 
2717
    if (field->flags & BLOB_FLAG)
 
2718
      recinfo->type= (int) FIELD_BLOB;
 
2719
    else
 
2720
      recinfo->type=FIELD_NORMAL;
 
2721
    if (!--hidden_field_count)
 
2722
      null_count=(null_count+7) & ~7;           // move to next byte
 
2723
 
 
2724
    // fix table name in field entry
 
2725
    field->table_name= &table->alias;
 
2726
  }
 
2727
 
 
2728
  param->copy_field_end=copy;
 
2729
  param->recinfo=recinfo;
 
2730
  table->storeRecordAsDefault();        // Make empty default record
 
2731
 
 
2732
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
 
2733
    max_rows= ~(uint64_t) 0;
 
2734
  else
 
2735
    max_rows= (uint64_t) (((share->db_type() == heap_engine) ?
 
2736
                          min(session->variables.tmp_table_size,
 
2737
                              session->variables.max_heap_table_size) :
 
2738
                          session->variables.tmp_table_size) /
 
2739
                         share->reclength);
 
2740
 
 
2741
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
 
2742
  /*
 
2743
    Push the LIMIT clause to the temporary table creation, so that we
 
2744
    materialize only up to 'rows_limit' records instead of all result records.
 
2745
  */
 
2746
  set_if_smaller(max_rows, rows_limit);
 
2747
 
 
2748
  share->setMaxRows(max_rows);
 
2749
 
 
2750
  param->end_write_records= rows_limit;
 
2751
 
 
2752
  keyinfo= param->keyinfo;
 
2753
 
 
2754
  if (group)
 
2755
  {
 
2756
    table->group=group;                         /* Table is grouped by key */
 
2757
    param->group_buff=group_buff;
 
2758
    share->keys=1;
 
2759
    share->uniques= test(using_unique_constraint);
 
2760
    table->key_info=keyinfo;
 
2761
    keyinfo->key_part=key_part_info;
 
2762
    keyinfo->flags=HA_NOSAME;
 
2763
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
 
2764
    keyinfo->key_length= 0;
 
2765
    keyinfo->rec_per_key= 0;
 
2766
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
2767
    keyinfo->name= (char*) "group_key";
 
2768
    order_st *cur_group= group;
 
2769
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
 
2770
    {
 
2771
      Field *field=(*cur_group->item)->get_tmp_table_field();
 
2772
      bool maybe_null=(*cur_group->item)->maybe_null;
 
2773
      key_part_info->null_bit= 0;
 
2774
      key_part_info->field=  field;
 
2775
      key_part_info->offset= field->offset(table->record[0]);
 
2776
      key_part_info->length= (uint16_t) field->key_length();
 
2777
      key_part_info->type=   (uint8_t) field->key_type();
 
2778
      key_part_info->key_type= 
 
2779
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
 
2780
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
 
2781
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
 
2782
        0 : 1;
 
2783
      if (!using_unique_constraint)
 
2784
      {
 
2785
        cur_group->buff=(char*) group_buff;
 
2786
        if (!(cur_group->field= field->new_key_field(session->mem_root,table,
 
2787
                                                     group_buff +
 
2788
                                                     test(maybe_null),
 
2789
                                                     field->null_ptr,
 
2790
                                                     field->null_bit)))
 
2791
          goto err;
 
2792
        if (maybe_null)
 
2793
        {
 
2794
          /*
 
2795
            To be able to group on NULL, we reserved place in group_buff
 
2796
            for the NULL flag just before the column. (see above).
 
2797
            The field data is after this flag.
 
2798
            The NULL flag is updated in 'end_update()' and 'end_write()'
 
2799
          */
 
2800
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
 
2801
          key_part_info->null_bit=field->null_bit;
 
2802
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
 
2803
                                              (unsigned char*) table->record[0]);
 
2804
          cur_group->buff++;                        // Pointer to field data
 
2805
          group_buff++;                         // Skipp null flag
 
2806
        }
 
2807
        /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
 
2808
        key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
 
2809
        group_buff+= cur_group->field->pack_length();
 
2810
      }
 
2811
      keyinfo->key_length+=  key_part_info->length;
 
2812
    }
 
2813
  }
 
2814
 
 
2815
  if (distinct && field_count != param->hidden_field_count)
 
2816
  {
 
2817
    /*
 
2818
      Create an unique key or an unique constraint over all columns
 
2819
      that should be in the result.  In the temporary table, there are
 
2820
      'param->hidden_field_count' extra columns, whose null bits are stored
 
2821
      in the first 'hidden_null_pack_length' bytes of the row.
 
2822
    */
 
2823
    if (blob_count)
 
2824
    {
 
2825
      /*
 
2826
        Special mode for index creation in MyISAM used to support unique
 
2827
        indexes on blobs with arbitrary length. Such indexes cannot be
 
2828
        used for lookups.
 
2829
      */
 
2830
      share->uniques= 1;
 
2831
    }
 
2832
    null_pack_length-=hidden_null_pack_length;
 
2833
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
 
2834
                         (share->uniques ? test(null_pack_length) : 0));
 
2835
    table->distinct= 1;
 
2836
    share->keys= 1;
 
2837
    if (!(key_part_info= (KEY_PART_INFO*)
 
2838
          alloc_root(&table->mem_root,
 
2839
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
 
2840
      goto err;
 
2841
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
 
2842
    table->key_info=keyinfo;
 
2843
    keyinfo->key_part=key_part_info;
 
2844
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
 
2845
    keyinfo->key_length=(uint16_t) reclength;
 
2846
    keyinfo->name= (char*) "distinct_key";
 
2847
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
2848
    keyinfo->rec_per_key= 0;
 
2849
 
 
2850
    /*
 
2851
      Create an extra field to hold NULL bits so that unique indexes on
 
2852
      blobs can distinguish NULL from 0. This extra field is not needed
 
2853
      when we do not use UNIQUE indexes for blobs.
 
2854
    */
 
2855
    if (null_pack_length && share->uniques)
 
2856
    {
 
2857
      key_part_info->null_bit= 0;
 
2858
      key_part_info->offset=hidden_null_pack_length;
 
2859
      key_part_info->length=null_pack_length;
 
2860
      key_part_info->field= new Field_varstring(table->record[0],
 
2861
                                                (uint32_t) key_part_info->length,
 
2862
                                                0,
 
2863
                                                (unsigned char*) 0,
 
2864
                                                (uint32_t) 0,
 
2865
                                                NULL,
 
2866
                                                table->s,
 
2867
                                                &my_charset_bin);
 
2868
      if (!key_part_info->field)
 
2869
        goto err;
 
2870
      key_part_info->field->init(table);
 
2871
      key_part_info->key_type= 1; /* binary comparison */
 
2872
      key_part_info->type=    HA_KEYTYPE_BINARY;
 
2873
      key_part_info++;
 
2874
    }
 
2875
    /* Create a distinct key over the columns we are going to return */
 
2876
    for (i=param->hidden_field_count, reg_field=table->field + i ;
 
2877
         i < field_count;
 
2878
         i++, reg_field++, key_part_info++)
 
2879
    {
 
2880
      key_part_info->null_bit= 0;
 
2881
      key_part_info->field=    *reg_field;
 
2882
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
 
2883
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
 
2884
      /* TODO:
 
2885
        The below method of computing the key format length of the
 
2886
        key part is a copy/paste from opt_range.cc, and table.cc.
 
2887
        This should be factored out, e.g. as a method of Field.
 
2888
        In addition it is not clear if any of the Field::*_length
 
2889
        methods is supposed to compute the same length. If so, it
 
2890
        might be reused.
 
2891
      */
 
2892
      key_part_info->store_length= key_part_info->length;
 
2893
 
 
2894
      if ((*reg_field)->real_maybe_null())
 
2895
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
 
2896
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB ||
 
2897
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
 
2898
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
 
2899
 
 
2900
      key_part_info->type=     (uint8_t) (*reg_field)->key_type();
 
2901
      key_part_info->key_type =
 
2902
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
 
2903
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
 
2904
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
 
2905
        0 : 1;
 
2906
    }
 
2907
  }
 
2908
 
 
2909
  if (session->is_fatal_error)                          // If end of memory
 
2910
    goto err;
 
2911
  share->db_record_offset= 1;
 
2912
  if (share->db_type() == myisam_engine)
 
2913
  {
 
2914
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
 
2915
                                       &param->recinfo, select_options))
 
2916
      goto err;
 
2917
  }
 
2918
  if (table->open_tmp_table())
 
2919
    goto err;
 
2920
 
 
2921
  session->mem_root= mem_root_save;
 
2922
 
 
2923
  return(table);
 
2924
 
 
2925
err:
 
2926
  session->mem_root= mem_root_save;
 
2927
  table->free_tmp_table(session);
 
2928
  return NULL;
 
2929
}
 
2930
 
 
2931
/****************************************************************************/
 
2932
 
 
2933
/**
 
2934
  Create a reduced Table object with properly set up Field list from a
 
2935
  list of field definitions.
 
2936
 
 
2937
    The created table doesn't have a table Cursor associated with
 
2938
    it, has no keys, no group/distinct, no copy_funcs array.
 
2939
    The sole purpose of this Table object is to use the power of Field
 
2940
    class to read/write data to/from table->record[0]. Then one can store
 
2941
    the record in any container (RB tree, hash, etc).
 
2942
    The table is created in Session mem_root, so are the table's fields.
 
2943
    Consequently, if you don't BLOB fields, you don't need to free it.
 
2944
 
 
2945
  @param session         connection handle
 
2946
  @param field_list  list of column definitions
 
2947
 
 
2948
  @return
 
2949
    0 if out of memory, Table object in case of success
 
2950
*/
 
2951
 
 
2952
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
 
2953
{
 
2954
  uint32_t field_count= field_list.elements;
 
2955
  uint32_t blob_count= 0;
 
2956
  Field **field;
 
2957
  CreateField *cdef;                           /* column definition */
 
2958
  uint32_t record_length= 0;
 
2959
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
2960
  uint32_t null_pack_length;              /* NULL representation array length */
 
2961
  uint32_t *blob_field;
 
2962
  unsigned char *bitmaps;
 
2963
  Table *table;
 
2964
  TableShare *share;
 
2965
 
 
2966
  if (!multi_alloc_root(session->mem_root,
 
2967
                        &table, sizeof(*table),
 
2968
                        &share, sizeof(*share),
 
2969
                        &field, (field_count + 1) * sizeof(Field*),
 
2970
                        &blob_field, (field_count+1) *sizeof(uint32_t),
 
2971
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
2972
                        NULL))
 
2973
    return NULL;
 
2974
 
 
2975
  memset(table, 0, sizeof(*table));
 
2976
  memset(share, 0, sizeof(*share));
 
2977
  table->field= field;
 
2978
  table->s= share;
 
2979
  share->blob_field= blob_field;
 
2980
  share->fields= field_count;
 
2981
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
2982
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
2983
 
 
2984
  /* Create all fields and calculate the total length of record */
 
2985
  List_iterator_fast<CreateField> it(field_list);
 
2986
  while ((cdef= it++))
 
2987
  {
 
2988
    *field= make_field(share,
 
2989
                       NULL,
 
2990
                       0,
 
2991
                       cdef->length,
 
2992
                       (cdef->flags & NOT_NULL_FLAG) ? false : true,
 
2993
                       (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
 
2994
                       (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
 
2995
                       cdef->decimals,
 
2996
                       cdef->sql_type,
 
2997
                       cdef->charset,
 
2998
                       cdef->unireg_check,
 
2999
                       cdef->interval,
 
3000
                       cdef->field_name);
 
3001
    if (!*field)
 
3002
      goto error;
 
3003
    (*field)->init(table);
 
3004
    record_length+= (*field)->pack_length();
 
3005
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
3006
      null_count++;
 
3007
 
 
3008
    if ((*field)->flags & BLOB_FLAG)
 
3009
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
 
3010
 
 
3011
    field++;
 
3012
  }
 
3013
  *field= NULL;                             /* mark the end of the list */
 
3014
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
3015
  share->blob_fields= blob_count;
 
3016
 
 
3017
  null_pack_length= (null_count + 7)/8;
 
3018
  share->reclength= record_length + null_pack_length;
 
3019
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
3020
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
 
3021
  if (!table->record[0])
 
3022
    goto error;
 
3023
 
 
3024
  if (null_pack_length)
 
3025
  {
 
3026
    table->null_flags= (unsigned char*) table->record[0];
 
3027
    share->null_fields= null_count;
 
3028
    share->null_bytes= null_pack_length;
 
3029
  }
 
3030
 
 
3031
  table->in_use= session;           /* field->reset() may access table->in_use */
 
3032
  {
 
3033
    /* Set up field pointers */
 
3034
    unsigned char *null_pos= table->record[0];
 
3035
    unsigned char *field_pos= null_pos + share->null_bytes;
 
3036
    uint32_t null_bit= 1;
 
3037
 
 
3038
    for (field= table->field; *field; ++field)
 
3039
    {
 
3040
      Field *cur_field= *field;
 
3041
      if ((cur_field->flags & NOT_NULL_FLAG))
 
3042
        cur_field->move_field(field_pos);
 
3043
      else
 
3044
      {
 
3045
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
3046
        null_bit<<= 1;
 
3047
        if (null_bit == (1 << 8))
 
3048
        {
 
3049
          ++null_pos;
 
3050
          null_bit= 1;
 
3051
        }
 
3052
      }
 
3053
      cur_field->reset();
 
3054
 
 
3055
      field_pos+= cur_field->pack_length();
 
3056
    }
 
3057
  }
 
3058
  return table;
 
3059
error:
 
3060
  for (field= table->field; *field; ++field)
 
3061
    delete *field;                         /* just invokes field destructor */
 
3062
  return 0;
 
3063
}
 
3064
 
 
3065
bool Table::open_tmp_table()
 
3066
{
 
3067
  int error;
 
3068
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
 
3069
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
3070
  {
 
3071
    file->print_error(error,MYF(0));
 
3072
    db_stat= 0;
 
3073
    return true;
 
3074
  }
 
3075
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
3076
  return false;
 
3077
}
 
3078
 
 
3079
 
3535
3080
/*
3536
 
  Check type of .frm if we are not going to parse it
 
3081
  Create MyISAM temporary table
3537
3082
 
3538
3083
  SYNOPSIS
3539
 
  mysql_frm_type()
3540
 
  path        path to file
3541
 
 
3542
 
  RETURN
3543
 
  FRMTYPE_ERROR       error
3544
 
  FRMTYPE_TABLE       table
 
3084
    create_myisam_tmp_table()
 
3085
      keyinfo         Description of the index (there is always one index)
 
3086
      start_recinfo   MyISAM's column descriptions
 
3087
      recinfo INOUT   End of MyISAM's column descriptions
 
3088
      options         Option bits
 
3089
 
 
3090
  DESCRIPTION
 
3091
    Create a MyISAM temporary table according to passed description. The is
 
3092
    assumed to have one unique index or constraint.
 
3093
 
 
3094
    The passed array or MI_COLUMNDEF structures must have this form:
 
3095
 
 
3096
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
3097
         when there are many nullable columns)
 
3098
      2. Table columns
 
3099
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
3100
 
 
3101
    This function may use the free element to create hash column for unique
 
3102
    constraint.
 
3103
 
 
3104
   RETURN
 
3105
     false - OK
 
3106
     true  - Error
3545
3107
*/
3546
3108
 
3547
 
frm_type_enum mysql_frm_type(THD *thd __attribute__((unused)),
3548
 
                             char *path, enum legacy_db_type *dbt)
 
3109
bool Table::create_myisam_tmp_table(KEY *keyinfo,
 
3110
                                    MI_COLUMNDEF *start_recinfo,
 
3111
                                    MI_COLUMNDEF **recinfo,
 
3112
                                    uint64_t options)
3549
3113
{
3550
 
  File file;
3551
 
  uchar header[10];     /* This should be optimized */
3552
3114
  int error;
3553
 
 
3554
 
  *dbt= DB_TYPE_UNKNOWN;
3555
 
 
3556
 
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
3557
 
    return(FRMTYPE_ERROR);
3558
 
  error= my_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
3559
 
  my_close(file, MYF(MY_WME));
3560
 
 
3561
 
  if (error)
3562
 
    return(FRMTYPE_ERROR);
3563
 
 
3564
 
  /*  
3565
 
    This is just a check for DB_TYPE. We'll return default unknown type
3566
 
    if the following test is true (arg #3). This should not have effect
3567
 
    on return value from this function (default FRMTYPE_TABLE)
3568
 
   */  
3569
 
  if (header[0] != (uchar) 254 || header[1] != 1 ||
3570
 
      (header[2] != FRM_VER && header[2] != FRM_VER+1 &&
3571
 
       (header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
3572
 
    return(FRMTYPE_TABLE);
3573
 
 
3574
 
  *dbt= (enum legacy_db_type) (uint) *(header + 3);
3575
 
  return(FRMTYPE_TABLE);                   // Is probably a .frm table
3576
 
}
3577
 
 
3578
 
 
3579
 
/*****************************************************************************
3580
 
** Instansiate templates
3581
 
*****************************************************************************/
 
3115
  MI_KEYDEF keydef;
 
3116
  MI_UNIQUEDEF uniquedef;
 
3117
  TableShare *share= s;
 
3118
 
 
3119
  if (share->keys)
 
3120
  {                                             // Get keys for ni_create
 
3121
    bool using_unique_constraint= 0;
 
3122
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
 
3123
                                            sizeof(*seg) * keyinfo->key_parts);
 
3124
    if (!seg)
 
3125
      goto err;
 
3126
 
 
3127
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
3128
    if (keyinfo->key_length >= file->max_key_length() ||
 
3129
        keyinfo->key_parts > file->max_key_parts() ||
 
3130
        share->uniques)
 
3131
    {
 
3132
      /* Can't create a key; Make a unique constraint instead of a key */
 
3133
      share->keys=    0;
 
3134
      share->uniques= 1;
 
3135
      using_unique_constraint=1;
 
3136
      memset(&uniquedef, 0, sizeof(uniquedef));
 
3137
      uniquedef.keysegs=keyinfo->key_parts;
 
3138
      uniquedef.seg=seg;
 
3139
      uniquedef.null_are_equal=1;
 
3140
 
 
3141
      /* Create extra column for hash value */
 
3142
      memset(*recinfo, 0, sizeof(**recinfo));
 
3143
      (*recinfo)->type= FIELD_CHECK;
 
3144
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
3145
      (*recinfo)++;
 
3146
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
 
3147
    }
 
3148
    else
 
3149
    {
 
3150
      /* Create an unique key */
 
3151
      memset(&keydef, 0, sizeof(keydef));
 
3152
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
3153
      keydef.keysegs=  keyinfo->key_parts;
 
3154
      keydef.seg= seg;
 
3155
    }
 
3156
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
3157
    {
 
3158
      Field *key_field=keyinfo->key_part[i].field;
 
3159
      seg->flag=     0;
 
3160
      seg->language= key_field->charset()->number;
 
3161
      seg->length=   keyinfo->key_part[i].length;
 
3162
      seg->start=    keyinfo->key_part[i].offset;
 
3163
      if (key_field->flags & BLOB_FLAG)
 
3164
      {
 
3165
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
3166
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
3167
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
3168
                                  - share->blob_ptr_size);
 
3169
        seg->flag= HA_BLOB_PART;
 
3170
        seg->length= 0;                 // Whole blob in unique constraint
 
3171
      }
 
3172
      else
 
3173
      {
 
3174
        seg->type= keyinfo->key_part[i].type;
 
3175
      }
 
3176
      if (!(key_field->flags & NOT_NULL_FLAG))
 
3177
      {
 
3178
        seg->null_bit= key_field->null_bit;
 
3179
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
 
3180
        /*
 
3181
          We are using a GROUP BY on something that contains NULL
 
3182
          In this case we have to tell MyISAM that two NULL should
 
3183
          on INSERT be regarded at the same value
 
3184
        */
 
3185
        if (!using_unique_constraint)
 
3186
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
3187
      }
 
3188
    }
 
3189
  }
 
3190
  MI_CREATE_INFO create_info;
 
3191
  memset(&create_info, 0, sizeof(create_info));
 
3192
 
 
3193
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
3194
      OPTION_BIG_TABLES)
 
3195
    create_info.data_file_length= ~(uint64_t) 0;
 
3196
 
 
3197
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
 
3198
                       (uint32_t) (*recinfo-start_recinfo),
 
3199
                       start_recinfo,
 
3200
                       share->uniques, &uniquedef,
 
3201
                       &create_info,
 
3202
                       HA_CREATE_TMP_TABLE)))
 
3203
  {
 
3204
    file->print_error(error,MYF(0));
 
3205
    db_stat= 0;
 
3206
    goto err;
 
3207
  }
 
3208
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
 
3209
  share->db_record_offset= 1;
 
3210
  return false;
 
3211
 err:
 
3212
  return true;
 
3213
}
 
3214
 
 
3215
 
 
3216
void Table::free_tmp_table(Session *session)
 
3217
{
 
3218
  MEM_ROOT own_root= mem_root;
 
3219
  const char *save_proc_info;
 
3220
 
 
3221
  save_proc_info=session->get_proc_info();
 
3222
  session->set_proc_info("removing tmp table");
 
3223
 
 
3224
  // Release latches since this can take a long time
 
3225
  plugin::StorageEngine::releaseTemporaryLatches(session);
 
3226
 
 
3227
  if (file)
 
3228
  {
 
3229
    if (db_stat)
 
3230
      file->closeMarkForDelete(s->table_name.str);
 
3231
 
 
3232
    s->db_type()->doDeleteTable(session, s->table_name.str);
 
3233
 
 
3234
    delete file;
 
3235
  }
 
3236
 
 
3237
  /* free blobs */
 
3238
  for (Field **ptr= field ; *ptr ; ptr++)
 
3239
    (*ptr)->free();
 
3240
  free_io_cache();
 
3241
 
 
3242
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
 
3243
  session->set_proc_info(save_proc_info);
 
3244
}
 
3245
 
 
3246
/**
 
3247
  If a HEAP table gets full, create a MyISAM table and copy all rows
 
3248
  to this.
 
3249
*/
 
3250
 
 
3251
bool create_myisam_from_heap(Session *session, Table *table,
 
3252
                             MI_COLUMNDEF *start_recinfo,
 
3253
                             MI_COLUMNDEF **recinfo,
 
3254
                             int error, bool ignore_last_dupp_key_error)
 
3255
{
 
3256
  Table new_table;
 
3257
  TableShare share;
 
3258
  const char *save_proc_info;
 
3259
  int write_err;
 
3260
 
 
3261
  if (table->s->db_type() != heap_engine ||
 
3262
      error != HA_ERR_RECORD_FILE_FULL)
 
3263
  {
 
3264
    table->file->print_error(error,MYF(0));
 
3265
    return true;
 
3266
  }
 
3267
 
 
3268
  // Release latches since this can take a long time
 
3269
  plugin::StorageEngine::releaseTemporaryLatches(session);
 
3270
 
 
3271
  new_table= *table;
 
3272
  share= *table->s;
 
3273
  new_table.s= &share;
 
3274
  new_table.s->storage_engine= myisam_engine;
 
3275
  if (!(new_table.file= new_table.s->db_type()->getCursor(&share, &new_table.mem_root)))
 
3276
    return true;                                // End of memory
 
3277
 
 
3278
  save_proc_info=session->get_proc_info();
 
3279
  session->set_proc_info("converting HEAP to MyISAM");
 
3280
 
 
3281
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
 
3282
                                        recinfo, session->lex->select_lex.options |
 
3283
                                        session->options))
 
3284
    goto err2;
 
3285
  if (new_table.open_tmp_table())
 
3286
    goto err1;
 
3287
  if (table->file->indexes_are_disabled())
 
3288
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
3289
  table->file->ha_index_or_rnd_end();
 
3290
  table->file->ha_rnd_init(1);
 
3291
  if (table->no_rows)
 
3292
  {
 
3293
    new_table.file->extra(HA_EXTRA_NO_ROWS);
 
3294
    new_table.no_rows=1;
 
3295
  }
 
3296
 
 
3297
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
 
3298
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
 
3299
 
 
3300
  /*
 
3301
    copy all old rows from heap table to MyISAM table
 
3302
    This is the only code that uses record[1] to read/write but this
 
3303
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
 
3304
  */
 
3305
  while (!table->file->rnd_next(new_table.record[1]))
 
3306
  {
 
3307
    write_err= new_table.file->ha_write_row(new_table.record[1]);
 
3308
    if (write_err)
 
3309
      goto err;
 
3310
  }
 
3311
  /* copy row that filled HEAP table */
 
3312
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
 
3313
  {
 
3314
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
3315
        !ignore_last_dupp_key_error)
 
3316
      goto err;
 
3317
  }
 
3318
 
 
3319
  /* remove heap table and change to use myisam table */
 
3320
  (void) table->file->ha_rnd_end();
 
3321
  (void) table->file->close();                  // This deletes the table !
 
3322
  delete table->file;
 
3323
  table->file= NULL;
 
3324
  new_table.s= table->s;                       // Keep old share
 
3325
  *table= new_table;
 
3326
  *table->s= share;
 
3327
 
 
3328
  table->file->change_table_ptr(table, table->s);
 
3329
  table->use_all_columns();
 
3330
  if (save_proc_info)
 
3331
  {
 
3332
    const char *new_proc_info=
 
3333
      (!strcmp(save_proc_info,"Copying to tmp table") ?
 
3334
      "Copying to tmp table on disk" : save_proc_info);
 
3335
    session->set_proc_info(new_proc_info);
 
3336
  }
 
3337
  return false;
 
3338
 
 
3339
 err:
 
3340
  table->file->print_error(write_err, MYF(0));
 
3341
  (void) table->file->ha_rnd_end();
 
3342
  (void) new_table.file->close();
 
3343
 err1:
 
3344
  new_table.s->db_type()->doDeleteTable(session, new_table.s->table_name.str);
 
3345
 err2:
 
3346
  delete new_table.file;
 
3347
  session->set_proc_info(save_proc_info);
 
3348
  table->mem_root= new_table.mem_root;
 
3349
  return true;
 
3350
}
 
3351
 
 
3352
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
3353
{
 
3354
  my_bitmap_map *old= bitmap->getBitmap();
 
3355
  bitmap->setBitmap(s->all_set.getBitmap());
 
3356
  return old;
 
3357
}
 
3358
 
 
3359
void Table::restore_column_map(my_bitmap_map *old)
 
3360
{
 
3361
  read_set->setBitmap(old);
 
3362
}
 
3363
 
 
3364
uint32_t Table::find_shortest_key(const key_map *usable_keys)
 
3365
{
 
3366
  uint32_t min_length= UINT32_MAX;
 
3367
  uint32_t best= MAX_KEY;
 
3368
  if (usable_keys->any())
 
3369
  {
 
3370
    for (uint32_t nr= 0; nr < s->keys ; nr++)
 
3371
    {
 
3372
      if (usable_keys->test(nr))
 
3373
      {
 
3374
        if (key_info[nr].key_length < min_length)
 
3375
        {
 
3376
          min_length= key_info[nr].key_length;
 
3377
          best=nr;
 
3378
        }
 
3379
      }
 
3380
    }
 
3381
  }
 
3382
  return best;
 
3383
}
 
3384
 
 
3385
/*****************************************************************************
 
3386
  Remove duplicates from tmp table
 
3387
  This should be recoded to add a unique index to the table and remove
 
3388
  duplicates
 
3389
  Table is a locked single thread table
 
3390
  fields is the number of fields to check (from the end)
 
3391
*****************************************************************************/
 
3392
 
 
3393
bool Table::compare_record(Field **ptr)
 
3394
{
 
3395
  for (; *ptr ; ptr++)
 
3396
  {
 
3397
    if ((*ptr)->cmp_offset(s->rec_buff_length))
 
3398
      return true;
 
3399
  }
 
3400
  return false;
 
3401
}
 
3402
 
 
3403
/* Return false if row hasn't changed */
 
3404
 
 
3405
bool Table::compare_record()
 
3406
{
 
3407
  if (s->blob_fields + s->varchar_fields == 0)
 
3408
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
 
3409
  /* Compare null bits */
 
3410
  if (memcmp(null_flags,
 
3411
             null_flags + s->rec_buff_length,
 
3412
             s->null_bytes))
 
3413
    return true;                                // Diff in NULL value
 
3414
  /* Compare updated fields */
 
3415
  for (Field **ptr= field ; *ptr ; ptr++)
 
3416
  {
 
3417
    if (isWriteSet((*ptr)->field_index) &&
 
3418
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
 
3419
      return true;
 
3420
  }
 
3421
  return false;
 
3422
}
 
3423
 
 
3424
/*
 
3425
 * Store a record from previous record into next
 
3426
 *
 
3427
 */
 
3428
void Table::storeRecord()
 
3429
{
 
3430
  memcpy(record[1], record[0], (size_t) s->reclength);
 
3431
}
 
3432
 
 
3433
/*
 
3434
 * Store a record as an insert
 
3435
 *
 
3436
 */
 
3437
void Table::storeRecordAsInsert()
 
3438
{
 
3439
  memcpy(insert_values, record[0], (size_t) s->reclength);
 
3440
}
 
3441
 
 
3442
/*
 
3443
 * Store a record with default values
 
3444
 *
 
3445
 */
 
3446
void Table::storeRecordAsDefault()
 
3447
{
 
3448
  memcpy(s->default_values, record[0], (size_t) s->reclength);
 
3449
}
 
3450
 
 
3451
/*
 
3452
 * Restore a record from previous record into next
 
3453
 *
 
3454
 */
 
3455
void Table::restoreRecord()
 
3456
{
 
3457
  memcpy(record[0], record[1], (size_t) s->reclength);
 
3458
}
 
3459
 
 
3460
/*
 
3461
 * Restore a record with default values
 
3462
 *
 
3463
 */
 
3464
void Table::restoreRecordAsDefault()
 
3465
{
 
3466
  memcpy(record[0], s->default_values, (size_t) s->reclength);
 
3467
}
 
3468
 
 
3469
/*
 
3470
 * Empty a record
 
3471
 *
 
3472
 */
 
3473
void Table::emptyRecord()
 
3474
{
 
3475
  restoreRecordAsDefault();
 
3476
  memset(null_flags, 255, s->null_bytes);
 
3477
}
 
3478
 
 
3479
/*****************************************************************************
 
3480
  The different ways to read a record
 
3481
  Returns -1 if row was not found, 0 if row was found and 1 on errors
 
3482
*****************************************************************************/
 
3483
 
 
3484
/** Help function when we get some an error from the table Cursor. */
 
3485
 
 
3486
int Table::report_error(int error)
 
3487
{
 
3488
  if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND)
 
3489
  {
 
3490
    status= STATUS_GARBAGE;
 
3491
    return -1;                                  // key not found; ok
 
3492
  }
 
3493
  /*
 
3494
    Locking reads can legally return also these errors, do not
 
3495
    print them to the .err log
 
3496
  */
 
3497
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
 
3498
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
 
3499
                    error, s->path.str);
 
3500
  file->print_error(error,MYF(0));
 
3501
 
 
3502
  return 1;
 
3503
}
 
3504
 
 
3505
 
 
3506
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
 
3507
{
 
3508
  used_fields= 0;
 
3509
  const_table= 0;
 
3510
  null_row= 0;
 
3511
  status= STATUS_NO_RECORD;
 
3512
  maybe_null= table_list->outer_join;
 
3513
  TableList *embedding= table_list->embedding;
 
3514
  while (!maybe_null && embedding)
 
3515
  {
 
3516
    maybe_null= embedding->outer_join;
 
3517
    embedding= embedding->embedding;
 
3518
  }
 
3519
  tablenr= table_number;
 
3520
  map= (table_map) 1 << table_number;
 
3521
  force_index= table_list->force_index;
 
3522
  covering_keys= s->keys_for_keyread;
 
3523
  merge_keys.reset();
 
3524
}
 
3525
 
 
3526
Field *Table::find_field_in_table_sef(const char *name)
 
3527
{
 
3528
  Field **field_ptr;
 
3529
  if (s->name_hash.records)
 
3530
  {
 
3531
    field_ptr= (Field**)hash_search(&s->name_hash,(unsigned char*) name,
 
3532
                                    strlen(name));
 
3533
    if (field_ptr)
 
3534
    {
 
3535
      /*
 
3536
        field_ptr points to field in TableShare. Convert it to the matching
 
3537
        field in table
 
3538
      */
 
3539
      field_ptr= (field + (field_ptr - s->field));
 
3540
    }
 
3541
  }
 
3542
  else
 
3543
  {
 
3544
    if (!(field_ptr= field))
 
3545
      return (Field *)0;
 
3546
    for (; *field_ptr; ++field_ptr)
 
3547
      if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
 
3548
        break;
 
3549
  }
 
3550
  if (field_ptr)
 
3551
    return *field_ptr;
 
3552
  else
 
3553
    return (Field *)0;
 
3554
}
 
3555
 
 
3556
 
 
3557
/*
 
3558
  Used by ALTER Table when the table is a temporary one. It changes something
 
3559
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old
 
3560
  name).
 
3561
  Prepares a table cache key, which is the concatenation of db, table_name and
 
3562
  session->slave_proxy_id, separated by '\0'.
 
3563
*/
 
3564
 
 
3565
bool Table::rename_temporary_table(const char *db, const char *table_name)
 
3566
{
 
3567
  char *key;
 
3568
  uint32_t key_length;
 
3569
  TableShare *share= s;
 
3570
 
 
3571
  if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
 
3572
    return true;
 
3573
 
 
3574
  key_length= TableShare::createKey(key, db, table_name);
 
3575
  share->set_table_cache_key(key, key_length);
 
3576
 
 
3577
  return false;
 
3578
}
3582
3579
 
3583
3580
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
3584
3581
template class List<String>;