~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Daniel Nichter
  • Date: 2011-10-23 16:01:37 UTC
  • mto: This revision was merged to the branch mainline in revision 2448.
  • Revision ID: daniel@percona.com-20111023160137-7ac3blgz8z4tf8za
Add Administration Getting Started and Logging.  Capitalize SQL clause keywords.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
 
17
17
/* Some general useful functions */
18
18
 
19
 
#include <drizzled/server_includes.h>
 
19
#include <config.h>
 
20
 
 
21
#include <float.h>
 
22
#include <fcntl.h>
 
23
 
 
24
#include <string>
 
25
#include <vector>
 
26
#include <algorithm>
 
27
 
20
28
#include <drizzled/error.h>
21
29
#include <drizzled/gettext.h>
22
30
 
23
 
#include <drizzled/tmp_table.h>
24
 
#include <drizzled/sj_tmp_table.h>
 
31
#include <drizzled/plugin/transactional_storage_engine.h>
 
32
#include <drizzled/plugin/authorization.h>
25
33
#include <drizzled/nested_join.h>
26
 
#include <drizzled/data_home.h>
27
34
#include <drizzled/sql_parse.h>
28
35
#include <drizzled/item/sum.h>
29
 
#include <drizzled/virtual_column_info.h>
30
36
#include <drizzled/table_list.h>
31
37
#include <drizzled/session.h>
32
38
#include <drizzled/sql_base.h>
 
39
#include <drizzled/sql_select.h>
33
40
#include <drizzled/field/blob.h>
34
41
#include <drizzled/field/varstring.h>
35
42
#include <drizzled/field/double.h>
36
 
#include <string>
 
43
#include <drizzled/message/table.pb.h>
 
44
#include <drizzled/sql_table.h>
 
45
#include <drizzled/charset.h>
 
46
#include <drizzled/internal/m_string.h>
 
47
#include <plugin/myisam/myisam.h>
 
48
#include <drizzled/plugin/storage_engine.h>
 
49
#include <drizzled/item/string.h>
 
50
#include <drizzled/item/int.h>
 
51
#include <drizzled/item/decimal.h>
 
52
#include <drizzled/item/float.h>
 
53
#include <drizzled/item/null.h>
 
54
#include <drizzled/temporal.h>
 
55
#include <drizzled/table/singular.h>
 
56
#include <drizzled/table_proto.h>
 
57
#include <drizzled/typelib.h>
 
58
#include <drizzled/sql_lex.h>
 
59
#include <drizzled/statistics_variables.h>
 
60
#include <drizzled/system_variables.h>
 
61
#include <drizzled/open_tables_state.h>
37
62
 
38
63
using namespace std;
39
64
 
40
 
/* Keyword for parsing virtual column functions */
41
 
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
42
 
 
43
 
/* Functions defined in this file */
44
 
 
45
 
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
46
 
                      myf errortype, int errarg);
47
 
static int open_binary_frm(Session *session, TABLE_SHARE *share,
48
 
                           unsigned char *head, File file);
49
 
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
50
 
                              uint32_t types, char **names);
51
 
static uint32_t find_field(Field **fields, unsigned char *record,
52
 
                           uint32_t start, uint32_t length);
 
65
namespace drizzled {
 
66
 
 
67
extern plugin::StorageEngine *heap_engine;
 
68
extern plugin::StorageEngine *myisam_engine;
 
69
 
 
70
/* Functions defined in this cursor */
53
71
 
54
72
/*************************************************************************/
55
73
 
56
 
/* Get column name from column hash */
57
 
 
58
 
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
59
 
{
60
 
  *length= (uint) strlen((*buff)->field_name);
61
 
  return (unsigned char*) (*buff)->field_name;
62
 
}
63
 
 
64
 
 
65
 
/*
66
 
  Returns pointer to '.frm' extension of the file name.
67
 
 
68
 
  SYNOPSIS
69
 
    fn_rext()
70
 
    name       file name
71
 
 
72
 
  DESCRIPTION
73
 
    Checks file name part starting with the rightmost '.' character,
74
 
    and returns it if it is equal to '.frm'. 
75
 
 
76
 
  TODO
77
 
    It is a good idea to get rid of this function modifying the code
78
 
    to garantee that the functions presently calling fn_rext() always
79
 
    get arguments in the same format: either with '.frm' or without '.frm'.
80
 
 
81
 
  RETURN VALUES
82
 
    Pointer to the '.frm' extension. If there is no extension,
83
 
    or extension is not '.frm', pointer at the end of file name.
84
 
*/
85
 
 
86
 
char *fn_rext(char *name)
87
 
{
88
 
  char *res= strrchr(name, '.');
89
 
  if (res && !strcmp(res, reg_ext))
90
 
    return res;
91
 
  return name + strlen(name);
92
 
}
93
 
 
94
 
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
95
 
{
96
 
  assert(db != NULL);
97
 
  assert(name != NULL);
98
 
 
99
 
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
100
 
      (my_strcasecmp(system_charset_info,
101
 
                    INFORMATION_SCHEMA_NAME.c_str(),
102
 
                    db->str) == 0))
103
 
  {
104
 
    return TABLE_CATEGORY_INFORMATION;
105
 
  }
106
 
 
107
 
  return TABLE_CATEGORY_USER;
108
 
}
109
 
 
110
 
 
111
 
/*
112
 
  Allocate a setup TABLE_SHARE structure
113
 
 
114
 
  SYNOPSIS
115
 
    alloc_table_share()
116
 
    TableList           Take database and table name from there
117
 
    key                 Table cache key (db \0 table_name \0...)
118
 
    key_length          Length of key
119
 
 
120
 
  RETURN
121
 
    0  Error (out of memory)
122
 
    #  Share
123
 
*/
124
 
 
125
 
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
126
 
                               uint32_t key_length)
127
 
{
128
 
  MEM_ROOT mem_root;
129
 
  TABLE_SHARE *share;
130
 
  char *key_buff, *path_buff;
131
 
  char path[FN_REFLEN];
132
 
  uint32_t path_length;
133
 
 
134
 
  path_length= build_table_filename(path, sizeof(path) - 1,
135
 
                                    table_list->db,
136
 
                                    table_list->table_name, "", 0);
137
 
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
138
 
  if (multi_alloc_root(&mem_root,
139
 
                       &share, sizeof(*share),
140
 
                       &key_buff, key_length,
141
 
                       &path_buff, path_length + 1,
142
 
                       NULL))
143
 
  {
144
 
    memset(share, 0, sizeof(*share));
145
 
 
146
 
    share->set_table_cache_key(key_buff, key, key_length);
147
 
 
148
 
    share->path.str= path_buff;
149
 
    share->path.length= path_length;
150
 
    my_stpcpy(share->path.str, path);
151
 
    share->normalized_path.str=    share->path.str;
152
 
    share->normalized_path.length= path_length;
153
 
 
154
 
    share->version=       refresh_version;
155
 
 
156
 
    /*
157
 
      This constant is used to mark that no table map version has been
158
 
      assigned.  No arithmetic is done on the value: it will be
159
 
      overwritten with a value taken from DRIZZLE_BIN_LOG.
160
 
    */
161
 
    share->table_map_version= UINT64_MAX;
162
 
 
163
 
    /*
164
 
      Since alloc_table_share() can be called without any locking (for
165
 
      example, ha_create_table... functions), we do not assign a table
166
 
      map id here.  Instead we assign a value that is not used
167
 
      elsewhere, and then assign a table map id inside open_table()
168
 
      under the protection of the LOCK_open mutex.
169
 
    */
170
 
    share->table_map_id= UINT32_MAX;
171
 
    share->cached_row_logging_check= -1;
172
 
 
173
 
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
174
 
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
175
 
    pthread_cond_init(&share->cond, NULL);
176
 
  }
177
 
  return(share);
178
 
}
179
 
 
180
 
 
181
 
/*
182
 
  Initialize share for temporary tables
183
 
 
184
 
  SYNOPSIS
185
 
    init_tmp_table_share()
186
 
    session         thread handle
187
 
    share       Share to fill
188
 
    key         Table_cache_key, as generated from create_table_def_key.
189
 
                must start with db name.    
190
 
    key_length  Length of key
191
 
    table_name  Table name
192
 
    path        Path to file (possible in lower case) without .frm
193
 
 
194
 
  NOTES
195
 
    This is different from alloc_table_share() because temporary tables
196
 
    don't have to be shared between threads or put into the table def
197
 
    cache, so we can do some things notable simpler and faster
198
 
 
199
 
    If table is not put in session->temporary_tables (happens only when
200
 
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
201
 
    use key_length= 0 as neither table_cache_key or key_length will be used).
202
 
*/
203
 
 
204
 
void init_tmp_table_share(Session *session, TABLE_SHARE *share, const char *key,
205
 
                          uint32_t key_length, const char *table_name,
206
 
                          const char *path)
207
 
{
208
 
 
209
 
  memset(share, 0, sizeof(*share));
210
 
  init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
211
 
  share->table_category=         TABLE_CATEGORY_TEMPORARY;
212
 
  share->tmp_table=              INTERNAL_TMP_TABLE;
213
 
  share->db.str=                 (char*) key;
214
 
  share->db.length=              strlen(key);
215
 
  share->table_cache_key.str=    (char*) key;
216
 
  share->table_cache_key.length= key_length;
217
 
  share->table_name.str=         (char*) table_name;
218
 
  share->table_name.length=      strlen(table_name);
219
 
  share->path.str=               (char*) path;
220
 
  share->normalized_path.str=    (char*) path;
221
 
  share->path.length= share->normalized_path.length= strlen(path);
222
 
 
223
 
  /*
224
 
    Temporary tables are not replicated, but we set up these fields
225
 
    anyway to be able to catch errors.
226
 
   */
227
 
  share->table_map_version= ~(uint64_t)0;
228
 
  share->cached_row_logging_check= -1;
229
 
 
230
 
  /*
231
 
    table_map_id is also used for MERGE tables to suppress repeated
232
 
    compatibility checks.
233
 
  */
234
 
  share->table_map_id= (ulong) session->query_id;
235
 
 
236
 
  return;
237
 
}
238
 
 
239
 
 
240
 
/*
241
 
  Free table share and memory used by it
242
 
 
243
 
  SYNOPSIS
244
 
    free_table_share()
245
 
    share               Table share
246
 
 
247
 
  NOTES
248
 
    share->mutex must be locked when we come here if it's not a temp table
249
 
*/
250
 
 
251
 
void free_table_share(TABLE_SHARE *share)
252
 
{
253
 
  MEM_ROOT mem_root;
254
 
  assert(share->ref_count == 0);
255
 
 
256
 
  /*
257
 
    If someone is waiting for this to be deleted, inform it about this.
258
 
    Don't do a delete until we know that no one is refering to this anymore.
259
 
  */
260
 
  if (share->tmp_table == NO_TMP_TABLE)
261
 
  {
262
 
    /* share->mutex is locked in release_table_share() */
263
 
    while (share->waiting_on_cond)
264
 
    {
265
 
      pthread_cond_broadcast(&share->cond);
266
 
      pthread_cond_wait(&share->cond, &share->mutex);
267
 
    }
268
 
    /* No thread refers to this anymore */
269
 
    pthread_mutex_unlock(&share->mutex);
270
 
    pthread_mutex_destroy(&share->mutex);
271
 
    pthread_cond_destroy(&share->cond);
272
 
  }
273
 
  hash_free(&share->name_hash);
274
 
  
275
 
  plugin_unlock(NULL, share->db_plugin);
276
 
  share->db_plugin= NULL;
277
 
 
278
 
  /* We must copy mem_root from share because share is allocated through it */
279
 
  memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
280
 
  free_root(&mem_root, MYF(0));                 // Free's share
281
 
  return;
282
 
}
283
 
 
284
 
/*
285
 
  Read table definition from a binary / text based .frm file
286
 
  
287
 
  SYNOPSIS
288
 
  open_table_def()
289
 
  session               Thread handler
290
 
  share         Fill this with table definition
291
 
  db_flags      Bit mask of the following flags: OPEN_VIEW
292
 
 
293
 
  NOTES
294
 
    This function is called when the table definition is not cached in
295
 
    table_def_cache
296
 
    The data is returned in 'share', which is alloced by
297
 
    alloc_table_share().. The code assumes that share is initialized.
298
 
 
299
 
  RETURN VALUES
300
 
   0    ok
301
 
   1    Error (see open_table_error)
302
 
   2    Error (see open_table_error)
303
 
   3    Wrong data in .frm file
304
 
   4    Error (see open_table_error)
305
 
   5    Error (see open_table_error: charset unavailable)
306
 
   6    Unknown .frm version
307
 
*/
308
 
 
309
 
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
310
 
{
311
 
  int error, table_type;
312
 
  bool error_given;
313
 
  File file;
314
 
  unsigned char head[64], *disk_buff;
315
 
  string        path("");
316
 
 
317
 
  MEM_ROOT **root_ptr, *old_root;
318
 
 
319
 
  error= 1;
320
 
  error_given= 0;
321
 
  disk_buff= NULL;
322
 
 
323
 
  path.reserve(FN_REFLEN);
324
 
  path.append(share->normalized_path.str);
325
 
  path.append(reg_ext);
326
 
  if ((file= open(path.c_str(), O_RDONLY)) < 0)
327
 
  {
328
 
    /*
329
 
      We don't try to open 5.0 unencoded name, if
330
 
      - non-encoded name contains '@' signs, 
331
 
        because '@' can be misinterpreted.
332
 
        It is not clear if '@' is escape character in 5.1,
333
 
        or a normal character in 5.0.
334
 
        
335
 
      - non-encoded db or table name contain "#mysql50#" prefix.
336
 
        This kind of tables must have been opened only by the
337
 
        open() above.
338
 
    */
339
 
    if (strchr(share->table_name.str, '@') ||
340
 
        !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
341
 
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
342
 
        !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
343
 
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
344
 
      goto err_not_open;
345
 
 
346
 
    /* Try unencoded 5.0 name */
347
 
    size_t length;
348
 
    char unpacked_path[FN_REFLEN];
349
 
    path.clear();
350
 
    path.append(drizzle_data_home);
351
 
    path.append("/");
352
 
    path.append(share->db.str);
353
 
    path.append("/");
354
 
    path.append(share->table_name.str);
355
 
    path.append(reg_ext);
356
 
    length= unpack_filename(unpacked_path, path.c_str()) - reg_ext_length;
357
 
    /*
358
 
      The following is a safety test and should never fail
359
 
      as the old file name should never be longer than the new one.
360
 
    */
361
 
    assert(length <= share->normalized_path.length);
362
 
    /*
363
 
      If the old and the new names have the same length,
364
 
      then table name does not have tricky characters,
365
 
      so no need to check the old file name.
366
 
    */
367
 
    if (length == share->normalized_path.length ||
368
 
        ((file= open(unpacked_path, O_RDONLY)) < 0))
369
 
      goto err_not_open;
370
 
 
371
 
    /* Unencoded 5.0 table name found */
372
 
    unpacked_path[length]= '\0'; // Remove .frm extension
373
 
    my_stpcpy(share->normalized_path.str, unpacked_path);
374
 
    share->normalized_path.length= length;
375
 
  }
376
 
 
377
 
  error= 4;
378
 
  if (my_read(file, head, 64, MYF(MY_NABP)))
379
 
    goto err;
380
 
 
381
 
  if (head[0] == (unsigned char) 254 && head[1] == 1)
382
 
  {
383
 
    if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
384
 
        (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
385
 
    {
386
 
      table_type= 1;
387
 
    }
388
 
    else
389
 
    {
390
 
      error= 6;                                 // Unkown .frm version
391
 
      goto err;
392
 
    }
393
 
  }
394
 
  else
395
 
    goto err;
396
 
 
397
 
  /* No handling of text based files yet */
398
 
  if (table_type == 1)
399
 
  {
400
 
    root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
401
 
    old_root= *root_ptr;
402
 
    *root_ptr= &share->mem_root;
403
 
    error= open_binary_frm(session, share, head, file);
404
 
    *root_ptr= old_root;
405
 
    error_given= 1;
406
 
  }
407
 
  else
408
 
    assert(1);
409
 
 
410
 
  share->table_category= get_table_category(& share->db, & share->table_name);
411
 
 
412
 
  if (!error)
413
 
    session->status_var.opened_shares++;
414
 
 
415
 
err:
416
 
  my_close(file, MYF(MY_WME));
417
 
 
418
 
err_not_open:
419
 
  if (error && !error_given)
420
 
  {
421
 
    share->error= error;
422
 
    open_table_error(share, error, (share->open_errno= my_errno), 0);
423
 
  }
424
 
 
425
 
  return(error);
426
 
}
427
 
 
428
 
 
429
 
/*
430
 
  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
431
 
*/
432
 
 
433
 
static int open_binary_frm(Session *session, TABLE_SHARE *share, unsigned char *head,
434
 
                           File file)
435
 
{
436
 
  int error, errarg= 0;
437
 
  uint32_t new_frm_ver, field_pack_length, new_field_pack_flag;
438
 
  uint32_t interval_count, interval_parts, read_length, int_length;
439
 
  uint32_t db_create_options, keys, key_parts, n_length;
440
 
  uint32_t key_info_length, com_length, null_bit_pos=0;
441
 
  uint32_t vcol_screen_length;
442
 
  uint32_t extra_rec_buf_length;
443
 
  uint32_t i,j;
444
 
  bool use_hash;
445
 
  unsigned char forminfo[288];
446
 
  char *keynames, *names, *comment_pos, *vcol_screen_pos;
447
 
  unsigned char *record;
448
 
  unsigned char *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
449
 
  ulong pos, record_offset, *rec_per_key, rec_buff_length;
450
 
  handler *handler_file= 0;
451
 
  KEY   *keyinfo;
452
 
  KEY_PART_INFO *key_part;
453
 
  Field  **field_ptr, *reg_field;
454
 
  const char **interval_array;
455
 
  enum legacy_db_type legacy_db_type;
456
 
  my_bitmap_map *bitmaps;
457
 
  unsigned char *buff= 0;
458
 
  unsigned char *field_extra_info= 0;
459
 
 
460
 
  new_field_pack_flag= head[27];
461
 
  new_frm_ver= (head[2] - FRM_VER);
462
 
  field_pack_length= new_frm_ver < 2 ? 11 : 17;
463
 
  disk_buff= 0;
464
 
 
465
 
  error= 3;
466
 
  if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
467
 
    goto err;                                   /* purecov: inspected */
468
 
  my_seek(file,pos,MY_SEEK_SET,MYF(0));
469
 
  if (my_read(file,forminfo,288,MYF(MY_NABP)))
470
 
    goto err;
471
 
 
472
 
  legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
473
 
  assert(share->db_plugin == NULL);
474
 
  /*
475
 
    if the storage engine is dynamic, no point in resolving it by its
476
 
    dynamically allocated legacy_db_type. We will resolve it later by name.
477
 
  */
478
 
  if (legacy_db_type > DB_TYPE_UNKNOWN && 
479
 
      legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
480
 
    share->db_plugin= ha_lock_engine(NULL, 
481
 
                                     ha_checktype(session, legacy_db_type, 0, 0));
482
 
  share->db_create_options= db_create_options= uint2korr(head+30);
483
 
  share->db_options_in_use= share->db_create_options;
484
 
  share->mysql_version= uint4korr(head+51);
485
 
  share->null_field_first= 0;
486
 
  if (!head[32])                                // New frm file in 3.23
487
 
  {
488
 
    share->avg_row_length= uint4korr(head+34);
489
 
    share->transactional= (ha_choice) (head[39] & 3);
490
 
    share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
491
 
    share->row_type= (row_type) head[40];
492
 
    share->block_size= uint4korr(head+43);
493
 
    share->table_charset= get_charset((uint) head[38],MYF(0));
494
 
    share->null_field_first= 1;
495
 
  }
496
 
  if (!share->table_charset)
497
 
  {
498
 
    /* unknown charset in head[38] or pre-3.23 frm */
499
 
    if (use_mb(default_charset_info))
500
 
    {
501
 
      /* Warn that we may be changing the size of character columns */
502
 
      sql_print_warning(_("'%s' had no or invalid character set, "
503
 
                        "and default character set is multi-byte, "
504
 
                        "so character column sizes may have changed"),
505
 
                        share->path.str);
506
 
    }
507
 
    share->table_charset= default_charset_info;
508
 
  }
509
 
  share->db_record_offset= 1;
510
 
  if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
511
 
    share->blob_ptr_size= portable_sizeof_char_ptr;
512
 
  /* Set temporarily a good value for db_low_byte_first */
513
 
  share->db_low_byte_first= true;
514
 
  error=4;
515
 
  share->max_rows= uint4korr(head+18);
516
 
  share->min_rows= uint4korr(head+22);
517
 
 
518
 
  /* Read keyinformation */
519
 
  key_info_length= (uint) uint2korr(head+28);
520
 
  my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0));
521
 
  if (read_string(file,(unsigned char**) &disk_buff,key_info_length))
522
 
    goto err;                                   /* purecov: inspected */
523
 
  if (disk_buff[0] & 0x80)
524
 
  {
525
 
    share->keys=      keys=      (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
526
 
    share->key_parts= key_parts= uint2korr(disk_buff+2);
527
 
  }
528
 
  else
529
 
  {
530
 
    share->keys=      keys=      disk_buff[0];
531
 
    share->key_parts= key_parts= disk_buff[1];
532
 
  }
533
 
  share->keys_for_keyread.init(0);
534
 
  share->keys_in_use.init(keys);
535
 
 
536
 
  n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
537
 
  if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
538
 
                                    n_length + uint2korr(disk_buff+4))))
539
 
    goto err;                                   /* purecov: inspected */
540
 
  memset(keyinfo, 0, n_length);
541
 
  share->key_info= keyinfo;
542
 
  key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
543
 
  strpos=disk_buff+6;
544
 
 
545
 
  if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
546
 
                                         sizeof(ulong*)*key_parts)))
547
 
    goto err;
548
 
 
549
 
  for (i=0 ; i < keys ; i++, keyinfo++)
550
 
  {
551
 
    keyinfo->table= 0;                           // Updated in open_frm
552
 
    if (new_frm_ver >= 3)
553
 
    {
554
 
      keyinfo->flags=      (uint) uint2korr(strpos) ^ HA_NOSAME;
555
 
      keyinfo->key_length= (uint) uint2korr(strpos+2);
556
 
      keyinfo->key_parts=  (uint) strpos[4];
557
 
      keyinfo->algorithm=  (enum ha_key_alg) strpos[5];
558
 
      keyinfo->block_size= uint2korr(strpos+6);
559
 
      strpos+=8;
560
 
    }
561
 
 
562
 
    keyinfo->key_part=   key_part;
563
 
    keyinfo->rec_per_key= rec_per_key;
564
 
    for (j=keyinfo->key_parts ; j-- ; key_part++)
565
 
    {
566
 
      *rec_per_key++=0;
567
 
      key_part->fieldnr=        (uint16_t) (uint2korr(strpos) & FIELD_NR_MASK);
568
 
      key_part->offset= (uint) uint2korr(strpos+2)-1;
569
 
      key_part->key_type=       (uint) uint2korr(strpos+5);
570
 
      // key_part->field=       (Field*) 0;     // Will be fixed later
571
 
      if (new_frm_ver >= 1)
572
 
      {
573
 
        key_part->key_part_flag= *(strpos+4);
574
 
        key_part->length=       (uint) uint2korr(strpos+7);
575
 
        strpos+=9;
576
 
      }
577
 
      else
578
 
      {
579
 
        key_part->length=       *(strpos+4);
580
 
        key_part->key_part_flag=0;
581
 
        if (key_part->length > 128)
582
 
        {
583
 
          key_part->length&=127;                /* purecov: inspected */
584
 
          key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
585
 
        }
586
 
        strpos+=7;
587
 
      }
588
 
      key_part->store_length=key_part->length;
589
 
    }
590
 
  }
591
 
  keynames=(char*) key_part;
592
 
  strpos+= (my_stpcpy(keynames, (char *) strpos) - keynames)+1;
593
 
 
594
 
  //reading index comments
595
 
  for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
596
 
  {
597
 
    if (keyinfo->flags & HA_USES_COMMENT)
598
 
    {
599
 
      keyinfo->comment.length= uint2korr(strpos);
600
 
      keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
601
 
                                         keyinfo->comment.length);
602
 
      strpos+= 2 + keyinfo->comment.length;
603
 
    } 
604
 
    assert(test(keyinfo->flags & HA_USES_COMMENT) == 
605
 
               (keyinfo->comment.length > 0));
606
 
  }
607
 
 
608
 
  share->reclength = uint2korr((head+16));
609
 
  share->stored_rec_length= share->reclength;
610
 
 
611
 
  record_offset= (ulong) (uint2korr(head+6)+
612
 
                          ((uint2korr(head+14) == 0xffff ?
613
 
                            uint4korr(head+47) : uint2korr(head+14))));
614
 
 
615
 
  if ((n_length= uint4korr(head+55)))
616
 
  {
617
 
    /* Read extra data segment */
618
 
    unsigned char *next_chunk, *buff_end;
619
 
    if (!(next_chunk= buff= (unsigned char*) my_malloc(n_length, MYF(MY_WME))))
620
 
      goto err;
621
 
    if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
622
 
    {
623
 
      goto err;
624
 
    }
625
 
    share->connect_string.length= uint2korr(buff);
626
 
    if (!(share->connect_string.str= strmake_root(&share->mem_root,
627
 
                                                  (char*) next_chunk + 2,
628
 
                                                  share->connect_string.
629
 
                                                  length)))
630
 
    {
631
 
      goto err;
632
 
    }
633
 
    next_chunk+= share->connect_string.length + 2;
634
 
    buff_end= buff + n_length;
635
 
    if (next_chunk + 2 < buff_end)
636
 
    {
637
 
      uint32_t str_db_type_length= uint2korr(next_chunk);
638
 
      LEX_STRING name;
639
 
      name.str= (char*) next_chunk + 2;
640
 
      name.length= str_db_type_length;
641
 
 
642
 
      plugin_ref tmp_plugin= ha_resolve_by_name(session, &name);
643
 
      if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
644
 
      {
645
 
        if (legacy_db_type > DB_TYPE_UNKNOWN &&
646
 
            legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
647
 
            legacy_db_type != ha_legacy_type(
648
 
                plugin_data(tmp_plugin, handlerton *)))
649
 
        {
650
 
          /* bad file, legacy_db_type did not match the name */
651
 
          free(buff);
652
 
          goto err;
653
 
        }
654
 
        /*
655
 
          tmp_plugin is locked with a local lock.
656
 
          we unlock the old value of share->db_plugin before
657
 
          replacing it with a globally locked version of tmp_plugin
658
 
        */
659
 
        plugin_unlock(NULL, share->db_plugin);
660
 
        share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
661
 
      }
662
 
      else if (!tmp_plugin)
663
 
      {
664
 
        /* purecov: begin inspected */
665
 
        error= 8;
666
 
        my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
667
 
        free(buff);
668
 
        goto err;
669
 
        /* purecov: end */
670
 
      }
671
 
      next_chunk+= str_db_type_length + 2;
672
 
    }
673
 
    if (share->mysql_version >= 50110)
674
 
    {
675
 
      /* New auto_partitioned indicator introduced in 5.1.11 */
676
 
      next_chunk++;
677
 
    }
678
 
    if (forminfo[46] == (unsigned char)255)
679
 
    {
680
 
      //reading long table comment
681
 
      if (next_chunk + 2 > buff_end)
682
 
      {
683
 
          free(buff);
684
 
          goto err;
685
 
      }
686
 
      share->comment.length = uint2korr(next_chunk);
687
 
      if (! (share->comment.str= strmake_root(&share->mem_root,
688
 
                               (char*)next_chunk + 2, share->comment.length)))
689
 
      {
690
 
          free(buff);
691
 
          goto err;
692
 
      }
693
 
      next_chunk+= 2 + share->comment.length;
694
 
    }
695
 
    assert(next_chunk <= buff_end);
696
 
    if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
697
 
    {
698
 
      /*
699
 
       New frm format in mysql_version 5.2.5 (originally in
700
 
       mysql-5.1.22-ndb-6.2.5)
701
 
       New column properties added:
702
 
       COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
703
 
       TABLESPACE name is now stored in frm
704
 
      */
705
 
      if (next_chunk >= buff_end)
706
 
      {
707
 
        if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
708
 
        {
709
 
          goto err;
710
 
        }
711
 
      }
712
 
      else
713
 
      {
714
 
        const uint32_t format_section_header_size= 8;
715
 
        uint32_t format_section_len= uint2korr(next_chunk+0);
716
 
 
717
 
        field_extra_info= next_chunk + format_section_header_size + 1;
718
 
        next_chunk+= format_section_len;
719
 
      }
720
 
    }
721
 
    assert (next_chunk <= buff_end);
722
 
    if (next_chunk > buff_end)
723
 
    {
724
 
      goto err;
725
 
    }
726
 
  }
727
 
  share->key_block_size= uint2korr(head+62);
728
 
 
729
 
  error=4;
730
 
  extra_rec_buf_length= uint2korr(head+59);
731
 
  rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
732
 
  share->rec_buff_length= rec_buff_length;
733
 
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
734
 
                                     rec_buff_length)))
735
 
    goto err;                                   /* purecov: inspected */
736
 
  share->default_values= record;
737
 
  if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
738
 
    goto err;                                   /* purecov: inspected */
739
 
 
740
 
  my_seek(file,pos+288,MY_SEEK_SET,MYF(0));
741
 
 
742
 
  share->fields= uint2korr(forminfo+258);
743
 
  pos= uint2korr(forminfo+260);                 /* Length of all screens */
744
 
  n_length= uint2korr(forminfo+268);
745
 
  interval_count= uint2korr(forminfo+270);
746
 
  interval_parts= uint2korr(forminfo+272);
747
 
  int_length= uint2korr(forminfo+274);
748
 
  share->null_fields= uint2korr(forminfo+282);
749
 
  com_length= uint2korr(forminfo+284);
750
 
  vcol_screen_length= uint2korr(forminfo+286);
751
 
  share->vfields= 0;
752
 
  share->stored_fields= share->fields;
753
 
  if (forminfo[46] != (unsigned char)255)
754
 
  {
755
 
    share->comment.length=  (int) (forminfo[46]);
756
 
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
757
 
                                     share->comment.length);
758
 
  }
759
 
 
760
 
 
761
 
  if (!(field_ptr = (Field **)
762
 
        alloc_root(&share->mem_root,
763
 
                   (uint) ((share->fields+1)*sizeof(Field*)+
764
 
                           interval_count*sizeof(TYPELIB)+
765
 
                           (share->fields+interval_parts+
766
 
                            keys+3)*sizeof(char *)+
767
 
                           (n_length+int_length+com_length+
768
 
                               vcol_screen_length)))))
769
 
    goto err;                                   /* purecov: inspected */
770
 
 
771
 
  share->field= field_ptr;
772
 
  read_length=(uint) (share->fields * field_pack_length +
773
 
                      pos+ (uint) (n_length+int_length+com_length+
774
 
                                   vcol_screen_length));
775
 
  if (read_string(file,(unsigned char**) &disk_buff,read_length))
776
 
    goto err;                                   /* purecov: inspected */
777
 
  strpos= disk_buff+pos;
778
 
 
779
 
  share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
780
 
  interval_array= (const char **) (share->intervals+interval_count);
781
 
  names= (char*) (interval_array+share->fields+interval_parts+keys+3);
782
 
  if (!interval_count)
783
 
    share->intervals= 0;                        // For better debugging
784
 
  memcpy(names, strpos+(share->fields*field_pack_length),
785
 
         (uint) (n_length+int_length));
786
 
  comment_pos= names+(n_length+int_length);
787
 
  memcpy(comment_pos, disk_buff+read_length-com_length-vcol_screen_length, 
788
 
         com_length);
789
 
  vcol_screen_pos= names+(n_length+int_length+com_length);
790
 
  memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length, 
791
 
         vcol_screen_length);
792
 
 
793
 
  fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
794
 
  if (share->fieldnames.count != share->fields)
795
 
    goto err;
796
 
  fix_type_pointers(&interval_array, share->intervals, interval_count,
797
 
                    &names);
798
 
 
799
 
  {
800
 
    /* Set ENUM and SET lengths */
801
 
    TYPELIB *interval;
802
 
    for (interval= share->intervals;
803
 
         interval < share->intervals + interval_count;
804
 
         interval++)
805
 
    {
806
 
      uint32_t count= (uint) (interval->count + 1) * sizeof(uint);
807
 
      if (!(interval->type_lengths= (uint32_t *) alloc_root(&share->mem_root,
808
 
                                                        count)))
809
 
        goto err;
810
 
      for (count= 0; count < interval->count; count++)
811
 
      {
812
 
        char *val= (char*) interval->type_names[count];
813
 
        interval->type_lengths[count]= strlen(val);
814
 
      }
815
 
      interval->type_lengths[count]= 0;
816
 
    }
817
 
  }
818
 
 
819
 
  if (keynames)
820
 
    fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
821
 
 
822
 
 /* Allocate handler */
823
 
  if (!(handler_file= get_new_handler(share, session->mem_root,
824
 
                                      share->db_type())))
825
 
    goto err;
826
 
 
827
 
  record= share->default_values-1;              /* Fieldstart = 1 */
828
 
  if (share->null_field_first)
829
 
  {
830
 
    null_flags= null_pos= (unsigned char*) record+1;
831
 
    null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
832
 
    /*
833
 
      null_bytes below is only correct under the condition that
834
 
      there are no bit fields.  Correct values is set below after the
835
 
      table struct is initialized
836
 
    */
837
 
    share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
838
 
  }
839
 
 
840
 
  use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
841
 
  if (use_hash)
842
 
    use_hash= !hash_init(&share->name_hash,
843
 
                         system_charset_info,
844
 
                         share->fields,0,0,
845
 
                         (hash_get_key) get_field_name,0,0);
846
 
 
847
 
  for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
848
 
  {
849
 
    uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
850
 
    uint32_t vcol_info_length=0;
851
 
    enum_field_types field_type;
852
 
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
853
 
    const CHARSET_INFO *charset= NULL;
854
 
    LEX_STRING comment;
855
 
    virtual_column_info *vcol_info= NULL;
856
 
    bool fld_is_stored= true;
857
 
 
858
 
    if (field_extra_info)
859
 
    {
860
 
      char tmp= field_extra_info[i];
861
 
      column_format= (enum column_format_type)
862
 
                    ((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
863
 
    }
864
 
    if (new_frm_ver >= 3)
865
 
    {
866
 
      /* new frm file in 4.1 */
867
 
      field_length= uint2korr(strpos+3);
868
 
      recpos=       uint3korr(strpos+5);
869
 
      pack_flag=    uint2korr(strpos+8);
870
 
      unireg_type=  (uint) strpos[10];
871
 
      interval_nr=  (uint) strpos[12];
872
 
      uint32_t comment_length=uint2korr(strpos+15);
873
 
      field_type=(enum_field_types) (uint) strpos[13];
874
 
 
875
 
      {
876
 
        if (!strpos[14])
877
 
          charset= &my_charset_bin;
878
 
        else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
879
 
        {
880
 
          error= 5; // Unknown or unavailable charset
881
 
          errarg= (int) strpos[14];
882
 
          goto err;
883
 
        }
884
 
      }
885
 
      if (field_type == DRIZZLE_TYPE_VIRTUAL)
886
 
      {
887
 
        assert(interval_nr); // Expect non-null expression
888
 
        /* 
889
 
          The interval_id byte in the .frm file stores the length of the
890
 
          expression statement for a virtual column.
891
 
        */
892
 
        vcol_info_length= interval_nr;
893
 
        interval_nr= 0;
894
 
      }
895
 
      if (!comment_length)
896
 
      {
897
 
        comment.str= (char*) "";
898
 
        comment.length=0;
899
 
      }
900
 
      else
901
 
      {
902
 
        comment.str=    (char*) comment_pos;
903
 
        comment.length= comment_length;
904
 
        comment_pos+=   comment_length;
905
 
      }
906
 
      if (vcol_info_length)
907
 
      {
908
 
        /*
909
 
          Get virtual column data stored in the .frm file as follows:
910
 
          byte 1      = 1 (always 1 to allow for future extensions)
911
 
          byte 2      = sql_type
912
 
          byte 3      = flags (as of now, 0 - no flags, 1 - field is physically stored)
913
 
          byte 4-...  = virtual column expression (text data)
914
 
        */
915
 
        vcol_info= new virtual_column_info();
916
 
        if ((uint)vcol_screen_pos[0] != 1)
917
 
        {
918
 
          error= 4;
919
 
          goto err;
920
 
        }
921
 
        field_type= (enum_field_types) (unsigned char) vcol_screen_pos[1];
922
 
        fld_is_stored= (bool) (uint) vcol_screen_pos[2];
923
 
        vcol_info->expr_str.str= (char *)memdup_root(&share->mem_root,
924
 
                                                     vcol_screen_pos+
925
 
                                                       (uint)FRM_VCOL_HEADER_SIZE,
926
 
                                                     vcol_info_length-
927
 
                                                       (uint)FRM_VCOL_HEADER_SIZE);
928
 
        vcol_info->expr_str.length= vcol_info_length-(uint)FRM_VCOL_HEADER_SIZE;
929
 
        vcol_screen_pos+= vcol_info_length;
930
 
        share->vfields++;
931
 
      }
932
 
    }
933
 
    else
934
 
    {
935
 
      field_length= (uint) strpos[3];
936
 
      recpos=       uint2korr(strpos+4),
937
 
      pack_flag=    uint2korr(strpos+6);
938
 
      pack_flag&=   ~FIELDFLAG_NO_DEFAULT;     // Safety for old files
939
 
      unireg_type=  (uint) strpos[8];
940
 
      interval_nr=  (uint) strpos[10];
941
 
 
942
 
      /* old frm file */
943
 
      field_type= (enum_field_types) f_packtype(pack_flag);
944
 
      if (f_is_binary(pack_flag))
945
 
      {
946
 
        /*
947
 
          Try to choose the best 4.1 type:
948
 
          - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" 
949
 
            try to find a binary collation for character set.
950
 
          - for other types (e.g. BLOB) just use my_charset_bin. 
951
 
        */
952
 
        if (!f_is_blob(pack_flag))
953
 
        {
954
 
          // 3.23 or 4.0 string
955
 
          if (!(charset= get_charset_by_csname(share->table_charset->csname,
956
 
                                               MY_CS_BINSORT, MYF(0))))
957
 
            charset= &my_charset_bin;
958
 
        }
959
 
        else
960
 
          charset= &my_charset_bin;
961
 
      }
962
 
      else
963
 
        charset= share->table_charset;
964
 
      memset(&comment, 0, sizeof(comment));
965
 
    }
966
 
 
967
 
    if (interval_nr && charset->mbminlen > 1)
968
 
    {
969
 
      /* Unescape UCS2 intervals from HEX notation */
970
 
      TYPELIB *interval= share->intervals + interval_nr - 1;
971
 
      unhex_type2(interval);
972
 
    }
973
 
 
974
 
    *field_ptr= reg_field=
975
 
      make_field(share, record+recpos,
976
 
                 (uint32_t) field_length,
977
 
                 null_pos, null_bit_pos,
978
 
                 pack_flag,
979
 
                 field_type,
980
 
                 charset,
981
 
                 (Field::utype) MTYP_TYPENR(unireg_type),
982
 
                 (interval_nr ?
983
 
                  share->intervals+interval_nr-1 :
984
 
                  (TYPELIB*) 0),
985
 
                 share->fieldnames.type_names[i]);
986
 
    if (!reg_field)                             // Not supported field type
987
 
    {
988
 
      error= 4;
989
 
      goto err;                 /* purecov: inspected */
990
 
    }
991
 
 
992
 
    reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
993
 
    reg_field->field_index= i;
994
 
    reg_field->comment=comment;
995
 
    reg_field->vcol_info= vcol_info;
996
 
    reg_field->is_stored= fld_is_stored;
997
 
    if (!(reg_field->flags & NOT_NULL_FLAG))
998
 
    {
999
 
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
1000
 
        null_pos++;
1001
 
    }
1002
 
    if (f_no_default(pack_flag))
1003
 
      reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
1004
 
 
1005
 
    if (reg_field->unireg_check == Field::NEXT_NUMBER)
1006
 
      share->found_next_number_field= field_ptr;
1007
 
    if (share->timestamp_field == reg_field)
1008
 
      share->timestamp_field_offset= i;
1009
 
 
1010
 
    if (use_hash)
1011
 
      (void) my_hash_insert(&share->name_hash,
1012
 
                            (unsigned char*) field_ptr); // never fail
1013
 
    if (!reg_field->is_stored)
1014
 
    {
1015
 
      share->stored_fields--;
1016
 
      if (share->stored_rec_length>=recpos)
1017
 
        share->stored_rec_length= recpos-1;
1018
 
    }
1019
 
  }
1020
 
  *field_ptr=0;                                 // End marker
1021
 
  /* Sanity checks: */
1022
 
  assert(share->fields>=share->stored_fields);
1023
 
  assert(share->reclength>=share->stored_rec_length);
1024
 
 
1025
 
  /* Fix key->name and key_part->field */
1026
 
  if (key_parts)
1027
 
  {
1028
 
    uint32_t primary_key=(uint) (find_type((char*) "PRIMARY",
1029
 
                                       &share->keynames, 3) - 1);
1030
 
    int64_t ha_option= handler_file->ha_table_flags();
1031
 
    keyinfo= share->key_info;
1032
 
    key_part= keyinfo->key_part;
1033
 
 
1034
 
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1035
 
    {
1036
 
      uint32_t usable_parts= 0;
1037
 
      keyinfo->name=(char*) share->keynames.type_names[key];
1038
 
 
1039
 
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1040
 
      {
1041
 
        /*
1042
 
          If the UNIQUE key doesn't have NULL columns and is not a part key
1043
 
          declare this as a primary key.
1044
 
        */
1045
 
        primary_key=key;
1046
 
        for (i=0 ; i < keyinfo->key_parts ;i++)
1047
 
        {
1048
 
          uint32_t fieldnr= key_part[i].fieldnr;
1049
 
          if (!fieldnr ||
1050
 
              share->field[fieldnr-1]->null_ptr ||
1051
 
              share->field[fieldnr-1]->key_length() !=
1052
 
              key_part[i].length)
1053
 
          {
1054
 
            primary_key=MAX_KEY;                // Can't be used
1055
 
            break;
1056
 
          }
1057
 
        }
1058
 
      }
1059
 
 
1060
 
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1061
 
      {
1062
 
        Field *field;
1063
 
        if (new_field_pack_flag <= 1)
1064
 
          key_part->fieldnr= (uint16_t) find_field(share->field,
1065
 
                                                 share->default_values,
1066
 
                                                 (uint) key_part->offset,
1067
 
                                                 (uint) key_part->length);
1068
 
        if (!key_part->fieldnr)
1069
 
        {
1070
 
          error= 4;                             // Wrong file
1071
 
          goto err;
1072
 
        }
1073
 
        field= key_part->field= share->field[key_part->fieldnr-1];
1074
 
        key_part->type= field->key_type();
1075
 
        if (field->null_ptr)
1076
 
        {
1077
 
          key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
1078
 
                                        share->default_values);
1079
 
          key_part->null_bit= field->null_bit;
1080
 
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1081
 
          keyinfo->flags|=HA_NULL_PART_KEY;
1082
 
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1083
 
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1084
 
        }
1085
 
        if (field->type() == DRIZZLE_TYPE_BLOB ||
1086
 
            field->real_type() == DRIZZLE_TYPE_VARCHAR)
1087
 
        {
1088
 
          if (field->type() == DRIZZLE_TYPE_BLOB)
1089
 
            key_part->key_part_flag|= HA_BLOB_PART;
1090
 
          else
1091
 
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1092
 
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1093
 
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
1094
 
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1095
 
        }
1096
 
        if (i == 0 && key != primary_key)
1097
 
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1098
 
                           (keyinfo->key_parts == 1)) ?
1099
 
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1100
 
        if (i == 0)
1101
 
          field->key_start.set_bit(key);
1102
 
        if (field->key_length() == key_part->length &&
1103
 
            !(field->flags & BLOB_FLAG))
1104
 
        {
1105
 
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1106
 
          {
1107
 
            share->keys_for_keyread.set_bit(key);
1108
 
            field->part_of_key.set_bit(key);
1109
 
            field->part_of_key_not_clustered.set_bit(key);
1110
 
          }
1111
 
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1112
 
            field->part_of_sortkey.set_bit(key);
1113
 
        }
1114
 
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1115
 
            usable_parts == i)
1116
 
          usable_parts++;                       // For FILESORT
1117
 
        field->flags|= PART_KEY_FLAG;
1118
 
        if (key == primary_key)
1119
 
        {
1120
 
          field->flags|= PRI_KEY_FLAG;
1121
 
          /*
1122
 
            If this field is part of the primary key and all keys contains
1123
 
            the primary key, then we can use any key to find this column
1124
 
          */
1125
 
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1126
 
          {
1127
 
            field->part_of_key= share->keys_in_use;
1128
 
            if (field->part_of_sortkey.is_set(key))
1129
 
              field->part_of_sortkey= share->keys_in_use;
1130
 
          }
1131
 
        }
1132
 
        if (field->key_length() != key_part->length)
1133
 
        {
1134
 
          key_part->key_part_flag|= HA_PART_KEY_SEG;
1135
 
        }
1136
 
      }
1137
 
      keyinfo->usable_key_parts= usable_parts; // Filesort
1138
 
 
1139
 
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1140
 
                    keyinfo->key_parts);
1141
 
      share->total_key_length+= keyinfo->key_length;
1142
 
      /*
1143
 
        MERGE tables do not have unique indexes. But every key could be
1144
 
        an unique index on the underlying MyISAM table. (Bug #10400)
1145
 
      */
1146
 
      if ((keyinfo->flags & HA_NOSAME) ||
1147
 
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1148
 
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1149
 
    }
1150
 
    if (primary_key < MAX_KEY &&
1151
 
        (share->keys_in_use.is_set(primary_key)))
1152
 
    {
1153
 
      share->primary_key= primary_key;
1154
 
      /*
1155
 
        If we are using an integer as the primary key then allow the user to
1156
 
        refer to it as '_rowid'
1157
 
      */
1158
 
      if (share->key_info[primary_key].key_parts == 1)
1159
 
      {
1160
 
        Field *field= share->key_info[primary_key].key_part[0].field;
1161
 
        if (field && field->result_type() == INT_RESULT)
1162
 
        {
1163
 
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1164
 
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1165
 
                                      fieldnr);
1166
 
        }
1167
 
      }
1168
 
    }
1169
 
    else
1170
 
      share->primary_key = MAX_KEY; // we do not have a primary key
1171
 
  }
1172
 
  else
1173
 
    share->primary_key= MAX_KEY;
1174
 
  if (disk_buff)
1175
 
    free(disk_buff);
1176
 
  disk_buff= NULL;
1177
 
  if (new_field_pack_flag <= 1)
1178
 
  {
1179
 
    /* Old file format with default as not null */
1180
 
    uint32_t null_length= (share->null_fields+7)/8;
1181
 
    memset(share->default_values + (null_flags - (unsigned char*) record), 
1182
 
          null_length, 255);
1183
 
  }
1184
 
 
1185
 
  if (share->found_next_number_field)
1186
 
  {
1187
 
    reg_field= *share->found_next_number_field;
1188
 
    if ((int) (share->next_number_index= (uint)
1189
 
               find_ref_key(share->key_info, share->keys,
1190
 
                            share->default_values, reg_field,
1191
 
                            &share->next_number_key_offset,
1192
 
                            &share->next_number_keypart)) < 0)
1193
 
    {
1194
 
      /* Wrong field definition */
1195
 
      error= 4;
1196
 
      goto err;
1197
 
    }
1198
 
    else
1199
 
      reg_field->flags |= AUTO_INCREMENT_FLAG;
1200
 
  }
1201
 
 
1202
 
  if (share->blob_fields)
1203
 
  {
1204
 
    Field **ptr;
1205
 
    uint32_t k, *save;
1206
 
 
1207
 
    /* Store offsets to blob fields to find them fast */
1208
 
    if (!(share->blob_field= save=
1209
 
          (uint*) alloc_root(&share->mem_root,
1210
 
                             (uint) (share->blob_fields* sizeof(uint)))))
1211
 
      goto err;
1212
 
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1213
 
    {
1214
 
      if ((*ptr)->flags & BLOB_FLAG)
1215
 
        (*save++)= k;
1216
 
    }
1217
 
  }
1218
 
 
1219
 
  /*
1220
 
    the correct null_bytes can now be set, since bitfields have been taken
1221
 
    into account
1222
 
  */
1223
 
  share->null_bytes= (null_pos - (unsigned char*) null_flags +
1224
 
                      (null_bit_pos + 7) / 8);
1225
 
  share->last_null_bit_pos= null_bit_pos;
1226
 
 
1227
 
  share->db_low_byte_first= handler_file->low_byte_first();
1228
 
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1229
 
 
1230
 
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1231
 
                                             share->column_bitmap_size)))
1232
 
    goto err;
1233
 
  bitmap_init(&share->all_set, bitmaps, share->fields, false);
1234
 
  bitmap_set_all(&share->all_set);
1235
 
 
1236
 
  delete handler_file;
1237
 
  if (buff)
1238
 
    free(buff);
1239
 
  return (0);
1240
 
 
1241
 
 err:
1242
 
  if (buff)
1243
 
    free(buff);
1244
 
  share->error= error;
1245
 
  share->open_errno= my_errno;
1246
 
  share->errarg= errarg;
1247
 
  if (disk_buff)
1248
 
    free(disk_buff);
1249
 
  delete handler_file;
1250
 
  hash_free(&share->name_hash);
1251
 
 
1252
 
  open_table_error(share, error, share->open_errno, errarg);
1253
 
  return(error);
1254
 
} /* open_binary_frm */
1255
 
 
1256
 
 
1257
 
/*
1258
 
  Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
1259
 
  This routine is used for error handling purposes.
1260
 
 
1261
 
  SYNOPSIS
1262
 
    clear_field_flag()
1263
 
    table                Table object for which virtual columns are set-up
1264
 
 
1265
 
  RETURN VALUE
1266
 
    NONE
1267
 
*/
1268
 
static void clear_field_flag(Table *table)
1269
 
{
1270
 
  Field **ptr;
1271
 
 
1272
 
  for (ptr= table->field; *ptr; ptr++)
1273
 
    (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
1274
 
}
1275
 
 
1276
 
/*
1277
 
  The function uses the feature in fix_fields where the flag 
1278
 
  GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
1279
 
  This field must always be reset before returning from the function
1280
 
  since it is used for other purposes as well.
1281
 
 
1282
 
  SYNOPSIS
1283
 
    fix_fields_vcol_func()
1284
 
    session                  The thread object
1285
 
    func_item            The item tree reference of the virtual columnfunction
1286
 
    table                The table object
1287
 
    field_name           The name of the processed field
1288
 
 
1289
 
  RETURN VALUE
1290
 
    true                 An error occurred, something was wrong with the
1291
 
                         function.
1292
 
    false                Ok, a partition field array was created
1293
 
*/
1294
 
 
1295
 
bool fix_fields_vcol_func(Session *session,
1296
 
                          Item* func_expr,
1297
 
                          Table *table,
1298
 
                          const char *field_name)
1299
 
{
1300
 
  uint dir_length, home_dir_length;
1301
 
  bool result= true;
1302
 
  TableList tables;
1303
 
  TableList *save_table_list, *save_first_table, *save_last_table;
1304
 
  int error;
1305
 
  Name_resolution_context *context;
1306
 
  const char *save_where;
1307
 
  char* db_name;
1308
 
  char db_name_string[FN_REFLEN];
1309
 
  bool save_use_only_table_context;
1310
 
  Field **ptr, *field;
1311
 
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
1312
 
  assert(func_expr);
1313
 
 
1314
 
  /*
1315
 
    Set-up the TABLE_LIST object to be a list with a single table
1316
 
    Set the object to zero to create NULL pointers and set alias
1317
 
    and real name to table name and get database name from file name.
1318
 
  */
1319
 
 
1320
 
  bzero((void*)&tables, sizeof(TableList));
1321
 
  tables.alias= tables.table_name= (char*) table->s->table_name.str;
1322
 
  tables.table= table;
1323
 
  tables.next_local= NULL;
1324
 
  tables.next_name_resolution_table= NULL;
1325
 
  memcpy(db_name_string,
1326
 
         table->s->normalized_path.str,
1327
 
         table->s->normalized_path.length);
1328
 
  dir_length= dirname_length(db_name_string);
1329
 
  db_name_string[dir_length - 1]= 0;
1330
 
  home_dir_length= dirname_length(db_name_string);
1331
 
  db_name= &db_name_string[home_dir_length];
1332
 
  tables.db= db_name;
1333
 
 
1334
 
  session->mark_used_columns= MARK_COLUMNS_NONE;
1335
 
 
1336
 
  context= session->lex->current_context();
1337
 
  table->map= 1; //To ensure correct calculation of const item
1338
 
  table->get_fields_in_item_tree= true;
1339
 
  save_table_list= context->table_list;
1340
 
  save_first_table= context->first_name_resolution_table;
1341
 
  save_last_table= context->last_name_resolution_table;
1342
 
  context->table_list= &tables;
1343
 
  context->first_name_resolution_table= &tables;
1344
 
  context->last_name_resolution_table= NULL;
1345
 
  func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
1346
 
  save_where= session->where;
1347
 
  session->where= "virtual column function";
1348
 
 
1349
 
  /* Save the context before fixing the fields*/
1350
 
  save_use_only_table_context= session->lex->use_only_table_context;
1351
 
  session->lex->use_only_table_context= true;
1352
 
  /* Fix fields referenced to by the virtual column function */
1353
 
  error= func_expr->fix_fields(session, (Item**)0);
1354
 
  /* Restore the original context*/
1355
 
  session->lex->use_only_table_context= save_use_only_table_context;
1356
 
  context->table_list= save_table_list;
1357
 
  context->first_name_resolution_table= save_first_table;
1358
 
  context->last_name_resolution_table= save_last_table;
1359
 
 
1360
 
  if (unlikely(error))
1361
 
  {
1362
 
    clear_field_flag(table);
1363
 
    goto end;
1364
 
  }
1365
 
  session->where= save_where;
1366
 
  /* 
1367
 
    Walk through the Item tree checking if all items are valid 
1368
 
   to be part of the virtual column
1369
 
 */
1370
 
  error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
1371
 
  if (error)
1372
 
  {
1373
 
    my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
1374
 
    clear_field_flag(table);
1375
 
    goto end;
1376
 
  }
1377
 
  if (unlikely(func_expr->const_item()))
1378
 
  {
1379
 
    my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
1380
 
    clear_field_flag(table);
1381
 
    goto end;
1382
 
  }
1383
 
  /* Ensure that this virtual column is not based on another virtual field. */
1384
 
  ptr= table->field;
1385
 
  while ((field= *(ptr++))) 
1386
 
  {
1387
 
    if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
1388
 
        (field->vcol_info))
1389
 
    {
1390
 
      my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
1391
 
      clear_field_flag(table);
1392
 
      goto end;
1393
 
    }
1394
 
  }
1395
 
  /*
1396
 
    Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
1397
 
    when calling fix_fields.
1398
 
  */
1399
 
  clear_field_flag(table);
1400
 
  result= false;
1401
 
 
1402
 
end:
1403
 
  table->get_fields_in_item_tree= false;
1404
 
  session->mark_used_columns= save_mark_used_columns;
1405
 
  table->map= 0; //Restore old value
1406
 
  return(result);
1407
 
}
1408
 
 
1409
 
/*
1410
 
  Unpack the definition of a virtual column
1411
 
 
1412
 
  SYNOPSIS
1413
 
    unpack_vcol_info_from_frm()
1414
 
    session                  Thread handler
1415
 
    table                Table with the checked field
1416
 
    field                Pointer to Field object
1417
 
    open_mode            Open table mode needed to determine
1418
 
                         which errors need to be generated in a failure
1419
 
    error_reported       updated flag for the caller that no other error
1420
 
                         messages are to be generated.
1421
 
 
1422
 
  RETURN VALUES
1423
 
    true            Failure
1424
 
    false           Success
1425
 
*/
1426
 
bool unpack_vcol_info_from_frm(Session *session,
1427
 
                               Table *table,
1428
 
                               Field *field,
1429
 
                               LEX_STRING *vcol_expr,
1430
 
                               open_table_mode open_mode,
1431
 
                               bool *error_reported)
1432
 
{
1433
 
  assert(vcol_expr);
1434
 
 
1435
 
  /* 
1436
 
    Step 1: Construct a statement for the parser.
1437
 
    The parsed string needs to take the following format:
1438
 
    "PARSE_VCOL_EXPR (<expr_string_from_frm>)"
1439
 
  */
1440
 
  char *vcol_expr_str;
1441
 
  int str_len= 0;
1442
 
  
1443
 
  if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
1444
 
                                          vcol_expr->length + 
1445
 
                                            parse_vcol_keyword.length + 3)))
1446
 
  {
1447
 
    return(true);
1448
 
  }
1449
 
  memcpy(vcol_expr_str,
1450
 
         (char*) parse_vcol_keyword.str,
1451
 
         parse_vcol_keyword.length);
1452
 
  str_len= parse_vcol_keyword.length;
1453
 
  memcpy(vcol_expr_str + str_len, "(", 1);
1454
 
  str_len++;
1455
 
  memcpy(vcol_expr_str + str_len, 
1456
 
         (char*) vcol_expr->str, 
1457
 
         vcol_expr->length);
1458
 
  str_len+= vcol_expr->length;
1459
 
  memcpy(vcol_expr_str + str_len, ")", 1);
1460
 
  str_len++;
1461
 
  memcpy(vcol_expr_str + str_len, "\0", 1);
1462
 
  str_len++;
1463
 
  Lex_input_stream lip(session, vcol_expr_str, str_len);
1464
 
 
1465
 
  /* 
1466
 
    Step 2: Setup session for parsing.
1467
 
    1) make Item objects be created in the memory allocated for the Table
1468
 
       object (not TABLE_SHARE)
1469
 
    2) ensure that created Item's are not put on to session->free_list 
1470
 
       (which is associated with the parsed statement and hence cleared after 
1471
 
       the parsing)
1472
 
    3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR" 
1473
 
       to be parsed as a SQL command.
1474
 
  */
1475
 
  MEM_ROOT **root_ptr, *old_root;
1476
 
  Item *backup_free_list= session->free_list;
1477
 
  root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
1478
 
  old_root= *root_ptr;
1479
 
  *root_ptr= &table->mem_root;
1480
 
  session->free_list= NULL;
1481
 
  session->lex->parse_vcol_expr= true;
1482
 
 
1483
 
  /* 
1484
 
    Step 3: Use the parser to build an Item object from.
1485
 
  */
1486
 
  if (parse_sql(session, &lip))
1487
 
  {
1488
 
    goto parse_err;
1489
 
  }
1490
 
  /* From now on use vcol_info generated by the parser. */
1491
 
  field->vcol_info= session->lex->vcol_info;
1492
 
 
1493
 
  /* Validate the Item tree. */
1494
 
  if (fix_fields_vcol_func(session,
1495
 
                           field->vcol_info->expr_item,
1496
 
                           table,
1497
 
                           field->field_name))
1498
 
  {
1499
 
    if (open_mode == OTM_CREATE)
1500
 
    {
1501
 
      /*
1502
 
        During CREATE/ALTER TABLE it is ok to receive errors here.
1503
 
        It is not ok if it happens during the opening of an frm
1504
 
        file as part of a normal query.
1505
 
      */
1506
 
      *error_reported= true;
1507
 
    }
1508
 
    field->vcol_info= NULL;
1509
 
    goto parse_err;
1510
 
  }
1511
 
  field->vcol_info->item_free_list= session->free_list;
1512
 
  session->free_list= backup_free_list;
1513
 
  *root_ptr= old_root;
1514
 
 
1515
 
  return(false);
1516
 
 
1517
 
parse_err:
1518
 
  session->lex->parse_vcol_expr= false;
1519
 
  session->free_items();
1520
 
  *root_ptr= old_root;
1521
 
  session->free_list= backup_free_list;
1522
 
  return(true);
1523
 
}
1524
 
 
1525
 
 
1526
 
/*
1527
 
  Open a table based on a TABLE_SHARE
1528
 
 
1529
 
  SYNOPSIS
1530
 
    open_table_from_share()
1531
 
    session                     Thread handler
1532
 
    share               Table definition
1533
 
    alias               Alias for table
1534
 
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1535
 
                        HA_OPEN_RNDFILE..) can be 0 (example in
1536
 
                        ha_example_table)
1537
 
    prgflag             READ_ALL etc..
1538
 
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
1539
 
    outparam            result table
1540
 
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1541
 
                        if OTM_CREATE some errors are ignore
1542
 
                        if OTM_ALTER HA_OPEN is not called
1543
 
 
1544
 
  RETURN VALUES
1545
 
   0    ok
1546
 
   1    Error (see open_table_error)
1547
 
   2    Error (see open_table_error)
1548
 
   3    Wrong data in .frm file
1549
 
   4    Error (see open_table_error)
1550
 
   5    Error (see open_table_error: charset unavailable)
1551
 
   7    Table definition has changed in engine
1552
 
*/
1553
 
 
1554
 
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1555
 
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1556
 
                          Table *outparam, open_table_mode open_mode)
1557
 
{
1558
 
  int error;
1559
 
  uint32_t records, i, bitmap_size;
1560
 
  bool error_reported= false;
1561
 
  unsigned char *record, *bitmaps;
1562
 
  Field **field_ptr, **vfield_ptr;
1563
 
 
1564
 
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1565
 
  assert(session->lex->is_lex_started);
1566
 
 
1567
 
  error= 1;
1568
 
  memset(outparam, 0, sizeof(*outparam));
1569
 
  outparam->in_use= session;
1570
 
  outparam->s= share;
1571
 
  outparam->db_stat= db_stat;
1572
 
  outparam->write_row_record= NULL;
1573
 
 
1574
 
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1575
 
 
1576
 
  if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
1577
 
    goto err;
1578
 
  outparam->quick_keys.init();
1579
 
  outparam->covering_keys.init();
1580
 
  outparam->keys_in_use_for_query.init();
1581
 
 
1582
 
  /* Allocate handler */
1583
 
  outparam->file= 0;
1584
 
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
1585
 
  {
1586
 
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1587
 
                                          share->db_type())))
1588
 
      goto err;
1589
 
  }
1590
 
  else
1591
 
  {
1592
 
    assert(!db_stat);
1593
 
  }
1594
 
 
1595
 
  error= 4;
1596
 
  outparam->reginfo.lock_type= TL_UNLOCK;
1597
 
  outparam->current_lock= F_UNLCK;
1598
 
  records=0;
1599
 
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1600
 
    records=1;
1601
 
  if (prgflag & (READ_ALL+EXTRA_RECORD))
1602
 
    records++;
1603
 
 
1604
 
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1605
 
                                   share->rec_buff_length * records)))
1606
 
    goto err;                                   /* purecov: inspected */
1607
 
 
1608
 
  if (records == 0)
1609
 
  {
1610
 
    /* We are probably in hard repair, and the buffers should not be used */
1611
 
    outparam->record[0]= outparam->record[1]= share->default_values;
1612
 
  }
1613
 
  else
1614
 
  {
1615
 
    outparam->record[0]= record;
1616
 
    if (records > 1)
1617
 
      outparam->record[1]= record+ share->rec_buff_length;
1618
 
    else
1619
 
      outparam->record[1]= outparam->record[0];   // Safety
1620
 
  }
1621
 
 
1622
 
#ifdef HAVE_purify
1623
 
  /*
1624
 
    We need this because when we read var-length rows, we are not updating
1625
 
    bytes after end of varchar
1626
 
  */
1627
 
  if (records > 1)
1628
 
  {
1629
 
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1630
 
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
1631
 
    if (records > 2)
1632
 
      memcpy(outparam->record[1], share->default_values,
1633
 
             share->rec_buff_length);
1634
 
  }
1635
 
#endif
1636
 
 
1637
 
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1638
 
                                          (uint) ((share->fields+1)*
1639
 
                                                  sizeof(Field*)))))
1640
 
    goto err;                                   /* purecov: inspected */
1641
 
 
1642
 
  outparam->field= field_ptr;
1643
 
 
1644
 
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
1645
 
  if (share->null_field_first)
1646
 
    outparam->null_flags= (unsigned char*) record+1;
1647
 
  else
1648
 
    outparam->null_flags= (unsigned char*) (record+ 1+ share->reclength -
1649
 
                                    share->null_bytes);
1650
 
 
1651
 
  /* Setup copy of fields from share, but use the right alias and record */
1652
 
  for (i=0 ; i < share->fields; i++, field_ptr++)
1653
 
  {
1654
 
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1655
 
      goto err;
1656
 
  }
1657
 
  (*field_ptr)= 0;                              // End marker
1658
 
 
1659
 
  if (share->found_next_number_field)
1660
 
    outparam->found_next_number_field=
1661
 
      outparam->field[(uint) (share->found_next_number_field - share->field)];
1662
 
  if (share->timestamp_field)
1663
 
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1664
 
 
1665
 
 
1666
 
  /* Fix key->name and key_part->field */
1667
 
  if (share->key_parts)
1668
 
  {
1669
 
    KEY *key_info, *key_info_end;
1670
 
    KEY_PART_INFO *key_part;
1671
 
    uint32_t n_length;
1672
 
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1673
 
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1674
 
      goto err;
1675
 
    outparam->key_info= key_info;
1676
 
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1677
 
    
1678
 
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1679
 
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1680
 
                                                   share->key_parts));
1681
 
 
1682
 
    for (key_info_end= key_info + share->keys ;
1683
 
         key_info < key_info_end ;
1684
 
         key_info++)
1685
 
    {
1686
 
      KEY_PART_INFO *key_part_end;
1687
 
 
1688
 
      key_info->table= outparam;
1689
 
      key_info->key_part= key_part;
1690
 
 
1691
 
      for (key_part_end= key_part+ key_info->key_parts ;
1692
 
           key_part < key_part_end ;
1693
 
           key_part++)
1694
 
      {
1695
 
        Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1696
 
 
1697
 
        if (field->key_length() != key_part->length &&
1698
 
            !(field->flags & BLOB_FLAG))
1699
 
        {
1700
 
          /*
1701
 
            We are using only a prefix of the column as a key:
1702
 
            Create a new field for the key part that matches the index
1703
 
          */
1704
 
          field= key_part->field=field->new_field(&outparam->mem_root,
1705
 
                                                  outparam, 0);
1706
 
          field->field_length= key_part->length;
1707
 
        }
1708
 
      }
1709
 
    }
1710
 
  }
1711
 
 
1712
 
  /*
1713
 
    Process virtual columns, if any.
1714
 
  */
1715
 
  if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
1716
 
                                              (uint) ((share->vfields+1)*
1717
 
                                                      sizeof(Field*)))))
1718
 
    goto err;
1719
 
 
1720
 
  outparam->vfield= vfield_ptr;
1721
 
  
1722
 
  for (field_ptr= outparam->field; *field_ptr; field_ptr++)
1723
 
  {
1724
 
    if ((*field_ptr)->vcol_info)
1725
 
    {
1726
 
      if (unpack_vcol_info_from_frm(session,
1727
 
                                    outparam,
1728
 
                                    *field_ptr,
1729
 
                                    &(*field_ptr)->vcol_info->expr_str,
1730
 
                                    open_mode,
1731
 
                                    &error_reported))
1732
 
      {
1733
 
        error= 4; // in case no error is reported
1734
 
        goto err;
1735
 
      }
1736
 
      *(vfield_ptr++)= *field_ptr;
1737
 
    }
1738
 
  }
1739
 
  *vfield_ptr= NULL;                              // End marker
1740
 
  /* Check virtual columns against table's storage engine. */
1741
 
  if ((share->vfields && outparam->file) && 
1742
 
        (not outparam->file->check_if_supported_virtual_columns()))
1743
 
  {
1744
 
    my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
1745
 
             MYF(0), 
1746
 
             "Specified storage engine");
1747
 
    error_reported= true;
1748
 
    goto err;
1749
 
  }
1750
 
 
1751
 
  /* Allocate bitmaps */
1752
 
 
1753
 
  bitmap_size= share->column_bitmap_size;
1754
 
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1755
 
    goto err;
1756
 
  bitmap_init(&outparam->def_read_set,
1757
 
              (my_bitmap_map*) bitmaps, share->fields, false);
1758
 
  bitmap_init(&outparam->def_write_set,
1759
 
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
1760
 
  bitmap_init(&outparam->tmp_set,
1761
 
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1762
 
  outparam->default_column_bitmaps();
1763
 
 
1764
 
  /* The table struct is now initialized;  Open the table */
1765
 
  error= 2;
1766
 
  if (db_stat && open_mode != OTM_ALTER)
1767
 
  {
1768
 
    int ha_err;
1769
 
    if ((ha_err= (outparam->file->
1770
 
                  ha_open(outparam, share->normalized_path.str,
1771
 
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1772
 
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1773
 
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
1774
 
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1775
 
                          HA_OPEN_ABORT_IF_LOCKED :
1776
 
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1777
 
    {
1778
 
      /* Set a flag if the table is crashed and it can be auto. repaired */
1779
 
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1780
 
                       outparam->file->auto_repair() &&
1781
 
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
1782
 
 
1783
 
      switch (ha_err)
1784
 
      {
1785
 
        case HA_ERR_NO_SUCH_TABLE:
1786
 
          /*
1787
 
            The table did not exists in storage engine, use same error message
1788
 
            as if the .frm file didn't exist
1789
 
          */
1790
 
          error= 1;
1791
 
          my_errno= ENOENT;
1792
 
          break;
1793
 
        case EMFILE:
1794
 
          /*
1795
 
            Too many files opened, use same error message as if the .frm
1796
 
            file can't open
1797
 
           */
1798
 
          error= 1;
1799
 
          my_errno= EMFILE;
1800
 
          break;
1801
 
        default:
1802
 
          outparam->file->print_error(ha_err, MYF(0));
1803
 
          error_reported= true;
1804
 
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1805
 
            error= 7;
1806
 
          break;
1807
 
      }
1808
 
      goto err;                                 /* purecov: inspected */
1809
 
    }
1810
 
  }
1811
 
 
1812
 
#if defined(HAVE_purify) 
1813
 
  memset(bitmaps, 0, bitmap_size*3);
1814
 
#endif
1815
 
 
1816
 
  outparam->no_replicate= outparam->file;
1817
 
  session->status_var.opened_tables++;
1818
 
 
1819
 
  return (0);
1820
 
 
1821
 
 err:
1822
 
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1823
 
    open_table_error(share, error, my_errno, 0);
1824
 
  delete outparam->file;
1825
 
  outparam->file= 0;                            // For easier error checking
1826
 
  outparam->db_stat=0;
1827
 
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1828
 
  free((char*) outparam->alias);
1829
 
  return (error);
1830
 
}
1831
 
 
1832
 
 
1833
 
/*
1834
 
  Free information allocated by openfrm
1835
 
 
1836
 
  SYNOPSIS
1837
 
    closefrm()
1838
 
    table               Table object to free
1839
 
    free_share          Is 1 if we also want to free table_share
1840
 
*/
1841
 
 
1842
 
int closefrm(register Table *table, bool free_share)
1843
 
{
1844
 
  int error=0;
1845
 
 
1846
 
  if (table->db_stat)
1847
 
    error=table->file->close();
1848
 
  free((char*) table->alias);
1849
 
  table->alias= 0;
1850
 
  if (table->field)
1851
 
  {
1852
 
    for (Field **ptr=table->field ; *ptr ; ptr++)
 
74
// @note this should all be the destructor
 
75
int Table::delete_table(bool free_share)
 
76
{
 
77
  int error= 0;
 
78
 
 
79
  if (db_stat)
 
80
    error= cursor->close();
 
81
  _alias.clear();
 
82
 
 
83
  if (field)
 
84
  {
 
85
    for (Field **ptr=field ; *ptr ; ptr++)
 
86
    {
1853
87
      delete *ptr;
1854
 
    table->field= 0;
 
88
    }
 
89
    field= 0;
1855
90
  }
1856
 
  delete table->file;
1857
 
  table->file= 0;                               /* For easier errorchecking */
 
91
  safe_delete(cursor);
 
92
 
1858
93
  if (free_share)
1859
94
  {
1860
 
    if (table->s->tmp_table == NO_TMP_TABLE)
1861
 
      release_table_share(table->s, RELEASE_NORMAL);
1862
 
    else
1863
 
      free_table_share(table->s);
 
95
    release();
1864
96
  }
1865
 
  free_root(&table->mem_root, MYF(0));
1866
 
  return(error);
1867
 
}
 
97
 
 
98
  return error;
 
99
}
 
100
 
 
101
Table::~Table()
 
102
{
 
103
  mem_root.free_root(MYF(0));
 
104
}
 
105
 
 
106
 
 
107
void Table::resetTable(Session *session,
 
108
                       TableShare *share,
 
109
                       uint32_t db_stat_arg)
 
110
{
 
111
  setShare(share);
 
112
  in_use= session;
 
113
 
 
114
  field= NULL;
 
115
 
 
116
  cursor= NULL;
 
117
  next= NULL;
 
118
  prev= NULL;
 
119
 
 
120
  read_set= NULL;
 
121
  write_set= NULL;
 
122
 
 
123
  tablenr= 0;
 
124
  db_stat= db_stat_arg;
 
125
 
 
126
  record[0]= (unsigned char *) NULL;
 
127
  record[1]= (unsigned char *) NULL;
 
128
 
 
129
  insert_values.clear();
 
130
  key_info= NULL;
 
131
  next_number_field= NULL;
 
132
  found_next_number_field= NULL;
 
133
  timestamp_field= NULL;
 
134
 
 
135
  pos_in_table_list= NULL;
 
136
  group= NULL;
 
137
  _alias.clear();
 
138
  null_flags= NULL;
 
139
 
 
140
  lock_position= 0;
 
141
  lock_data_start= 0;
 
142
  lock_count= 0;
 
143
  used_fields= 0;
 
144
  status= 0;
 
145
  derived_select_number= 0;
 
146
  current_lock= F_UNLCK;
 
147
  copy_blobs= false;
 
148
 
 
149
  maybe_null= false;
 
150
 
 
151
  null_row= false;
 
152
 
 
153
  force_index= false;
 
154
  distinct= false;
 
155
  const_table= false;
 
156
  no_rows= false;
 
157
  key_read= false;
 
158
  no_keyread= false;
 
159
 
 
160
  open_placeholder= false;
 
161
  locked_by_name= false;
 
162
  no_cache= false;
 
163
 
 
164
  auto_increment_field_not_null= false;
 
165
  alias_name_used= false;
 
166
 
 
167
  query_id= 0;
 
168
  quick_condition_rows= 0;
 
169
 
 
170
  timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
 
171
  map= 0;
 
172
 
 
173
  reginfo.reset();
 
174
 
 
175
  covering_keys.reset();
 
176
 
 
177
  quick_keys.reset();
 
178
  merge_keys.reset();
 
179
 
 
180
  keys_in_use_for_query.reset();
 
181
  keys_in_use_for_group_by.reset();
 
182
  keys_in_use_for_order_by.reset();
 
183
 
 
184
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
 
185
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
 
186
 
 
187
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
 
188
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
 
189
 
 
190
  mem_root.init(TABLE_ALLOC_BLOCK_SIZE);
 
191
}
 
192
 
1868
193
 
1869
194
 
1870
195
/* Deallocate temporary blob storage */
1871
196
 
1872
 
void free_blobs(register Table *table)
 
197
void free_blobs(Table *table)
1873
198
{
1874
199
  uint32_t *ptr, *end;
1875
200
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
1876
201
       ptr != end ;
1877
202
       ptr++)
1878
 
    ((Field_blob*) table->field[*ptr])->free();
1879
 
}
1880
 
 
1881
 
 
1882
 
        /* Find where a form starts */
1883
 
        /* if formname is NULL then only formnames is read */
1884
 
 
1885
 
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
1886
 
{
1887
 
  uint32_t a_length,names,length;
1888
 
  unsigned char *pos,*buf;
1889
 
  ulong ret_value=0;
1890
 
 
1891
 
  names=uint2korr(head+8);
1892
 
  a_length=(names+2)*sizeof(char *);            /* Room for two extra */
1893
 
 
1894
 
  if (!save_names)
1895
 
    a_length=0;
1896
 
  else
1897
 
    save_names->type_names=0;                   /* Clear if error */
1898
 
 
1899
 
  if (names)
1900
 
  {
1901
 
    length=uint2korr(head+4);
1902
 
    my_seek(file,64L,MY_SEEK_SET,MYF(0));
1903
 
    if (!(buf= (unsigned char*) my_malloc((size_t) length+a_length+names*4,
1904
 
                                  MYF(MY_WME))) ||
1905
 
        my_read(file, buf+a_length, (size_t) (length+names*4),
1906
 
                MYF(MY_NABP)))
1907
 
    {                                           /* purecov: inspected */
1908
 
      if (buf)
1909
 
        free(buf);
1910
 
      return(0L);                               /* purecov: inspected */
1911
 
    }
1912
 
    pos= buf+a_length+length;
1913
 
    ret_value=uint4korr(pos);
1914
 
  }
1915
 
  if (! save_names)
1916
 
  {
1917
 
    if (names)
1918
 
      free((unsigned char*) buf);
1919
 
  }
1920
 
  else if (!names)
1921
 
    memset(save_names, 0, sizeof(save_names));
1922
 
  else
1923
 
  {
1924
 
    char *str;
1925
 
    str=(char *) (buf+a_length);
1926
 
    fix_type_pointers((const char ***) &buf,save_names,1,&str);
1927
 
  }
1928
 
  return(ret_value);
1929
 
}
1930
 
 
1931
 
 
1932
 
/*
1933
 
  Read string from a file with malloc
1934
 
 
1935
 
  NOTES:
1936
 
    We add an \0 at end of the read string to make reading of C strings easier
1937
 
*/
1938
 
 
1939
 
int read_string(File file, unsigned char**to, size_t length)
1940
 
{
1941
 
 
1942
 
  if (*to)
1943
 
    free(*to);
1944
 
  if (!(*to= (unsigned char*) my_malloc(length+1,MYF(MY_WME))) ||
1945
 
      my_read(file, *to, length,MYF(MY_NABP)))
1946
 
  {
1947
 
    if (*to)
1948
 
      free(*to);
1949
 
    *to= NULL;
1950
 
    return(1);                           /* purecov: inspected */
1951
 
  }
1952
 
  *((char*) *to+length)= '\0';
1953
 
  return (0);
1954
 
} /* read_string */
1955
 
 
1956
 
 
1957
 
        /* Add a new form to a form file */
1958
 
 
1959
 
ulong make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
1960
 
                     const char *newname)
1961
 
{
1962
 
  uint32_t i,bufflength,maxlength,n_length,length,names;
1963
 
  ulong endpos,newpos;
1964
 
  unsigned char buff[IO_SIZE];
1965
 
  unsigned char *pos;
1966
 
 
1967
 
  length=(uint) strlen(newname)+1;
1968
 
  n_length=uint2korr(fileinfo+4);
1969
 
  maxlength=uint2korr(fileinfo+6);
1970
 
  names=uint2korr(fileinfo+8);
1971
 
  newpos=uint4korr(fileinfo+10);
1972
 
 
1973
 
  if (64+length+n_length+(names+1)*4 > maxlength)
1974
 
  {                                             /* Expand file */
1975
 
    newpos+=IO_SIZE;
1976
 
    int4store(fileinfo+10,newpos);
1977
 
    endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */
1978
 
    bufflength= (uint) (endpos & (IO_SIZE-1));  /* IO_SIZE is a power of 2 */
1979
 
 
1980
 
    while (endpos > maxlength)
1981
 
    {
1982
 
      my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0));
1983
 
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
1984
 
        return(0L);
1985
 
      my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
1986
 
                   MYF(0));
1987
 
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
1988
 
        return(0);
1989
 
      endpos-=bufflength; bufflength=IO_SIZE;
1990
 
    }
1991
 
    memset(buff, 0, IO_SIZE);                   /* Null new block */
1992
 
    my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0));
1993
 
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
1994
 
        return(0L);
1995
 
    maxlength+=IO_SIZE;                         /* Fix old ref */
1996
 
    int2store(fileinfo+6,maxlength);
1997
 
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i-- ;
1998
 
         pos+=4)
1999
 
    {
2000
 
      endpos=uint4korr(pos)+IO_SIZE;
2001
 
      int4store(pos,endpos);
2002
 
    }
2003
 
  }
2004
 
 
2005
 
  if (n_length == 1 )
2006
 
  {                                             /* First name */
2007
 
    length++;
2008
 
    strxmov((char*) buff,"/",newname,"/",NULL);
2009
 
  }
2010
 
  else
2011
 
    strxmov((char*) buff,newname,"/",NULL); /* purecov: inspected */
2012
 
  my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0));
2013
 
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
2014
 
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
2015
 
                         names*4, MYF(MY_NABP+MY_WME))) ||
2016
 
      my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
2017
 
    return(0L); /* purecov: inspected */
2018
 
 
2019
 
  int2store(fileinfo+8,names+1);
2020
 
  int2store(fileinfo+4,n_length+length);
2021
 
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
2022
 
  return(newpos);
2023
 
} /* make_new_entry */
2024
 
 
2025
 
 
2026
 
        /* error message when opening a form file */
2027
 
 
2028
 
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
2029
 
{
2030
 
  int err_no;
2031
 
  char buff[FN_REFLEN];
2032
 
  myf errortype= ME_ERROR+ME_WAITTANG;
2033
 
 
2034
 
  switch (error) {
2035
 
  case 7:
2036
 
  case 1:
2037
 
    if (db_errno == ENOENT)
2038
 
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
2039
 
    else
2040
 
    {
2041
 
      strxmov(buff, share->normalized_path.str, reg_ext, NULL);
2042
 
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
2043
 
               errortype, buff, db_errno);
2044
 
    }
2045
 
    break;
2046
 
  case 2:
2047
 
  {
2048
 
    handler *file= 0;
2049
 
    const char *datext= "";
2050
 
    
2051
 
    if (share->db_type() != NULL)
2052
 
    {
2053
 
      if ((file= get_new_handler(share, current_session->mem_root,
2054
 
                                 share->db_type())))
2055
 
      {
2056
 
        if (!(datext= *file->bas_ext()))
2057
 
          datext= "";
2058
 
      }
2059
 
    }
2060
 
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
2061
 
      ER_FILE_USED : ER_CANT_OPEN_FILE;
2062
 
    strxmov(buff, share->normalized_path.str, datext, NULL);
2063
 
    my_error(err_no,errortype, buff, db_errno);
2064
 
    delete file;
2065
 
    break;
2066
 
  }
2067
 
  case 5:
2068
 
  {
2069
 
    const char *csname= get_charset_name((uint) errarg);
2070
 
    char tmp[10];
2071
 
    if (!csname || csname[0] =='?')
2072
 
    {
2073
 
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
2074
 
      csname= tmp;
2075
 
    }
2076
 
    my_printf_error(ER_UNKNOWN_COLLATION,
2077
 
                    _("Unknown collation '%s' in table '%-.64s' definition"), 
2078
 
                    MYF(0), csname, share->table_name.str);
2079
 
    break;
2080
 
  }
2081
 
  case 6:
2082
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
2083
 
    my_printf_error(ER_NOT_FORM_FILE,
2084
 
                    _("Table '%-.64s' was created with a different version "
2085
 
                    "of MySQL and cannot be read"), 
2086
 
                    MYF(0), buff);
2087
 
    break;
2088
 
  case 8:
2089
 
    break;
2090
 
  default:                              /* Better wrong error than none */
2091
 
  case 4:
2092
 
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
2093
 
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
2094
 
    break;
2095
 
  }
2096
 
  return;
2097
 
} /* open_table_error */
2098
 
 
2099
 
 
2100
 
        /*
2101
 
        ** fix a str_type to a array type
2102
 
        ** typeparts separated with some char. differents types are separated
2103
 
        ** with a '\0'
2104
 
        */
2105
 
 
2106
 
static void
2107
 
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
2108
 
                  char **names)
2109
 
{
2110
 
  char *type_name, *ptr;
2111
 
  char chr;
2112
 
 
2113
 
  ptr= *names;
2114
 
  while (types--)
2115
 
  {
2116
 
    point_to_type->name=0;
2117
 
    point_to_type->type_names= *array;
2118
 
 
2119
 
    if ((chr= *ptr))                    /* Test if empty type */
2120
 
    {
2121
 
      while ((type_name=strchr(ptr+1,chr)) != NULL)
2122
 
      {
2123
 
        *((*array)++) = ptr+1;
2124
 
        *type_name= '\0';               /* End string */
2125
 
        ptr=type_name;
2126
 
      }
2127
 
      ptr+=2;                           /* Skip end mark and last 0 */
2128
 
    }
2129
 
    else
2130
 
      ptr++;
2131
 
    point_to_type->count= (uint) (*array - point_to_type->type_names);
2132
 
    point_to_type++;
2133
 
    *((*array)++)= NULL;                /* End of type */
2134
 
  }
2135
 
  *names=ptr;                           /* Update end */
2136
 
  return;
2137
 
} /* fix_type_pointers */
2138
 
 
2139
 
 
2140
 
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
2141
 
{
2142
 
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
2143
 
  if (!result)
2144
 
    return 0;
2145
 
  result->count=strings.elements;
2146
 
  result->name="";
2147
 
  uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
2148
 
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
2149
 
    return 0;
 
203
  {
 
204
    ((Field_blob*) table->getField(*ptr))->free();
 
205
  }
 
206
}
 
207
 
 
208
 
 
209
TYPELIB *typelib(memory::Root& mem_root, List<String> &strings)
 
210
{
 
211
  TYPELIB *result= new (mem_root) TYPELIB;
 
212
  result->count= strings.size();
 
213
  result->name= "";
 
214
  result->type_names= (const char**) mem_root.alloc((sizeof(char*) + sizeof(uint32_t)) * (result->count + 1));
2150
215
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
2151
 
  List_iterator<String> it(strings);
 
216
 
 
217
  List<String>::iterator it(strings.begin());
2152
218
  String *tmp;
2153
 
  for (uint32_t i=0; (tmp=it++) ; i++)
 
219
  for (uint32_t i= 0; (tmp= it++); i++)
2154
220
  {
2155
221
    result->type_names[i]= tmp->ptr();
2156
222
    result->type_lengths[i]= tmp->length();
2157
223
  }
2158
 
  result->type_names[result->count]= 0;         // End marker
 
224
 
 
225
  result->type_names[result->count]= 0;   // End marker
2159
226
  result->type_lengths[result->count]= 0;
 
227
 
2160
228
  return result;
2161
229
}
2162
230
 
2163
 
 
2164
 
/*
2165
 
 Search after a field with given start & length
2166
 
 If an exact field isn't found, return longest field with starts
2167
 
 at right position.
2168
 
 
2169
 
 NOTES
2170
 
   This is needed because in some .frm fields 'fieldnr' was saved wrong
2171
 
 
2172
 
 RETURN
2173
 
   0  error
2174
 
   #  field number +1
2175
 
*/
2176
 
 
2177
 
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length)
2178
 
{
2179
 
  Field **field;
2180
 
  uint32_t i, pos;
2181
 
 
2182
 
  pos= 0;
2183
 
  for (field= fields, i=1 ; *field ; i++,field++)
2184
 
  {
2185
 
    if ((*field)->offset(record) == start)
2186
 
    {
2187
 
      if ((*field)->key_length() == length)
2188
 
        return (i);
2189
 
      if (!pos || fields[pos-1]->pack_length() <
2190
 
          (*field)->pack_length())
2191
 
        pos= i;
2192
 
    }
2193
 
  }
2194
 
  return (pos);
2195
 
}
2196
 
 
2197
 
 
2198
231
        /* Check that the integer is in the internal */
2199
232
 
2200
 
int set_zone(register int nr, int min_zone, int max_zone)
 
233
int set_zone(int nr, int min_zone, int max_zone)
2201
234
{
2202
235
  if (nr<=min_zone)
2203
236
    return (min_zone);
2206
239
  return (nr);
2207
240
} /* set_zone */
2208
241
 
2209
 
        /* Adjust number to next larger disk buffer */
2210
 
 
2211
 
ulong next_io_size(register ulong pos)
2212
 
{
2213
 
  register ulong offset;
2214
 
  if ((offset= pos & (IO_SIZE-1)))
2215
 
    return pos-offset+IO_SIZE;
2216
 
  return pos;
2217
 
} /* next_io_size */
2218
 
 
2219
242
 
2220
243
/*
2221
244
  Store an SQL quoted string.
2222
245
 
2223
 
  SYNOPSIS  
 
246
  SYNOPSIS
2224
247
    append_unescaped()
2225
248
    res         result String
2226
249
    pos         string to be quoted
2238
261
 
2239
262
  for (; pos != end ; pos++)
2240
263
  {
2241
 
#if defined(USE_MB)
2242
264
    uint32_t mblen;
2243
265
    if (use_mb(default_charset_info) &&
2244
266
        (mblen= my_ismbchar(default_charset_info, pos, end)))
2245
267
    {
2246
268
      res->append(pos, mblen);
2247
 
      pos+= mblen;
 
269
      pos+= mblen - 1;
 
270
      if (pos >= end)
 
271
        break;
2248
272
      continue;
2249
273
    }
2250
 
#endif
2251
274
 
2252
275
    switch (*pos) {
2253
276
    case 0:                             /* Must be escaped for 'mysql' */
2278
301
  res->append('\'');
2279
302
}
2280
303
 
2281
 
 
2282
 
        /* Create a .frm file */
2283
 
 
2284
 
File create_frm(Session *session, const char *name, const char *db,
2285
 
                const char *table, uint32_t reclength, unsigned char *fileinfo,
2286
 
                HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
2287
 
{
2288
 
  register File file;
2289
 
  ulong length;
2290
 
  unsigned char fill[IO_SIZE];
2291
 
  int create_flags= O_RDWR | O_TRUNC;
2292
 
  ulong key_comment_total_bytes= 0;
2293
 
  uint32_t i;
2294
 
 
2295
 
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
2296
 
    create_flags|= O_EXCL;
2297
 
 
2298
 
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
2299
 
  if (create_info->max_rows > UINT32_MAX)
2300
 
    create_info->max_rows= UINT32_MAX;
2301
 
  if (create_info->min_rows > UINT32_MAX)
2302
 
    create_info->min_rows= UINT32_MAX;
2303
 
 
2304
 
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
2305
 
  {
2306
 
    uint32_t key_length, tmp_key_length;
2307
 
    uint32_t tmp;
2308
 
    memset(fileinfo, 0, 64);
2309
 
    /* header */
2310
 
    fileinfo[0]=(unsigned char) 254;
2311
 
    fileinfo[1]= 1;
2312
 
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
2313
 
 
2314
 
    fileinfo[3]= (unsigned char) ha_legacy_type(
2315
 
          ha_checktype(session,ha_legacy_type(create_info->db_type),0,0));
2316
 
    fileinfo[4]=1;
2317
 
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
2318
 
    for (i= 0; i < keys; i++)
2319
 
    {
2320
 
      assert(test(key_info[i].flags & HA_USES_COMMENT) == 
2321
 
                 (key_info[i].comment.length > 0));
2322
 
      if (key_info[i].flags & HA_USES_COMMENT)
2323
 
        key_comment_total_bytes += 2 + key_info[i].comment.length;
2324
 
    }
2325
 
    /*
2326
 
      Keep in sync with pack_keys() in unireg.cc
2327
 
      For each key:
2328
 
      8 bytes for the key header
2329
 
      9 bytes for each key-part (MAX_REF_PARTS)
2330
 
      NAME_LEN bytes for the name
2331
 
      1 byte for the NAMES_SEP_CHAR (before the name)
2332
 
      For all keys:
2333
 
      6 bytes for the header
2334
 
      1 byte for the NAMES_SEP_CHAR (after the last name)
2335
 
      9 extra bytes (padding for safety? alignment?)
2336
 
      comments
2337
 
    */
2338
 
    key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
2339
 
                 key_comment_total_bytes);
2340
 
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
2341
 
                                  create_info->extra_size));
2342
 
    int4store(fileinfo+10,length);
2343
 
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
2344
 
    int2store(fileinfo+14,tmp_key_length);
2345
 
    int2store(fileinfo+16,reclength);
2346
 
    int4store(fileinfo+18,create_info->max_rows);
2347
 
    int4store(fileinfo+22,create_info->min_rows);
2348
 
    /* fileinfo[26] is set in mysql_create_frm() */
2349
 
    fileinfo[27]=2;                             // Use long pack-fields
2350
 
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
2351
 
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
2352
 
    int2store(fileinfo+30,create_info->table_options);
2353
 
    fileinfo[32]=0;                             // No filename anymore
2354
 
    fileinfo[33]=5;                             // Mark for 5.0 frm file
2355
 
    int4store(fileinfo+34,create_info->avg_row_length);
2356
 
    fileinfo[38]= (create_info->default_table_charset ?
2357
 
                   create_info->default_table_charset->number : 0);
2358
 
    fileinfo[39]= (unsigned char) create_info->page_checksum;
2359
 
    fileinfo[40]= (unsigned char) create_info->row_type;
2360
 
    /* Next few bytes were for RAID support */
2361
 
    fileinfo[41]= 0;
2362
 
    fileinfo[42]= 0;
2363
 
    int4store(fileinfo+43,create_info->block_size);
2364
 
 
2365
 
    fileinfo[44]= 0;
2366
 
    fileinfo[45]= 0;
2367
 
    fileinfo[46]= 0;
2368
 
    int4store(fileinfo+47, key_length);
2369
 
    tmp= DRIZZLE_VERSION_ID;          // Store to avoid warning from int4store
2370
 
    int4store(fileinfo+51, tmp);
2371
 
    int4store(fileinfo+55, create_info->extra_size);
2372
 
    /*
2373
 
      59-60 is reserved for extra_rec_buf_length,
2374
 
      61 for default_part_db_type
2375
 
    */
2376
 
    int2store(fileinfo+62, create_info->key_block_size);
2377
 
    memset(fill, 0, IO_SIZE);
2378
 
    for (; length > IO_SIZE ; length-= IO_SIZE)
2379
 
    {
2380
 
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
2381
 
      {
2382
 
        my_close(file,MYF(0));
2383
 
        my_delete(name,MYF(0));
2384
 
        return(-1);
2385
 
      }
2386
 
    }
2387
 
  }
2388
 
  else
2389
 
  {
2390
 
    if (my_errno == ENOENT)
2391
 
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
2392
 
    else
2393
 
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
2394
 
  }
2395
 
  return (file);
2396
 
} /* create_frm */
2397
 
 
2398
 
/*
2399
 
  Set up column usage bitmaps for a temporary table
2400
 
 
2401
 
  IMPLEMENTATION
2402
 
    For temporary tables, we need one bitmap with all columns set and
2403
 
    a tmp_set bitmap to be used by things like filesort.
2404
 
*/
2405
 
 
2406
 
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
2407
 
{
2408
 
  uint32_t field_count= s->fields;
2409
 
 
2410
 
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count, false);
2411
 
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count, false);
2412
 
 
2413
 
  /* write_set and all_set are copies of read_set */
2414
 
  def_write_set= def_read_set;
2415
 
  s->all_set= def_read_set;
2416
 
  bitmap_set_all(&this->s->all_set);
2417
 
  default_column_bitmaps();
2418
 
}
2419
 
 
2420
 
 
2421
 
 
2422
 
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
2423
 
{
2424
 
  create_info->max_rows= s->max_rows;
2425
 
  create_info->min_rows= s->min_rows;
2426
 
  create_info->table_options= s->db_create_options;
2427
 
  create_info->avg_row_length= s->avg_row_length;
2428
 
  create_info->block_size= s->block_size;
2429
 
  create_info->row_type= s->row_type;
2430
 
  create_info->default_table_charset= s->table_charset;
2431
 
  create_info->table_charset= 0;
2432
 
  create_info->comment= s->comment;
2433
 
 
2434
 
  return;
2435
 
}
2436
 
 
2437
 
int
2438
 
rename_file_ext(const char * from,const char * to,const char * ext)
2439
 
{
2440
 
  char from_b[FN_REFLEN],to_b[FN_REFLEN];
2441
 
  strxmov(from_b,from,ext,NULL);
2442
 
  strxmov(to_b,to,ext,NULL);
2443
 
  return (my_rename(from_b,to_b,MYF(MY_WME)));
2444
 
}
2445
 
 
2446
 
 
2447
 
/*
2448
 
  Allocate string field in MEM_ROOT and return it as String
2449
 
 
2450
 
  SYNOPSIS
2451
 
    get_field()
2452
 
    mem         MEM_ROOT for allocating
2453
 
    field       Field for retrieving of string
2454
 
    res         result String
2455
 
 
2456
 
  RETURN VALUES
2457
 
    1   string is empty
2458
 
    0   all ok
2459
 
*/
2460
 
 
2461
 
bool get_field(MEM_ROOT *mem, Field *field, String *res)
2462
 
{
2463
 
  char buff[MAX_FIELD_WIDTH], *to;
2464
 
  String str(buff,sizeof(buff),&my_charset_bin);
2465
 
  uint32_t length;
2466
 
 
2467
 
  field->val_str(&str);
2468
 
  if (!(length= str.length()))
2469
 
  {
2470
 
    res->length(0);
2471
 
    return 1;
2472
 
  }
2473
 
  if (!(to= strmake_root(mem, str.ptr(), length)))
2474
 
    length= 0;                                  // Safety fix
2475
 
  res->set(to, length, ((Field_str*)field)->charset());
2476
 
  return 0;
2477
 
}
2478
 
 
2479
 
 
2480
 
/*
2481
 
  Allocate string field in MEM_ROOT and return it as NULL-terminated string
2482
 
 
2483
 
  SYNOPSIS
2484
 
    get_field()
2485
 
    mem         MEM_ROOT for allocating
2486
 
    field       Field for retrieving of string
2487
 
 
2488
 
  RETURN VALUES
2489
 
    NULL  string is empty
2490
 
    #      pointer to NULL-terminated string value of field
2491
 
*/
2492
 
 
2493
 
char *get_field(MEM_ROOT *mem, Field *field)
2494
 
{
2495
 
  char buff[MAX_FIELD_WIDTH], *to;
2496
 
  String str(buff,sizeof(buff),&my_charset_bin);
2497
 
  uint32_t length;
2498
 
 
2499
 
  field->val_str(&str);
2500
 
  length= str.length();
2501
 
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
2502
 
    return NULL;
2503
 
  memcpy(to,str.ptr(),(uint) length);
2504
 
  to[length]=0;
2505
 
  return to;
2506
 
}
2507
 
 
2508
 
/*
2509
 
  DESCRIPTION
2510
 
    given a buffer with a key value, and a map of keyparts
2511
 
    that are present in this value, returns the length of the value
2512
 
*/
2513
 
uint32_t calculate_key_len(Table *table, uint32_t key,
2514
 
                       const unsigned char *,
2515
 
                       key_part_map keypart_map)
2516
 
{
2517
 
  /* works only with key prefixes */
2518
 
  assert(((keypart_map + 1) & keypart_map) == 0);
2519
 
 
2520
 
  KEY *key_info= table->s->key_info+key;
2521
 
  KEY_PART_INFO *key_part= key_info->key_part;
2522
 
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
2523
 
  uint32_t length= 0;
2524
 
 
2525
 
  while (key_part < end_key_part && keypart_map)
2526
 
  {
2527
 
    length+= key_part->store_length;
2528
 
    keypart_map >>= 1;
2529
 
    key_part++;
2530
 
  }
2531
 
  return length;
2532
 
}
2533
 
 
2534
 
/*
2535
 
  Check if database name is valid
2536
 
 
2537
 
  SYNPOSIS
2538
 
    check_db_name()
2539
 
    org_name            Name of database and length
2540
 
 
2541
 
  NOTES
2542
 
    If lower_case_table_names is set then database is converted to lower case
2543
 
 
2544
 
  RETURN
2545
 
    0   ok
2546
 
    1   error
2547
 
*/
2548
 
 
2549
 
bool check_db_name(LEX_STRING *org_name)
2550
 
{
2551
 
  char *name= org_name->str;
2552
 
  uint32_t name_length= org_name->length;
2553
 
 
2554
 
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
2555
 
    return 1;
2556
 
 
2557
 
  if (lower_case_table_names && name != any_db)
2558
 
    my_casedn_str(files_charset_info, name);
2559
 
 
2560
 
  return check_identifier_name(org_name);
2561
 
}
2562
 
 
2563
 
 
2564
304
/*
2565
305
  Allow anything as a table name, as long as it doesn't contain an
2566
306
  ' ' at the end
2567
307
  returns 1 on error
2568
308
*/
2569
 
 
2570
 
 
2571
309
bool check_table_name(const char *name, uint32_t length)
2572
310
{
2573
311
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
2574
312
    return 1;
2575
 
  LEX_STRING ident;
 
313
  lex_string_t ident;
2576
314
  ident.str= (char*) name;
2577
315
  ident.length= length;
2578
316
  return check_identifier_name(&ident);
2588
326
{
2589
327
  uint32_t name_length= 0;  // name length in symbols
2590
328
  bool last_char_is_space= true;
2591
 
  
 
329
 
2592
330
  while (*name)
2593
331
  {
2594
 
#if defined(USE_MB) && defined(USE_MB_IDENT)
2595
332
    last_char_is_space= my_isspace(system_charset_info, *name);
2596
333
    if (use_mb(system_charset_info))
2597
334
    {
2598
 
      int len=my_ismbchar(system_charset_info, name, 
 
335
      int len=my_ismbchar(system_charset_info, name,
2599
336
                          name+system_charset_info->mbmaxlen);
2600
337
      if (len)
2601
338
      {
2606
343
        continue;
2607
344
      }
2608
345
    }
2609
 
#else
2610
 
    last_char_is_space= *name==' ';
2611
 
#endif
2612
346
    /*
2613
347
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
2614
348
      It is defined as 0xFF, which is a not valid byte in utf8.
2620
354
    name_length++;
2621
355
  }
2622
356
  /* Error if empty or too long column name */
2623
 
  return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
2624
 
}
2625
 
 
2626
 
 
2627
 
/**
2628
 
  Checks whether a table is intact. Should be done *just* after the table has
2629
 
  been opened.
2630
 
 
2631
 
  @param[in] table             The table to check
2632
 
  @param[in] table_f_count     Expected number of columns in the table
2633
 
  @param[in] table_def         Expected structure of the table (column name
2634
 
                               and type)
2635
 
 
2636
 
  @retval  false  OK
2637
 
  @retval  TRUE   There was an error. An error message is output
2638
 
                  to the error log.  We do not push an error
2639
 
                  message into the error stack because this
2640
 
                  function is currently only called at start up,
2641
 
                  and such errors never reach the user.
2642
 
*/
2643
 
 
2644
 
bool
2645
 
Table::table_check_intact(const uint32_t table_f_count,
2646
 
                          const TABLE_FIELD_W_TYPE *table_def)
2647
 
{
2648
 
  uint32_t i;
2649
 
  bool error= false;
2650
 
  bool fields_diff_count;
2651
 
 
2652
 
  fields_diff_count= (s->fields != table_f_count);
2653
 
  if (fields_diff_count)
2654
 
  {
2655
 
 
2656
 
    /* previous MySQL version */
2657
 
    if (DRIZZLE_VERSION_ID > s->mysql_version)
2658
 
    {
2659
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2660
 
                      alias, table_f_count, s->fields,
2661
 
                      s->mysql_version, DRIZZLE_VERSION_ID);
2662
 
      return(true);
2663
 
    }
2664
 
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
2665
 
    {
2666
 
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2667
 
                      table_f_count, s->fields);
2668
 
      return(true);
2669
 
    }
2670
 
    /*
2671
 
      Something has definitely changed, but we're running an older
2672
 
      version of MySQL with new system tables.
2673
 
      Let's check column definitions. If a column was added at
2674
 
      the end of the table, then we don't care much since such change
2675
 
      is backward compatible.
2676
 
    */
2677
 
  }
2678
 
  char buffer[STRING_BUFFER_USUAL_SIZE];
2679
 
  for (i=0 ; i < table_f_count; i++, table_def++)
2680
 
  {
2681
 
    String sql_type(buffer, sizeof(buffer), system_charset_info);
2682
 
    sql_type.length(0);
2683
 
    if (i < s->fields)
2684
 
    {
2685
 
      Field *field= this->field[i];
2686
 
 
2687
 
      if (strncmp(field->field_name, table_def->name.str,
2688
 
                  table_def->name.length))
2689
 
      {
2690
 
        /*
2691
 
          Name changes are not fatal, we use ordinal numbers to access columns.
2692
 
          Still this can be a sign of a tampered table, output an error
2693
 
          to the error log.
2694
 
        */
2695
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
2696
 
                        "expected column '%s' at position %d, found '%s'."),
2697
 
                        s->db.str, alias, table_def->name.str, i,
2698
 
                        field->field_name);
2699
 
      }
2700
 
      field->sql_type(sql_type);
2701
 
      /*
2702
 
        Generally, if column types don't match, then something is
2703
 
        wrong.
2704
 
 
2705
 
        However, we only compare column definitions up to the
2706
 
        length of the original definition, since we consider the
2707
 
        following definitions compatible:
2708
 
 
2709
 
        1. DATETIME and DATETIM
2710
 
        2. INT(11) and INT(11
2711
 
        3. SET('one', 'two') and SET('one', 'two', 'more')
2712
 
 
2713
 
        For SETs or ENUMs, if the same prefix is there it's OK to
2714
 
        add more elements - they will get higher ordinal numbers and
2715
 
        the new table definition is backward compatible with the
2716
 
        original one.
2717
 
       */
2718
 
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2719
 
                  table_def->type.length - 1))
2720
 
      {
2721
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
2722
 
                        "expected column '%s' at position %d to have type "
2723
 
                        "%s, found type %s."), s->db.str, alias,
2724
 
                        table_def->name.str, i, table_def->type.str,
2725
 
                        sql_type.c_ptr_safe());
2726
 
        error= true;
2727
 
      }
2728
 
      else if (table_def->cset.str && !field->has_charset())
2729
 
      {
2730
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
2731
 
                        "expected the type of column '%s' at position %d "
2732
 
                        "to have character set '%s' but the type has no "
2733
 
                        "character set."), s->db.str, alias,
2734
 
                        table_def->name.str, i, table_def->cset.str);
2735
 
        error= true;
2736
 
      }
2737
 
      else if (table_def->cset.str &&
2738
 
               strcmp(field->charset()->csname, table_def->cset.str))
2739
 
      {
2740
 
        sql_print_error(_("Incorrect definition of table %s.%s: "
2741
 
                        "expected the type of column '%s' at position %d "
2742
 
                        "to have character set '%s' but found "
2743
 
                        "character set '%s'."), s->db.str, alias,
2744
 
                        table_def->name.str, i, table_def->cset.str,
2745
 
                        field->charset()->csname);
2746
 
        error= true;
2747
 
      }
2748
 
    }
2749
 
    else
2750
 
    {
2751
 
      sql_print_error(_("Incorrect definition of table %s.%s: "
2752
 
                      "expected column '%s' at position %d to have type %s "
2753
 
                      " but the column is not found."),
2754
 
                      s->db.str, alias,
2755
 
                      table_def->name.str, i, table_def->type.str);
2756
 
      error= true;
2757
 
    }
2758
 
  }
2759
 
  return(error);
2760
 
}
2761
 
 
2762
 
 
2763
 
/*
2764
 
  Create Item_field for each column in the table.
2765
 
 
2766
 
  SYNPOSIS
2767
 
    Table::fill_item_list()
2768
 
      item_list          a pointer to an empty list used to store items
2769
 
 
2770
 
  DESCRIPTION
2771
 
    Create Item_field object for each column in the table and
2772
 
    initialize it with the corresponding Field. New items are
2773
 
    created in the current Session memory root.
2774
 
 
2775
 
  RETURN VALUE
2776
 
    0                    success
2777
 
    1                    out of memory
2778
 
*/
2779
 
 
2780
 
bool Table::fill_item_list(List<Item> *item_list) const
2781
 
{
2782
 
  /*
2783
 
    All Item_field's created using a direct pointer to a field
2784
 
    are fixed in Item_field constructor.
2785
 
  */
2786
 
  for (Field **ptr= field; *ptr; ptr++)
2787
 
  {
2788
 
    Item_field *item= new Item_field(*ptr);
2789
 
    if (!item || item_list->push_back(item))
2790
 
      return true;
2791
 
  }
2792
 
  return false;
2793
 
}
2794
 
 
2795
 
/*
2796
 
  Reset an existing list of Item_field items to point to the
2797
 
  Fields of this table.
2798
 
 
2799
 
  SYNPOSIS
2800
 
    Table::fill_item_list()
2801
 
      item_list          a non-empty list with Item_fields
2802
 
 
2803
 
  DESCRIPTION
2804
 
    This is a counterpart of fill_item_list used to redirect
2805
 
    Item_fields to the fields of a newly created table.
2806
 
    The caller must ensure that number of items in the item_list
2807
 
    is the same as the number of columns in the table.
2808
 
*/
2809
 
 
2810
 
void Table::reset_item_list(List<Item> *item_list) const
2811
 
{
2812
 
  List_iterator_fast<Item> it(*item_list);
2813
 
  for (Field **ptr= field; *ptr; ptr++)
2814
 
  {
2815
 
    Item_field *item_field= (Item_field*) it++;
2816
 
    assert(item_field != 0);
2817
 
    item_field->reset_field(*ptr);
2818
 
  }
2819
 
}
2820
 
 
2821
 
 
2822
 
/*
2823
 
  Find underlying base tables (TableList) which represent given
2824
 
  table_to_find (Table)
2825
 
 
2826
 
  SYNOPSIS
2827
 
    TableList::find_underlying_table()
2828
 
    table_to_find table to find
2829
 
 
2830
 
  RETURN
2831
 
    0  table is not found
2832
 
    found table reference
2833
 
*/
2834
 
 
2835
 
TableList *TableList::find_underlying_table(Table *table_to_find)
2836
 
{
2837
 
  /* is this real table and table which we are looking for? */
2838
 
  if (table == table_to_find && merge_underlying_list == 0)
2839
 
    return this;
2840
 
 
2841
 
  for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
2842
 
  {
2843
 
    TableList *result;
2844
 
    if ((result= tbl->find_underlying_table(table_to_find)))
2845
 
      return result;
2846
 
  }
2847
 
  return 0;
2848
 
}
2849
 
 
2850
 
/*
2851
 
  cleunup items belonged to view fields translation table
2852
 
 
2853
 
  SYNOPSIS
2854
 
    TableList::cleanup_items()
2855
 
*/
2856
 
 
2857
 
void TableList::cleanup_items()
2858
 
{
2859
 
  if (!field_translation)
2860
 
    return;
2861
 
 
2862
 
  for (Field_translator *transl= field_translation;
2863
 
       transl < field_translation_end;
2864
 
       transl++)
2865
 
    transl->item->walk(&Item::cleanup_processor, 0, 0);
2866
 
}
2867
 
 
2868
 
 
2869
 
bool TableList::placeholder()
2870
 
{
2871
 
  return derived || schema_table || (create && !table->getDBStat()) || !table;
2872
 
}
2873
 
 
2874
 
 
2875
 
/*
2876
 
  Set insert_values buffer
2877
 
 
2878
 
  SYNOPSIS
2879
 
    set_insert_values()
2880
 
    mem_root   memory pool for allocating
2881
 
 
2882
 
  RETURN
2883
 
    false - OK
2884
 
    TRUE  - out of memory
2885
 
*/
2886
 
 
2887
 
bool TableList::set_insert_values(MEM_ROOT *mem_root)
2888
 
{
2889
 
  if (table)
2890
 
  {
2891
 
    if (!table->insert_values &&
2892
 
        !(table->insert_values= (unsigned char *)alloc_root(mem_root,
2893
 
                                                   table->s->rec_buff_length)))
2894
 
      return true;
2895
 
  }
2896
 
 
2897
 
  return false;
2898
 
}
2899
 
 
2900
 
 
2901
 
/*
2902
 
  Test if this is a leaf with respect to name resolution.
2903
 
 
2904
 
  SYNOPSIS
2905
 
    TableList::is_leaf_for_name_resolution()
2906
 
 
2907
 
  DESCRIPTION
2908
 
    A table reference is a leaf with respect to name resolution if
2909
 
    it is either a leaf node in a nested join tree (table, view,
2910
 
    schema table, subquery), or an inner node that represents a
2911
 
    NATURAL/USING join, or a nested join with materialized join
2912
 
    columns.
2913
 
 
2914
 
  RETURN
2915
 
    TRUE if a leaf, false otherwise.
2916
 
*/
2917
 
bool TableList::is_leaf_for_name_resolution()
2918
 
{
2919
 
  return (is_natural_join || is_join_columns_complete || !nested_join);
2920
 
}
2921
 
 
2922
 
 
2923
 
/*
2924
 
  Retrieve the first (left-most) leaf in a nested join tree with
2925
 
  respect to name resolution.
2926
 
 
2927
 
  SYNOPSIS
2928
 
    TableList::first_leaf_for_name_resolution()
2929
 
 
2930
 
  DESCRIPTION
2931
 
    Given that 'this' is a nested table reference, recursively walk
2932
 
    down the left-most children of 'this' until we reach a leaf
2933
 
    table reference with respect to name resolution.
2934
 
 
2935
 
  IMPLEMENTATION
2936
 
    The left-most child of a nested table reference is the last element
2937
 
    in the list of children because the children are inserted in
2938
 
    reverse order.
2939
 
 
2940
 
  RETURN
2941
 
    If 'this' is a nested table reference - the left-most child of
2942
 
      the tree rooted in 'this',
2943
 
    else return 'this'
2944
 
*/
2945
 
 
2946
 
TableList *TableList::first_leaf_for_name_resolution()
2947
 
{
2948
 
  TableList *cur_table_ref= NULL;
2949
 
  nested_join_st *cur_nested_join;
2950
 
 
2951
 
  if (is_leaf_for_name_resolution())
2952
 
    return this;
2953
 
  assert(nested_join);
2954
 
 
2955
 
  for (cur_nested_join= nested_join;
2956
 
       cur_nested_join;
2957
 
       cur_nested_join= cur_table_ref->nested_join)
2958
 
  {
2959
 
    List_iterator_fast<TableList> it(cur_nested_join->join_list);
2960
 
    cur_table_ref= it++;
2961
 
    /*
2962
 
      If the current nested join is a RIGHT JOIN, the operands in
2963
 
      'join_list' are in reverse order, thus the first operand is
2964
 
      already at the front of the list. Otherwise the first operand
2965
 
      is in the end of the list of join operands.
2966
 
    */
2967
 
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2968
 
    {
2969
 
      TableList *next;
2970
 
      while ((next= it++))
2971
 
        cur_table_ref= next;
2972
 
    }
2973
 
    if (cur_table_ref->is_leaf_for_name_resolution())
2974
 
      break;
2975
 
  }
2976
 
  return cur_table_ref;
2977
 
}
2978
 
 
2979
 
 
2980
 
/*
2981
 
  Retrieve the last (right-most) leaf in a nested join tree with
2982
 
  respect to name resolution.
2983
 
 
2984
 
  SYNOPSIS
2985
 
    TableList::last_leaf_for_name_resolution()
2986
 
 
2987
 
  DESCRIPTION
2988
 
    Given that 'this' is a nested table reference, recursively walk
2989
 
    down the right-most children of 'this' until we reach a leaf
2990
 
    table reference with respect to name resolution.
2991
 
 
2992
 
  IMPLEMENTATION
2993
 
    The right-most child of a nested table reference is the first
2994
 
    element in the list of children because the children are inserted
2995
 
    in reverse order.
2996
 
 
2997
 
  RETURN
2998
 
    - If 'this' is a nested table reference - the right-most child of
2999
 
      the tree rooted in 'this',
3000
 
    - else - 'this'
3001
 
*/
3002
 
 
3003
 
TableList *TableList::last_leaf_for_name_resolution()
3004
 
{
3005
 
  TableList *cur_table_ref= this;
3006
 
  nested_join_st *cur_nested_join;
3007
 
 
3008
 
  if (is_leaf_for_name_resolution())
3009
 
    return this;
3010
 
  assert(nested_join);
3011
 
 
3012
 
  for (cur_nested_join= nested_join;
3013
 
       cur_nested_join;
3014
 
       cur_nested_join= cur_table_ref->nested_join)
3015
 
  {
3016
 
    cur_table_ref= cur_nested_join->join_list.head();
3017
 
    /*
3018
 
      If the current nested is a RIGHT JOIN, the operands in
3019
 
      'join_list' are in reverse order, thus the last operand is in the
3020
 
      end of the list.
3021
 
    */
3022
 
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
3023
 
    {
3024
 
      List_iterator_fast<TableList> it(cur_nested_join->join_list);
3025
 
      TableList *next;
3026
 
      cur_table_ref= it++;
3027
 
      while ((next= it++))
3028
 
        cur_table_ref= next;
3029
 
    }
3030
 
    if (cur_table_ref->is_leaf_for_name_resolution())
3031
 
      break;
3032
 
  }
3033
 
  return cur_table_ref;
 
357
  return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
3034
358
}
3035
359
 
3036
360
 
3047
371
    bitmap_clear_all(&table->def_read_set);
3048
372
    bitmap_clear_all(&table->def_write_set);
3049
373
  */
3050
 
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
3051
 
  column_bitmaps_set(&def_read_set, &def_write_set);
 
374
  def_read_set.reset();
 
375
  def_write_set.reset();
 
376
  column_bitmaps_set(def_read_set, def_write_set);
3052
377
}
3053
378
 
3054
379
 
3055
380
/*
3056
 
  Tell handler we are going to call position() and rnd_pos() later.
3057
 
  
 
381
  Tell Cursor we are going to call position() and rnd_pos() later.
 
382
 
3058
383
  NOTES:
3059
384
  This is needed for handlers that uses the primary key to find the
3060
385
  row. In this case we have to extend the read bitmap with the primary
3064
389
void Table::prepare_for_position()
3065
390
{
3066
391
 
3067
 
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
3068
 
      s->primary_key < MAX_KEY)
 
392
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
 
393
      getShare()->hasPrimaryKey())
3069
394
  {
3070
 
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3071
 
    /* signal change */
3072
 
    file->column_bitmaps_signal();
 
395
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
3073
396
  }
3074
397
  return;
3075
398
}
3087
410
 
3088
411
void Table::mark_columns_used_by_index(uint32_t index)
3089
412
{
3090
 
  MY_BITMAP *bitmap= &tmp_set;
 
413
  boost::dynamic_bitset<> *bitmap= &tmp_set;
3091
414
 
3092
 
  (void) file->extra(HA_EXTRA_KEYREAD);
3093
 
  bitmap_clear_all(bitmap);
3094
 
  mark_columns_used_by_index_no_reset(index, bitmap);
3095
 
  column_bitmaps_set(bitmap, bitmap);
 
415
  (void) cursor->extra(HA_EXTRA_KEYREAD);
 
416
  bitmap->reset();
 
417
  mark_columns_used_by_index_no_reset(index, *bitmap);
 
418
  column_bitmaps_set(*bitmap, *bitmap);
3096
419
  return;
3097
420
}
3098
421
 
3112
435
{
3113
436
 
3114
437
  key_read= 0;
3115
 
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
 
438
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
3116
439
  default_column_bitmaps();
3117
 
  file->column_bitmaps_signal();
3118
440
  return;
3119
441
}
3120
442
 
3123
445
  mark columns used by key, but don't reset other fields
3124
446
*/
3125
447
 
 
448
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
 
449
{
 
450
    mark_columns_used_by_index_no_reset(index, *read_set);
 
451
}
 
452
 
 
453
 
3126
454
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
3127
 
                                                   MY_BITMAP *bitmap)
 
455
                                                boost::dynamic_bitset<>& bitmap)
3128
456
{
3129
 
  KEY_PART_INFO *key_part= key_info[index].key_part;
3130
 
  KEY_PART_INFO *key_part_end= (key_part +
3131
 
                                key_info[index].key_parts);
3132
 
  for (;key_part != key_part_end; key_part++)
 
457
  KeyPartInfo *key_part= key_info[index].key_part;
 
458
  KeyPartInfo *key_part_end= (key_part + key_info[index].key_parts);
 
459
  for (; key_part != key_part_end; key_part++)
3133
460
  {
3134
 
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
3135
 
    if (key_part->field->vcol_info &&
3136
 
        key_part->field->vcol_info->expr_item)
3137
 
      key_part->field->vcol_info->
3138
 
               expr_item->walk(&Item::register_field_in_bitmap, 
3139
 
                               1, (unsigned char *) bitmap);
 
461
    if (! bitmap.empty())
 
462
      bitmap.set(key_part->fieldnr-1);
3140
463
  }
3141
464
}
3142
465
 
3156
479
    We must set bit in read set as update_auto_increment() is using the
3157
480
    store() to check overflow of auto_increment values
3158
481
  */
3159
 
  bitmap_set_bit(read_set, found_next_number_field->field_index);
3160
 
  bitmap_set_bit(write_set, found_next_number_field->field_index);
3161
 
  if (s->next_number_keypart)
3162
 
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
3163
 
  file->column_bitmaps_signal();
 
482
  setReadSet(found_next_number_field->position());
 
483
  setWriteSet(found_next_number_field->position());
 
484
  if (getShare()->next_number_keypart)
 
485
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
3164
486
}
3165
487
 
3166
488
 
3184
506
 
3185
507
void Table::mark_columns_needed_for_delete()
3186
508
{
3187
 
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
 
509
  /*
 
510
    If the Cursor has no cursor capabilites, or we have row-based
 
511
    replication active for the current statement, we have to read
 
512
    either the primary key, the hidden primary key or all columns to
 
513
    be able to do an delete
 
514
 
 
515
  */
 
516
  if (not getShare()->hasPrimaryKey())
 
517
  {
 
518
    /* fallback to use all columns in the table to identify row */
 
519
    use_all_columns();
 
520
    return;
 
521
  }
 
522
  else
 
523
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
524
 
 
525
  /* If we the engine wants all predicates we mark all keys */
 
526
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
3188
527
  {
3189
528
    Field **reg_field;
3190
529
    for (reg_field= field ; *reg_field ; reg_field++)
3191
530
    {
3192
531
      if ((*reg_field)->flags & PART_KEY_FLAG)
3193
 
        bitmap_set_bit(read_set, (*reg_field)->field_index);
3194
 
    }
3195
 
    file->column_bitmaps_signal();
3196
 
  }
3197
 
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE || (drizzle_bin_log.is_open() && in_use))
3198
 
  {
3199
 
    /*
3200
 
      If the handler has no cursor capabilites, or we have row-based
3201
 
      replication active for the current statement, we have to read
3202
 
      either the primary key, the hidden primary key or all columns to
3203
 
      be able to do an delete
3204
 
    */
3205
 
    if (s->primary_key == MAX_KEY)
3206
 
      file->use_hidden_primary_key();
3207
 
    else
3208
 
    {
3209
 
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3210
 
      file->column_bitmaps_signal();
 
532
        setReadSet((*reg_field)->position());
3211
533
    }
3212
534
  }
3213
535
}
3225
547
    if neeed, either the primary key column or all columns to be read.
3226
548
    (see mark_columns_needed_for_delete() for details)
3227
549
 
3228
 
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
550
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
3229
551
    mark all USED key columns as 'to-be-read'. This allows the engine to
3230
552
    loop over the given record to find all changed keys and doesn't have to
3231
553
    retrieve the row again.
3233
555
 
3234
556
void Table::mark_columns_needed_for_update()
3235
557
{
3236
 
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
 
558
  /*
 
559
    If the Cursor has no cursor capabilites, or we have row-based
 
560
    logging active for the current statement, we have to read either
 
561
    the primary key, the hidden primary key or all columns to be
 
562
    able to do an update
 
563
  */
 
564
  if (not getShare()->hasPrimaryKey())
 
565
  {
 
566
    /* fallback to use all columns in the table to identify row */
 
567
    use_all_columns();
 
568
    return;
 
569
  }
 
570
  else
 
571
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
572
 
 
573
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
3237
574
  {
3238
575
    /* Mark all used key columns for read */
3239
576
    Field **reg_field;
3240
577
    for (reg_field= field ; *reg_field ; reg_field++)
3241
578
    {
3242
579
      /* Merge keys is all keys that had a column refered to in the query */
3243
 
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
3244
 
        bitmap_set_bit(read_set, (*reg_field)->field_index);
3245
 
    }
3246
 
    file->column_bitmaps_signal();
3247
 
  }
3248
 
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) ||
3249
 
      (drizzle_bin_log.is_open() && in_use))
3250
 
  {
3251
 
    /*
3252
 
      If the handler has no cursor capabilites, or we have row-based
3253
 
      logging active for the current statement, we have to read either
3254
 
      the primary key, the hidden primary key or all columns to be
3255
 
      able to do an update
3256
 
    */
3257
 
    if (s->primary_key == MAX_KEY)
3258
 
      file->use_hidden_primary_key();
3259
 
    else
3260
 
    {
3261
 
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
3262
 
      file->column_bitmaps_signal();
3263
 
    }
3264
 
  }
3265
 
  /* Mark all virtual columns as writable */
3266
 
  mark_virtual_columns();
3267
 
  return;
 
580
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
 
581
        setReadSet((*reg_field)->position());
 
582
    }
 
583
  }
 
584
 
3268
585
}
3269
586
 
3270
587
 
3271
588
/*
3272
 
  Mark columns the handler needs for doing an insert
 
589
  Mark columns the Cursor needs for doing an insert
3273
590
 
3274
591
  For now, this is used to mark fields used by the trigger
3275
592
  as changed.
3279
596
{
3280
597
  if (found_next_number_field)
3281
598
    mark_auto_increment_column();
3282
 
  /* Mark all virtual columns as writable */
3283
 
  mark_virtual_columns();
3284
 
}
3285
 
 
3286
 
/* 
3287
 
  @brief Update the write and read table bitmap to allow
3288
 
         using procedure save_in_field for all virtual columns
3289
 
         in the table.
3290
 
 
3291
 
  @return       void
3292
 
 
3293
 
  @detail
3294
 
    Each virtual field is set in the write column map.
3295
 
    All fields that the virtual columns are based on are set in the
3296
 
    read bitmap.
3297
 
*/
3298
 
 
3299
 
void Table::mark_virtual_columns(void)
3300
 
{
3301
 
  Field **vfield_ptr, *tmp_vfield;
3302
 
  bool bitmap_updated= false;
3303
 
 
3304
 
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
3305
 
  {
3306
 
    tmp_vfield= *vfield_ptr;
3307
 
    assert(tmp_vfield->vcol_info && tmp_vfield->vcol_info->expr_item);
3308
 
    tmp_vfield->vcol_info->expr_item->walk(&Item::register_field_in_read_map, 
3309
 
                                           1, (unsigned char *) 0);
3310
 
    bitmap_set_bit(read_set, tmp_vfield->field_index);
3311
 
    bitmap_set_bit(write_set, tmp_vfield->field_index);
3312
 
    bitmap_updated= true;
3313
 
  }
3314
 
  if (bitmap_updated)
3315
 
    file->column_bitmaps_signal();
3316
 
}
3317
 
 
3318
 
 
3319
 
/*
3320
 
  Cleanup this table for re-execution.
3321
 
 
3322
 
  SYNOPSIS
3323
 
    TableList::reinit_before_use()
3324
 
*/
3325
 
 
3326
 
void TableList::reinit_before_use(Session *session)
3327
 
{
3328
 
  /*
3329
 
    Reset old pointers to TABLEs: they are not valid since the tables
3330
 
    were closed in the end of previous prepare or execute call.
3331
 
  */
3332
 
  table= 0;
3333
 
  /* Reset is_schema_table_processed value(needed for I_S tables */
3334
 
  schema_table_state= NOT_PROCESSED;
3335
 
 
3336
 
  TableList *embedded; /* The table at the current level of nesting. */
3337
 
  TableList *parent_embedding= this; /* The parent nested table reference. */
3338
 
  do
3339
 
  {
3340
 
    embedded= parent_embedding;
3341
 
    if (embedded->prep_on_expr)
3342
 
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
3343
 
    parent_embedding= embedded->embedding;
3344
 
  }
3345
 
  while (parent_embedding &&
3346
 
         parent_embedding->nested_join->join_list.head() == embedded);
3347
 
}
3348
 
 
3349
 
/*
3350
 
  Return subselect that contains the FROM list this table is taken from
3351
 
 
3352
 
  SYNOPSIS
3353
 
    TableList::containing_subselect()
3354
 
 
3355
 
  RETURN
3356
 
    Subselect item for the subquery that contains the FROM list
3357
 
    this table is taken from if there is any
3358
 
    0 - otherwise
3359
 
 
3360
 
*/
3361
 
 
3362
 
Item_subselect *TableList::containing_subselect()
3363
 
{    
3364
 
  return (select_lex ? select_lex->master_unit()->item : 0);
3365
 
}
3366
 
 
3367
 
/*
3368
 
  Compiles the tagged hints list and fills up the bitmasks.
3369
 
 
3370
 
  SYNOPSIS
3371
 
    process_index_hints()
3372
 
      table         the Table to operate on.
3373
 
 
3374
 
  DESCRIPTION
3375
 
    The parser collects the index hints for each table in a "tagged list" 
3376
 
    (TableList::index_hints). Using the information in this tagged list
3377
 
    this function sets the members Table::keys_in_use_for_query, 
3378
 
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
3379
 
    Table::force_index and Table::covering_keys.
3380
 
 
3381
 
    Current implementation of the runtime does not allow mixing FORCE INDEX
3382
 
    and USE INDEX, so this is checked here. Then the FORCE INDEX list 
3383
 
    (if non-empty) is appended to the USE INDEX list and a flag is set.
3384
 
 
3385
 
    Multiple hints of the same kind are processed so that each clause 
3386
 
    is applied to what is computed in the previous clause.
3387
 
    For example:
3388
 
        USE INDEX (i1) USE INDEX (i2)
3389
 
    is equivalent to
3390
 
        USE INDEX (i1,i2)
3391
 
    and means "consider only i1 and i2".
3392
 
        
3393
 
    Similarly
3394
 
        USE INDEX () USE INDEX (i1)
3395
 
    is equivalent to
3396
 
        USE INDEX (i1)
3397
 
    and means "consider only the index i1"
3398
 
 
3399
 
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
3400
 
    not an error.
3401
 
        
3402
 
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
3403
 
    order:
3404
 
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
3405
 
      2. All IGNORE INDEX
3406
 
 
3407
 
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
3408
 
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
3409
 
 
3410
 
    As an optimization if there is a covering index, and we have 
3411
 
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part, 
3412
 
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
3413
 
 
3414
 
  RETURN VALUE
3415
 
    false                no errors found
3416
 
    TRUE                 found and reported an error.
3417
 
*/
3418
 
bool TableList::process_index_hints(Table *tbl)
3419
 
{
3420
 
  /* initialize the result variables */
3421
 
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
3422
 
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
3423
 
 
3424
 
  /* index hint list processing */
3425
 
  if (index_hints)
3426
 
  {
3427
 
    key_map index_join[INDEX_HINT_FORCE + 1];
3428
 
    key_map index_order[INDEX_HINT_FORCE + 1];
3429
 
    key_map index_group[INDEX_HINT_FORCE + 1];
3430
 
    Index_hint *hint;
3431
 
    int type;
3432
 
    bool have_empty_use_join= false, have_empty_use_order= false, 
3433
 
         have_empty_use_group= false;
3434
 
    List_iterator <Index_hint> iter(*index_hints);
3435
 
 
3436
 
    /* initialize temporary variables used to collect hints of each kind */
3437
 
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
3438
 
    {
3439
 
      index_join[type].clear_all();
3440
 
      index_order[type].clear_all();
3441
 
      index_group[type].clear_all();
3442
 
    }
3443
 
 
3444
 
    /* iterate over the hints list */
3445
 
    while ((hint= iter++))
3446
 
    {
3447
 
      uint32_t pos;
3448
 
 
3449
 
      /* process empty USE INDEX () */
3450
 
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
3451
 
      {
3452
 
        if (hint->clause & INDEX_HINT_MASK_JOIN)
3453
 
        {
3454
 
          index_join[hint->type].clear_all();
3455
 
          have_empty_use_join= true;
3456
 
        }
3457
 
        if (hint->clause & INDEX_HINT_MASK_ORDER)
3458
 
        {
3459
 
          index_order[hint->type].clear_all();
3460
 
          have_empty_use_order= true;
3461
 
        }
3462
 
        if (hint->clause & INDEX_HINT_MASK_GROUP)
3463
 
        {
3464
 
          index_group[hint->type].clear_all();
3465
 
          have_empty_use_group= true;
3466
 
        }
3467
 
        continue;
3468
 
      }
3469
 
 
3470
 
      /* 
3471
 
        Check if an index with the given name exists and get his offset in 
3472
 
        the keys bitmask for the table 
3473
 
      */
3474
 
      if (tbl->s->keynames.type_names == 0 ||
3475
 
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
3476
 
                          hint->key_name.length, 1)) <= 0)
3477
 
      {
3478
 
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
3479
 
        return 1;
3480
 
      }
3481
 
 
3482
 
      pos--;
3483
 
 
3484
 
      /* add to the appropriate clause mask */
3485
 
      if (hint->clause & INDEX_HINT_MASK_JOIN)
3486
 
        index_join[hint->type].set_bit (pos);
3487
 
      if (hint->clause & INDEX_HINT_MASK_ORDER)
3488
 
        index_order[hint->type].set_bit (pos);
3489
 
      if (hint->clause & INDEX_HINT_MASK_GROUP)
3490
 
        index_group[hint->type].set_bit (pos);
3491
 
    }
3492
 
 
3493
 
    /* cannot mix USE INDEX and FORCE INDEX */
3494
 
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3495
 
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3496
 
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
3497
 
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
3498
 
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
3499
 
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
3500
 
    {
3501
 
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
3502
 
               index_hint_type_name[INDEX_HINT_FORCE]);
3503
 
      return 1;
3504
 
    }
3505
 
 
3506
 
    /* process FORCE INDEX as USE INDEX with a flag */
3507
 
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
3508
 
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
3509
 
        !index_group[INDEX_HINT_FORCE].is_clear_all())
3510
 
    {
3511
 
      tbl->force_index= true;
3512
 
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
3513
 
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
3514
 
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
3515
 
    }
3516
 
 
3517
 
    /* apply USE INDEX */
3518
 
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
3519
 
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
3520
 
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
3521
 
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
3522
 
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
3523
 
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
3524
 
 
3525
 
    /* apply IGNORE INDEX */
3526
 
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
3527
 
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
3528
 
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
3529
 
  }
3530
 
 
3531
 
  /* make sure covering_keys don't include indexes disabled with a hint */
3532
 
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
3533
 
  return 0;
3534
 
}
 
599
}
 
600
 
3535
601
 
3536
602
 
3537
603
size_t Table::max_row_length(const unsigned char *data)
3544
610
  {
3545
611
    Field_blob* const blob= (Field_blob*) field[*ptr];
3546
612
    length+= blob->get_length((const unsigned char*)
3547
 
                              (data + blob->offset(record[0]))) +
 
613
                              (data + blob->offset(getInsertRecord()))) +
3548
614
      HA_KEY_BLOB_LENGTH;
3549
615
  }
3550
616
  return length;
3551
617
}
3552
618
 
 
619
void Table::setVariableWidth(void)
 
620
{
 
621
  assert(in_use);
 
622
  if (in_use && in_use->lex().sql_command == SQLCOM_CREATE_TABLE)
 
623
  {
 
624
    getMutableShare()->setVariableWidth();
 
625
    return;
 
626
  }
 
627
 
 
628
  assert(0); // Programming error, you can't set this on a plain old Table.
 
629
}
 
630
 
3553
631
/****************************************************************************
3554
632
 Functions for creating temporary tables.
3555
633
****************************************************************************/
3556
 
 
3557
 
 
3558
 
/* Prototypes */
3559
 
void free_tmp_table(Session *session, Table *entry);
3560
 
 
3561
634
/**
3562
635
  Create field for temporary table from given field.
3563
636
 
3564
 
  @param session               Thread handler
 
637
  @param session               Thread Cursor
3565
638
  @param org_field    field from which new field will be created
3566
639
  @param name         New field name
3567
640
  @param table         Temporary table
3586
659
{
3587
660
  Field *new_field;
3588
661
 
3589
 
  /* 
3590
 
    Make sure that the blob fits into a Field_varstring which has 
3591
 
    2-byte lenght. 
 
662
  /*
 
663
    Make sure that the blob fits into a Field_varstring which has
 
664
    2-byte lenght.
3592
665
  */
3593
 
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
3594
 
      (org_field->flags & BLOB_FLAG))
3595
 
    new_field= new Field_varstring(convert_blob_length,
3596
 
                                   org_field->maybe_null(),
3597
 
                                   org_field->field_name, table->s,
3598
 
                                   org_field->charset());
 
666
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE && (org_field->flags & BLOB_FLAG))
 
667
  {
 
668
    table->setVariableWidth();
 
669
    new_field= new Field_varstring(convert_blob_length, org_field->maybe_null(), org_field->field_name, org_field->charset());
 
670
  }
3599
671
  else
3600
 
    new_field= org_field->new_field(session->mem_root, table,
3601
 
                                    table == org_field->table);
 
672
  {
 
673
    new_field= org_field->new_field(session->mem_root, table, table == org_field->getTable());
 
674
  }
3602
675
  if (new_field)
3603
676
  {
3604
677
    new_field->init(table);
3611
684
    if (org_field->maybe_null() || (item && item->maybe_null))
3612
685
      new_field->flags&= ~NOT_NULL_FLAG;        // Because of outer join
3613
686
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
3614
 
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
 
687
      table->getMutableShare()->db_create_options|= HA_OPTION_PACK_RECORD;
3615
688
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
3616
689
      ((Field_double *) new_field)->not_fixed= true;
3617
690
  }
3620
693
 
3621
694
 
3622
695
/**
3623
 
  Create field for information schema table.
3624
 
 
3625
 
  @param session                Thread handler
3626
 
  @param table          Temporary table
3627
 
  @param item           Item to create a field for
3628
 
 
3629
 
  @retval
3630
 
    0                   on error
3631
 
  @retval
3632
 
    new_created field
3633
 
*/
3634
 
 
3635
 
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
3636
 
{
3637
 
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
3638
 
  {
3639
 
    Field *field;
3640
 
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
3641
 
      field= new Field_blob(item->max_length, item->maybe_null,
3642
 
                            item->name, item->collation.collation);
3643
 
    else
3644
 
      field= new Field_varstring(item->max_length, item->maybe_null,
3645
 
                                 item->name,
3646
 
                                 table->s, item->collation.collation);
3647
 
    if (field)
3648
 
      field->init(table);
3649
 
    return field;
3650
 
  }
3651
 
  return item->tmp_table_field_from_field_type(table, 0);
3652
 
}
3653
 
 
3654
 
 
3655
 
/**
3656
696
  Create a temp table according to a field list.
3657
697
 
3658
698
  Given field pointers are changed to point at tmp_table for
3678
718
                              be used for name resolving; can be "".
3679
719
*/
3680
720
 
3681
 
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
3682
 
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
3683
 
#define RATIO_TO_PACK_ROWS             2
3684
 
 
3685
721
Table *
3686
 
create_tmp_table(Session *session,TMP_TABLE_PARAM *param,List<Item> &fields,
3687
 
                 order_st *group, bool distinct, bool save_sum_fields,
 
722
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
 
723
                 Order *group, bool distinct, bool save_sum_fields,
3688
724
                 uint64_t select_options, ha_rows rows_limit,
3689
 
                 char *table_alias)
 
725
                 const char *table_alias)
3690
726
{
3691
 
  MEM_ROOT *mem_root_save, own_root;
3692
 
  Table *table;
3693
 
  TABLE_SHARE *share;
3694
727
  uint  i,field_count,null_count,null_pack_length;
3695
728
  uint32_t  copy_func_count= param->func_count;
3696
729
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
3697
730
  uint32_t  blob_count,group_null_items, string_count;
3698
 
  uint32_t  temp_pool_slot=MY_BIT_NONE;
3699
731
  uint32_t fieldnr= 0;
3700
732
  ulong reclength, string_total_length;
3701
 
  bool  using_unique_constraint= 0;
3702
 
  bool  use_packed_rows= 0;
 
733
  bool  using_unique_constraint= false;
3703
734
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
3704
 
  char  *tmpname,path[FN_REFLEN];
3705
 
  unsigned char *pos, *group_buff, *bitmaps;
 
735
  unsigned char *pos, *group_buff;
3706
736
  unsigned char *null_flags;
3707
737
  Field **reg_field, **from_field, **default_field;
3708
 
  uint32_t *blob_field;
3709
 
  Copy_field *copy=0;
3710
 
  KEY *keyinfo;
3711
 
  KEY_PART_INFO *key_part_info;
 
738
  CopyField *copy= 0;
 
739
  KeyInfo *keyinfo;
 
740
  KeyPartInfo *key_part_info;
3712
741
  Item **copy_func;
3713
742
  MI_COLUMNDEF *recinfo;
3714
743
  uint32_t total_uneven_bit_length= 0;
3715
744
  bool force_copy_fields= param->force_copy_fields;
3716
 
 
3717
 
  status_var_increment(session->status_var.created_tmp_tables);
3718
 
 
3719
 
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
3720
 
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
3721
 
 
3722
 
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
3723
 
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
3724
 
            (unsigned long)current_pid, temp_pool_slot);
3725
 
  else
3726
 
  {
3727
 
    /* if we run out of slots or we are not using tempool */
3728
 
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
3729
 
            session->thread_id, session->tmp_table++);
3730
 
  }
3731
 
 
3732
 
  /*
3733
 
    No need to change table name to lower case as we are only creating
3734
 
    MyISAM or HEAP tables here
3735
 
  */
3736
 
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
3737
 
 
 
745
  uint64_t max_rows= 0;
 
746
 
 
747
  session->status_var.created_tmp_tables++;
3738
748
 
3739
749
  if (group)
3740
750
  {
3741
 
    if (!param->quick_group)
3742
 
      group=0;                                  // Can't use group key
3743
 
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
 
751
    if (! param->quick_group)
 
752
    {
 
753
      group= 0;                                 // Can't use group key
 
754
    }
 
755
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
3744
756
    {
3745
757
      /*
3746
758
        marker == 4 means two things:
3750
762
      */
3751
763
      (*tmp->item)->marker= 4;
3752
764
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
3753
 
        using_unique_constraint=1;
 
765
        using_unique_constraint= true;
3754
766
    }
3755
767
    if (param->group_length >= MAX_BLOB_WIDTH)
3756
 
      using_unique_constraint=1;
 
768
      using_unique_constraint= true;
3757
769
    if (group)
3758
 
      distinct=0;                               // Can't use distinct
 
770
      distinct= 0;                              // Can't use distinct
3759
771
  }
3760
772
 
3761
773
  field_count=param->field_count+param->func_count+param->sum_func_count;
3765
777
    When loose index scan is employed as access method, it already
3766
778
    computes all groups and the result of all aggregate functions. We
3767
779
    make space for the items of the aggregate function in the list of
3768
 
    functions TMP_TABLE_PARAM::items_to_copy, so that the values of
 
780
    functions Tmp_Table_Param::items_to_copy, so that the values of
3769
781
    these items are stored in the temporary table.
3770
782
  */
3771
783
  if (param->precomputed_group_by)
 
784
  {
3772
785
    copy_func_count+= param->sum_func_count;
3773
 
  
3774
 
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
3775
 
 
3776
 
  if (!multi_alloc_root(&own_root,
3777
 
                        &table, sizeof(*table),
3778
 
                        &share, sizeof(*share),
3779
 
                        &reg_field, sizeof(Field*) * (field_count+1),
3780
 
                        &default_field, sizeof(Field*) * (field_count),
3781
 
                        &blob_field, sizeof(uint)*(field_count+1),
3782
 
                        &from_field, sizeof(Field*)*field_count,
3783
 
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
3784
 
                        &param->keyinfo, sizeof(*param->keyinfo),
3785
 
                        &key_part_info,
3786
 
                        sizeof(*key_part_info)*(param->group_parts+1),
3787
 
                        &param->start_recinfo,
3788
 
                        sizeof(*param->recinfo)*(field_count*2+4),
3789
 
                        &tmpname, (uint) strlen(path)+1,
3790
 
                        &group_buff, (group && ! using_unique_constraint ?
3791
 
                                      param->group_length : 0),
3792
 
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3793
 
                        NULL))
3794
 
  {
3795
 
    if (temp_pool_slot != MY_BIT_NONE)
3796
 
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3797
 
    return(NULL);                               /* purecov: inspected */
3798
 
  }
3799
 
  /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in Session mem_root */
3800
 
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
3801
 
  {
3802
 
    if (temp_pool_slot != MY_BIT_NONE)
3803
 
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
3804
 
    free_root(&own_root, MYF(0));               /* purecov: inspected */
3805
 
    return(NULL);                               /* purecov: inspected */
3806
 
  }
 
786
  }
 
787
 
 
788
  table::Singular* table= &session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
 
789
 
 
790
  table->mem().multi_alloc(0,
 
791
    &default_field, sizeof(Field*) * (field_count),
 
792
    &from_field, sizeof(Field*)*field_count,
 
793
    &copy_func, sizeof(*copy_func)*(copy_func_count+1),
 
794
    &param->keyinfo, sizeof(*param->keyinfo),
 
795
    &key_part_info, sizeof(*key_part_info)*(param->group_parts+1),
 
796
    &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
 
797
    &group_buff, (group && ! using_unique_constraint ? param->group_length : 0),
 
798
    NULL);
 
799
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
 
800
  param->copy_field= copy= new (session->mem_root) CopyField[field_count];
3807
801
  param->items_to_copy= copy_func;
3808
 
  my_stpcpy(tmpname,path);
3809
802
  /* make table according to fields */
3810
803
 
3811
 
  memset(table, 0, sizeof(*table));
3812
 
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
3813
804
  memset(default_field, 0, sizeof(Field*) * (field_count));
3814
805
  memset(from_field, 0, sizeof(Field*)*field_count);
3815
806
 
3816
 
  table->mem_root= own_root;
3817
 
  mem_root_save= session->mem_root;
3818
 
  session->mem_root= &table->mem_root;
 
807
  memory::Root* mem_root_save= session->mem_root;
 
808
  session->mem_root= &table->mem();
3819
809
 
3820
 
  table->field=reg_field;
3821
 
  table->alias= table_alias;
 
810
  table->getMutableShare()->setFields(field_count+1);
 
811
  table->setFields(table->getMutableShare()->getFields(true));
 
812
  reg_field= table->getMutableShare()->getFields(true);
 
813
  table->setAlias(table_alias);
3822
814
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
3823
815
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
3824
816
  table->map=1;
3825
 
  table->temp_pool_slot = temp_pool_slot;
3826
817
  table->copy_blobs= 1;
 
818
  assert(session);
3827
819
  table->in_use= session;
3828
 
  table->quick_keys.init();
3829
 
  table->covering_keys.init();
3830
 
  table->keys_in_use_for_query.init();
 
820
  table->quick_keys.reset();
 
821
  table->covering_keys.reset();
 
822
  table->keys_in_use_for_query.reset();
3831
823
 
3832
 
  table->setShare(share);
3833
 
  init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
3834
 
  share->blob_field= blob_field;
3835
 
  share->blob_ptr_size= portable_sizeof_char_ptr;
3836
 
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
3837
 
  share->table_charset= param->table_charset;
3838
 
  share->primary_key= MAX_KEY;               // Indicate no primary key
3839
 
  share->keys_for_keyread.init();
3840
 
  share->keys_in_use.init();
 
824
  table->getMutableShare()->blob_field.resize(field_count+1);
 
825
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
 
826
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
 
827
  table->getMutableShare()->table_charset= param->table_charset;
 
828
  table->getMutableShare()->keys_for_keyread.reset();
 
829
  table->getMutableShare()->keys_in_use.reset();
3841
830
 
3842
831
  /* Calculate which type of fields we will store in the temporary table */
3843
832
 
3844
833
  reclength= string_total_length= 0;
3845
834
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
3846
 
  param->using_indirect_summary_function=0;
 
835
  param->using_indirect_summary_function= 0;
3847
836
 
3848
 
  List_iterator_fast<Item> li(fields);
3849
 
  Item *item;
 
837
  List<Item>::iterator li(fields.begin());
3850
838
  Field **tmp_from_field=from_field;
3851
 
  while ((item=li++))
 
839
  while (Item* item=li++)
3852
840
  {
3853
841
    Item::Type type=item->type();
3854
842
    if (not_all_columns)
3874
862
    }
3875
863
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
3876
864
    {                                           /* Can't calc group yet */
3877
 
      ((Item_sum*) item)->result_field=0;
3878
 
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
 
865
      ((Item_sum*) item)->result_field= 0;
 
866
      for (i= 0 ; i < ((Item_sum*) item)->arg_count ; i++)
3879
867
      {
3880
868
        Item **argp= ((Item_sum*) item)->args + i;
3881
869
        Item *arg= *argp;
3885
873
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
3886
874
                             tmp_from_field, &default_field[fieldnr],
3887
875
                             group != 0,not_all_columns,
3888
 
                             distinct, 0,
 
876
                             false,
3889
877
                             param->convert_blob_length);
3890
878
          if (!new_field)
3891
879
            goto err;                                   // Should be OOM
3903
891
            string_total_length+= new_field->pack_length();
3904
892
          }
3905
893
          session->mem_root= mem_root_save;
3906
 
          session->change_item_tree(argp, new Item_field(new_field));
3907
 
          session->mem_root= &table->mem_root;
 
894
          *argp= new Item_field(new_field);
 
895
          session->mem_root= &table->mem();
3908
896
          if (!(new_field->flags & NOT_NULL_FLAG))
3909
897
          {
3910
898
            null_count++;
3914
902
            */
3915
903
            (*argp)->maybe_null=1;
3916
904
          }
3917
 
          new_field->field_index= fieldnr++;
 
905
          new_field->setPosition(fieldnr++);
3918
906
        }
3919
907
      }
3920
908
    }
3930
918
        We here distinguish between UNION and multi-table-updates by the fact
3931
919
        that in the later case group is set to the row pointer.
3932
920
      */
3933
 
      Field *new_field= (param->schema_table) ?
3934
 
        create_tmp_field_for_schema(session, item, table) :
 
921
      Field *new_field=
3935
922
        create_tmp_field(session, table, item, type, &copy_func,
3936
923
                         tmp_from_field, &default_field[fieldnr],
3937
924
                         group != 0,
3938
925
                         !force_copy_fields &&
3939
 
                           (not_all_columns || group !=0),
3940
 
                         /*
3941
 
                           If item->marker == 4 then we force create_tmp_field
3942
 
                           to create a 64-bit longs for BIT fields because HEAP
3943
 
                           tables can't index BIT fields directly. We do the same
3944
 
                           for distinct, as we want the distinct index to be
3945
 
                           usable in this case too.
3946
 
                         */
3947
 
                         item->marker == 4 || param->bit_fields_as_long,
 
926
                           (not_all_columns || group != 0),
3948
927
                         force_copy_fields,
3949
928
                         param->convert_blob_length);
3950
929
 
3970
949
        group_null_items++;
3971
950
        new_field->flags|= GROUP_FLAG;
3972
951
      }
3973
 
      new_field->field_index= fieldnr++;
 
952
      new_field->setPosition(fieldnr++);
3974
953
      *(reg_field++)= new_field;
3975
954
    }
3976
955
    if (!--hidden_field_count)
3988
967
      null_count= 0;
3989
968
    }
3990
969
  }
3991
 
  assert(fieldnr == (uint) (reg_field - table->field));
3992
 
  assert(field_count >= (uint) (reg_field - table->field));
 
970
  assert(fieldnr == (uint32_t) (reg_field - table->getFields()));
 
971
  assert(field_count >= (uint32_t) (reg_field - table->getFields()));
3993
972
  field_count= fieldnr;
3994
973
  *reg_field= 0;
3995
974
  *blob_field= 0;                               // End marker
3996
 
  share->fields= field_count;
 
975
  table->getMutableShare()->setFieldSize(field_count);
3997
976
 
3998
977
  /* If result table is small; use a heap */
3999
978
  /* future: storage engine selection can be made dynamic? */
4000
 
  if (blob_count || using_unique_constraint ||
4001
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
4002
 
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
 
979
  if (blob_count || using_unique_constraint || 
 
980
      (session->lex().select_lex.options & SELECT_BIG_RESULT) ||
 
981
      (session->lex().current_select->olap == ROLLUP_TYPE) ||
 
982
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
4003
983
  {
4004
 
    share->db_plugin= ha_lock_engine(0, myisam_hton);
4005
 
    table->file= get_new_handler(share, &table->mem_root,
4006
 
                                 share->db_type());
 
984
    table->getMutableShare()->storage_engine= myisam_engine;
 
985
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
4007
986
    if (group &&
4008
 
        (param->group_parts > table->file->max_key_parts() ||
4009
 
         param->group_length > table->file->max_key_length()))
4010
 
      using_unique_constraint=1;
 
987
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
 
988
         param->group_length > table->cursor->getEngine()->max_key_length()))
 
989
    {
 
990
      using_unique_constraint= true;
 
991
    }
4011
992
  }
4012
993
  else
4013
994
  {
4014
 
    share->db_plugin= ha_lock_engine(0, heap_hton);
4015
 
    table->file= get_new_handler(share, &table->mem_root,
4016
 
                                 share->db_type());
 
995
    table->getMutableShare()->storage_engine= heap_engine;
 
996
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
4017
997
  }
4018
 
  if (!table->file)
 
998
  if (! table->cursor)
4019
999
    goto err;
4020
1000
 
4021
1001
 
4022
 
  if (!using_unique_constraint)
 
1002
  if (! using_unique_constraint)
4023
1003
    reclength+= group_null_items;       // null flag is stored separately
4024
1004
 
4025
 
  share->blob_fields= blob_count;
 
1005
  table->getMutableShare()->blob_fields= blob_count;
4026
1006
  if (blob_count == 0)
4027
1007
  {
4028
1008
    /* We need to ensure that first byte is not 0 for the delete link */
4037
1017
  reclength+=null_pack_length;
4038
1018
  if (!reclength)
4039
1019
    reclength=1;                                // Dummy select
4040
 
  /* Use packed rows if there is blobs or a lot of space to gain */
4041
 
  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)))
4042
 
    use_packed_rows= 1;
4043
1020
 
4044
 
  share->reclength= reclength;
 
1021
  table->getMutableShare()->setRecordLength(reclength);
4045
1022
  {
4046
1023
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
4047
 
    share->rec_buff_length= alloc_length;
4048
 
    if (!(table->record[0]= (unsigned char*)
4049
 
                            alloc_root(&table->mem_root, alloc_length*3)))
4050
 
      goto err;
4051
 
    table->record[1]= table->record[0]+alloc_length;
4052
 
    share->default_values= table->record[1]+alloc_length;
 
1024
    table->getMutableShare()->rec_buff_length= alloc_length;
 
1025
    table->record[0]= table->alloc(alloc_length*2);
 
1026
    table->record[1]= table->getInsertRecord()+alloc_length;
 
1027
    table->getMutableShare()->resizeDefaultValues(alloc_length);
4053
1028
  }
4054
 
  copy_func[0]=0;                               // End marker
4055
 
  param->func_count= copy_func - param->items_to_copy; 
 
1029
  copy_func[0]= 0;                              // End marker
 
1030
  param->func_count= copy_func - param->items_to_copy;
4056
1031
 
4057
 
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
1032
  table->setup_tmp_table_column_bitmaps();
4058
1033
 
4059
1034
  recinfo=param->start_recinfo;
4060
 
  null_flags=(unsigned char*) table->record[0];
4061
 
  pos=table->record[0]+ null_pack_length;
 
1035
  null_flags= table->getInsertRecord();
 
1036
  pos=table->getInsertRecord()+ null_pack_length;
4062
1037
  if (null_pack_length)
4063
1038
  {
4064
1039
    memset(recinfo, 0, sizeof(*recinfo));
4067
1042
    recinfo++;
4068
1043
    memset(null_flags, 255, null_pack_length);  // Set null fields
4069
1044
 
4070
 
    table->null_flags= (unsigned char*) table->record[0];
4071
 
    share->null_fields= null_count+ hidden_null_count;
4072
 
    share->null_bytes= null_pack_length;
 
1045
    table->null_flags= table->getInsertRecord();
 
1046
    table->getMutableShare()->null_fields= null_count+ hidden_null_count;
 
1047
    table->getMutableShare()->null_bytes= null_pack_length;
4073
1048
  }
4074
1049
  null_count= (blob_count == 0) ? 1 : 0;
4075
1050
  hidden_field_count=param->hidden_field_count;
4076
 
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
 
1051
  for (i= 0,reg_field= table->getFields(); i < field_count; i++,reg_field++,recinfo++)
4077
1052
  {
4078
1053
    Field *field= *reg_field;
4079
1054
    uint32_t length;
4087
1062
          We have to reserve one byte here for NULL bits,
4088
1063
          as this is updated by 'end_update()'
4089
1064
        */
4090
 
        *pos++=0;                               // Null is stored here
4091
 
        recinfo->length=1;
 
1065
        *pos++= '\0';                           // Null is stored here
 
1066
        recinfo->length= 1;
4092
1067
        recinfo->type=FIELD_NORMAL;
4093
1068
        recinfo++;
4094
1069
        memset(recinfo, 0, sizeof(*recinfo));
4112
1087
    */
4113
1088
    if (default_field[i] && default_field[i]->ptr)
4114
1089
    {
4115
 
      /* 
 
1090
      /*
4116
1091
         default_field[i] is set only in the cases  when 'field' can
4117
1092
         inherit the default value that is defined for the field referred
4118
1093
         by the Item_field object from which 'field' has been created.
4119
1094
      */
4120
 
      my_ptrdiff_t diff;
 
1095
      ptrdiff_t diff;
4121
1096
      Field *orig_field= default_field[i];
4122
1097
      /* Get the value from default_values */
4123
 
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
4124
 
                            orig_field->table->record[0]);
 
1098
      diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
4125
1099
      orig_field->move_field_offset(diff);      // Points now at default_values
4126
1100
      if (orig_field->is_real_null())
4127
1101
        field->set_null();
4130
1104
        field->set_notnull();
4131
1105
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
4132
1106
      }
4133
 
      orig_field->move_field_offset(-diff);     // Back to record[0]
4134
 
    } 
 
1107
      orig_field->move_field_offset(-diff);     // Back to getInsertRecord()
 
1108
    }
4135
1109
 
4136
1110
    if (from_field[i])
4137
1111
    {                                           /* Not a table Item */
4149
1123
      recinfo->type=FIELD_NORMAL;
4150
1124
    if (!--hidden_field_count)
4151
1125
      null_count=(null_count+7) & ~7;           // move to next byte
4152
 
 
4153
 
    // fix table name in field entry
4154
 
    field->table_name= &table->alias;
4155
1126
  }
4156
1127
 
4157
1128
  param->copy_field_end=copy;
4158
1129
  param->recinfo=recinfo;
4159
 
  store_record(table,s->default_values);        // Make empty default record
 
1130
  table->storeRecordAsDefault();        // Make empty default record
4160
1131
 
4161
1132
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
4162
 
    share->max_rows= ~(ha_rows) 0;
 
1133
  {
 
1134
    max_rows= ~(uint64_t) 0;
 
1135
  }
4163
1136
  else
4164
 
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
4165
 
                                 cmin(session->variables.tmp_table_size,
4166
 
                                     session->variables.max_heap_table_size) :
4167
 
                                 session->variables.tmp_table_size) /
4168
 
                                 share->reclength);
4169
 
  set_if_bigger(share->max_rows,1);             // For dummy start options
 
1137
  {
 
1138
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
 
1139
                           min(session->variables.tmp_table_size,
 
1140
                               session->variables.max_heap_table_size) :
 
1141
                           session->variables.tmp_table_size) /
 
1142
                          table->getMutableShare()->getRecordLength());
 
1143
  }
 
1144
 
 
1145
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
4170
1146
  /*
4171
1147
    Push the LIMIT clause to the temporary table creation, so that we
4172
1148
    materialize only up to 'rows_limit' records instead of all result records.
4173
1149
  */
4174
 
  set_if_smaller(share->max_rows, rows_limit);
 
1150
  set_if_smaller(max_rows, rows_limit);
 
1151
 
 
1152
  table->getMutableShare()->setMaxRows(max_rows);
 
1153
 
4175
1154
  param->end_write_records= rows_limit;
4176
1155
 
4177
1156
  keyinfo= param->keyinfo;
4180
1159
  {
4181
1160
    table->group=group;                         /* Table is grouped by key */
4182
1161
    param->group_buff=group_buff;
4183
 
    share->keys=1;
4184
 
    share->uniques= test(using_unique_constraint);
 
1162
    table->getMutableShare()->keys=1;
 
1163
    table->getMutableShare()->uniques= test(using_unique_constraint);
4185
1164
    table->key_info=keyinfo;
4186
1165
    keyinfo->key_part=key_part_info;
4187
1166
    keyinfo->flags=HA_NOSAME;
4188
1167
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
4189
 
    keyinfo->key_length=0;
4190
 
    keyinfo->rec_per_key=0;
 
1168
    keyinfo->key_length= 0;
 
1169
    keyinfo->rec_per_key= 0;
4191
1170
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
4192
1171
    keyinfo->name= (char*) "group_key";
4193
 
    order_st *cur_group= group;
 
1172
    Order *cur_group= group;
4194
1173
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
4195
1174
    {
4196
1175
      Field *field=(*cur_group->item)->get_tmp_table_field();
4197
1176
      bool maybe_null=(*cur_group->item)->maybe_null;
4198
 
      key_part_info->null_bit=0;
 
1177
      key_part_info->null_bit= 0;
4199
1178
      key_part_info->field=  field;
4200
 
      key_part_info->offset= field->offset(table->record[0]);
 
1179
      key_part_info->offset= field->offset(table->getInsertRecord());
4201
1180
      key_part_info->length= (uint16_t) field->key_length();
4202
1181
      key_part_info->type=   (uint8_t) field->key_type();
4203
 
      key_part_info->key_type =
 
1182
      key_part_info->key_type= 
4204
1183
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
4205
1184
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
4206
1185
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
4207
 
        0 : FIELDFLAG_BINARY;
 
1186
        0 : 1;
4208
1187
      if (!using_unique_constraint)
4209
1188
      {
4210
1189
        cur_group->buff=(char*) group_buff;
4213
1192
                                                     test(maybe_null),
4214
1193
                                                     field->null_ptr,
4215
1194
                                                     field->null_bit)))
4216
 
          goto err; /* purecov: inspected */
 
1195
          goto err;
4217
1196
        if (maybe_null)
4218
1197
        {
4219
1198
          /*
4224
1203
          */
4225
1204
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
4226
1205
          key_part_info->null_bit=field->null_bit;
4227
 
          key_part_info->null_offset= (uint) (field->null_ptr -
4228
 
                                              (unsigned char*) table->record[0]);
 
1206
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
 
1207
                                              (unsigned char*) table->getInsertRecord());
4229
1208
          cur_group->buff++;                        // Pointer to field data
4230
1209
          group_buff++;                         // Skipp null flag
4231
1210
        }
4252
1231
        indexes on blobs with arbitrary length. Such indexes cannot be
4253
1232
        used for lookups.
4254
1233
      */
4255
 
      share->uniques= 1;
 
1234
      table->getMutableShare()->uniques= 1;
4256
1235
    }
4257
1236
    null_pack_length-=hidden_null_pack_length;
4258
1237
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
4259
 
                         (share->uniques ? test(null_pack_length) : 0));
 
1238
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
4260
1239
    table->distinct= 1;
4261
 
    share->keys= 1;
4262
 
    if (!(key_part_info= (KEY_PART_INFO*)
4263
 
          alloc_root(&table->mem_root,
4264
 
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
4265
 
      goto err;
4266
 
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
 
1240
    table->getMutableShare()->keys= 1;
 
1241
    key_part_info= new (table->mem()) KeyPartInfo[keyinfo->key_parts];
 
1242
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KeyPartInfo));
4267
1243
    table->key_info=keyinfo;
4268
1244
    keyinfo->key_part=key_part_info;
4269
1245
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
4270
1246
    keyinfo->key_length=(uint16_t) reclength;
4271
1247
    keyinfo->name= (char*) "distinct_key";
4272
1248
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
4273
 
    keyinfo->rec_per_key=0;
 
1249
    keyinfo->rec_per_key= 0;
4274
1250
 
4275
1251
    /*
4276
1252
      Create an extra field to hold NULL bits so that unique indexes on
4277
1253
      blobs can distinguish NULL from 0. This extra field is not needed
4278
1254
      when we do not use UNIQUE indexes for blobs.
4279
1255
    */
4280
 
    if (null_pack_length && share->uniques)
 
1256
    if (null_pack_length && table->getMutableShare()->uniques)
4281
1257
    {
4282
 
      key_part_info->null_bit=0;
 
1258
      key_part_info->null_bit= 0;
4283
1259
      key_part_info->offset=hidden_null_pack_length;
4284
1260
      key_part_info->length=null_pack_length;
4285
 
      key_part_info->field= new Field_varstring(table->record[0],
 
1261
      table->setVariableWidth();
 
1262
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
4286
1263
                                                (uint32_t) key_part_info->length,
4287
1264
                                                0,
4288
1265
                                                (unsigned char*) 0,
4289
 
                                                (uint) 0,
4290
 
                                                Field::NONE,
4291
 
                                                NULL, 
4292
 
                                                table->s,
 
1266
                                                (uint32_t) 0,
 
1267
                                                NULL,
4293
1268
                                                &my_charset_bin);
4294
1269
      if (!key_part_info->field)
4295
1270
        goto err;
4296
1271
      key_part_info->field->init(table);
4297
 
      key_part_info->key_type=FIELDFLAG_BINARY;
 
1272
      key_part_info->key_type= 1; /* binary comparison */
4298
1273
      key_part_info->type=    HA_KEYTYPE_BINARY;
4299
1274
      key_part_info++;
4300
1275
    }
4301
1276
    /* Create a distinct key over the columns we are going to return */
4302
 
    for (i=param->hidden_field_count, reg_field=table->field + i ;
 
1277
    for (i=param->hidden_field_count, reg_field=table->getFields() + i ;
4303
1278
         i < field_count;
4304
1279
         i++, reg_field++, key_part_info++)
4305
1280
    {
4306
 
      key_part_info->null_bit=0;
 
1281
      key_part_info->null_bit= 0;
4307
1282
      key_part_info->field=    *reg_field;
4308
 
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
 
1283
      key_part_info->offset=   (*reg_field)->offset(table->getInsertRecord());
4309
1284
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
4310
 
      /* TODO:
4311
 
        The below method of computing the key format length of the
4312
 
        key part is a copy/paste from opt_range.cc, and table.cc.
 
1285
      /* @todo The below method of computing the key format length of the
 
1286
        key part is a copy/paste from optimizer/range.cc, and table.cc.
4313
1287
        This should be factored out, e.g. as a method of Field.
4314
1288
        In addition it is not clear if any of the Field::*_length
4315
1289
        methods is supposed to compute the same length. If so, it
4319
1293
 
4320
1294
      if ((*reg_field)->real_maybe_null())
4321
1295
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
4322
 
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB || 
 
1296
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB ||
4323
1297
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
4324
1298
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
4325
1299
 
4328
1302
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
4329
1303
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
4330
1304
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
4331
 
        0 : FIELDFLAG_BINARY;
 
1305
        0 : 1;
4332
1306
    }
4333
1307
  }
4334
1308
 
4335
1309
  if (session->is_fatal_error)                          // If end of memory
4336
 
    goto err;                                    /* purecov: inspected */
4337
 
  share->db_record_offset= 1;
4338
 
  if (share->db_type() == myisam_hton)
 
1310
    goto err;
 
1311
  table->getMutableShare()->db_record_offset= 1;
 
1312
  if (table->getShare()->db_type() == myisam_engine)
4339
1313
  {
4340
1314
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
4341
1315
                                       &param->recinfo, select_options))
4342
1316
      goto err;
4343
1317
  }
 
1318
  assert(table->in_use);
4344
1319
  if (table->open_tmp_table())
4345
1320
    goto err;
4346
1321
 
4350
1325
 
4351
1326
err:
4352
1327
  session->mem_root= mem_root_save;
4353
 
  table->free_tmp_table(session);                    /* purecov: inspected */
4354
 
  if (temp_pool_slot != MY_BIT_NONE)
4355
 
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4356
 
  return(NULL);                         /* purecov: inspected */
 
1328
  table= NULL;
 
1329
 
 
1330
  return NULL;
4357
1331
}
4358
1332
 
4359
1333
/****************************************************************************/
4360
1334
 
4361
 
/**
4362
 
  Create a reduced Table object with properly set up Field list from a
4363
 
  list of field definitions.
4364
 
 
4365
 
    The created table doesn't have a table handler associated with
4366
 
    it, has no keys, no group/distinct, no copy_funcs array.
4367
 
    The sole purpose of this Table object is to use the power of Field
4368
 
    class to read/write data to/from table->record[0]. Then one can store
4369
 
    the record in any container (RB tree, hash, etc).
4370
 
    The table is created in Session mem_root, so are the table's fields.
4371
 
    Consequently, if you don't BLOB fields, you don't need to free it.
4372
 
 
4373
 
  @param session         connection handle
4374
 
  @param field_list  list of column definitions
4375
 
 
4376
 
  @return
4377
 
    0 if out of memory, Table object in case of success
4378
 
*/
4379
 
 
4380
 
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4381
 
{
4382
 
  uint32_t field_count= field_list.elements;
4383
 
  uint32_t blob_count= 0;
4384
 
  Field **field;
4385
 
  Create_field *cdef;                           /* column definition */
4386
 
  uint32_t record_length= 0;
4387
 
  uint32_t null_count= 0;                 /* number of columns which may be null */
4388
 
  uint32_t null_pack_length;              /* NULL representation array length */
4389
 
  uint32_t *blob_field;
4390
 
  unsigned char *bitmaps;
4391
 
  Table *table;
4392
 
  TABLE_SHARE *share;
4393
 
 
4394
 
  if (!multi_alloc_root(session->mem_root,
4395
 
                        &table, sizeof(*table),
4396
 
                        &share, sizeof(*share),
4397
 
                        &field, (field_count + 1) * sizeof(Field*),
4398
 
                        &blob_field, (field_count+1) *sizeof(uint),
4399
 
                        &bitmaps, bitmap_buffer_size(field_count)*2,
4400
 
                        NULL))
4401
 
    return 0;
4402
 
 
4403
 
  memset(table, 0, sizeof(*table));
4404
 
  memset(share, 0, sizeof(*share));
4405
 
  table->field= field;
4406
 
  table->s= share;
4407
 
  share->blob_field= blob_field;
4408
 
  share->fields= field_count;
4409
 
  share->blob_ptr_size= portable_sizeof_char_ptr;
4410
 
  table->setup_tmp_table_column_bitmaps(bitmaps);
4411
 
 
4412
 
  /* Create all fields and calculate the total length of record */
4413
 
  List_iterator_fast<Create_field> it(field_list);
4414
 
  while ((cdef= it++))
4415
 
  {
4416
 
    *field= make_field(share, 0, cdef->length,
4417
 
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
4418
 
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
4419
 
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
4420
 
                       cdef->unireg_check,
4421
 
                       cdef->interval, cdef->field_name);
4422
 
    if (!*field)
4423
 
      goto error;
4424
 
    (*field)->init(table);
4425
 
    record_length+= (*field)->pack_length();
4426
 
    if (! ((*field)->flags & NOT_NULL_FLAG))
4427
 
      null_count++;
4428
 
 
4429
 
    if ((*field)->flags & BLOB_FLAG)
4430
 
      share->blob_field[blob_count++]= (uint) (field - table->field);
4431
 
 
4432
 
    field++;
4433
 
  }
4434
 
  *field= NULL;                             /* mark the end of the list */
4435
 
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
4436
 
  share->blob_fields= blob_count;
4437
 
 
4438
 
  null_pack_length= (null_count + 7)/8;
4439
 
  share->reclength= record_length + null_pack_length;
4440
 
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4441
 
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4442
 
  if (!table->record[0])
4443
 
    goto error;
4444
 
 
4445
 
  if (null_pack_length)
4446
 
  {
4447
 
    table->null_flags= (unsigned char*) table->record[0];
4448
 
    share->null_fields= null_count;
4449
 
    share->null_bytes= null_pack_length;
4450
 
  }
4451
 
 
4452
 
  table->in_use= session;           /* field->reset() may access table->in_use */
4453
 
  {
4454
 
    /* Set up field pointers */
4455
 
    unsigned char *null_pos= table->record[0];
4456
 
    unsigned char *field_pos= null_pos + share->null_bytes;
4457
 
    uint32_t null_bit= 1;
4458
 
 
4459
 
    for (field= table->field; *field; ++field)
4460
 
    {
4461
 
      Field *cur_field= *field;
4462
 
      if ((cur_field->flags & NOT_NULL_FLAG))
4463
 
        cur_field->move_field(field_pos);
4464
 
      else
4465
 
      {
4466
 
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
4467
 
        null_bit<<= 1;
4468
 
        if (null_bit == (1 << 8))
4469
 
        {
4470
 
          ++null_pos;
4471
 
          null_bit= 1;
4472
 
        }
4473
 
      }
4474
 
      cur_field->reset();
4475
 
 
4476
 
      field_pos+= cur_field->pack_length();
4477
 
    }
4478
 
  }
4479
 
  return table;
4480
 
error:
4481
 
  for (field= table->field; *field; ++field)
4482
 
    delete *field;                         /* just invokes field destructor */
4483
 
  return 0;
4484
 
}
4485
 
 
4486
 
 
4487
 
bool Table::open_tmp_table()
4488
 
{
4489
 
  int error;
4490
 
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
4491
 
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
4492
 
  {
4493
 
    file->print_error(error,MYF(0)); /* purecov: inspected */
4494
 
    db_stat=0;
4495
 
    return(1);
4496
 
  }
4497
 
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
4498
 
  return(0);
4499
 
}
4500
 
 
4501
 
 
4502
 
/*
4503
 
  Create MyISAM temporary table
4504
 
 
4505
 
  SYNOPSIS
4506
 
    create_myisam_tmp_table()
4507
 
      keyinfo         Description of the index (there is always one index)
4508
 
      start_recinfo   MyISAM's column descriptions
4509
 
      recinfo INOUT   End of MyISAM's column descriptions
4510
 
      options         Option bits
4511
 
   
4512
 
  DESCRIPTION
4513
 
    Create a MyISAM temporary table according to passed description. The is
4514
 
    assumed to have one unique index or constraint.
4515
 
 
4516
 
    The passed array or MI_COLUMNDEF structures must have this form:
4517
 
 
4518
 
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
4519
 
         when there are many nullable columns)
4520
 
      2. Table columns
4521
 
      3. One free MI_COLUMNDEF element (*recinfo points here)
4522
 
   
4523
 
    This function may use the free element to create hash column for unique
4524
 
    constraint.
4525
 
 
4526
 
   RETURN
4527
 
     false - OK
4528
 
     true  - Error
4529
 
*/
4530
 
 
4531
 
bool Table::create_myisam_tmp_table(KEY *keyinfo, 
4532
 
                                    MI_COLUMNDEF *start_recinfo,
4533
 
                                    MI_COLUMNDEF **recinfo, 
4534
 
                                    uint64_t options)
4535
 
{
4536
 
  int error;
4537
 
  MI_KEYDEF keydef;
4538
 
  MI_UNIQUEDEF uniquedef;
4539
 
  TABLE_SHARE *share= s;
4540
 
 
4541
 
  if (share->keys)
4542
 
  {                                             // Get keys for ni_create
4543
 
    bool using_unique_constraint=0;
4544
 
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
4545
 
                                            sizeof(*seg) * keyinfo->key_parts);
4546
 
    if (!seg)
4547
 
      goto err;
4548
 
 
4549
 
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
4550
 
    if (keyinfo->key_length >= file->max_key_length() ||
4551
 
        keyinfo->key_parts > file->max_key_parts() ||
4552
 
        share->uniques)
4553
 
    {
4554
 
      /* Can't create a key; Make a unique constraint instead of a key */
4555
 
      share->keys=    0;
4556
 
      share->uniques= 1;
4557
 
      using_unique_constraint=1;
4558
 
      memset(&uniquedef, 0, sizeof(uniquedef));
4559
 
      uniquedef.keysegs=keyinfo->key_parts;
4560
 
      uniquedef.seg=seg;
4561
 
      uniquedef.null_are_equal=1;
4562
 
 
4563
 
      /* Create extra column for hash value */
4564
 
      memset(*recinfo, 0, sizeof(**recinfo));
4565
 
      (*recinfo)->type= FIELD_CHECK;
4566
 
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
4567
 
      (*recinfo)++;
4568
 
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
4569
 
    }
4570
 
    else
4571
 
    {
4572
 
      /* Create an unique key */
4573
 
      memset(&keydef, 0, sizeof(keydef));
4574
 
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
4575
 
      keydef.keysegs=  keyinfo->key_parts;
4576
 
      keydef.seg= seg;
4577
 
    }
4578
 
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
4579
 
    {
4580
 
      Field *field=keyinfo->key_part[i].field;
4581
 
      seg->flag=     0;
4582
 
      seg->language= field->charset()->number;
4583
 
      seg->length=   keyinfo->key_part[i].length;
4584
 
      seg->start=    keyinfo->key_part[i].offset;
4585
 
      if (field->flags & BLOB_FLAG)
4586
 
      {
4587
 
        seg->type=
4588
 
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
4589
 
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
4590
 
        seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
4591
 
        seg->flag= HA_BLOB_PART;
4592
 
        seg->length=0;                  // Whole blob in unique constraint
4593
 
      }
4594
 
      else
4595
 
      {
4596
 
        seg->type= keyinfo->key_part[i].type;
4597
 
      }
4598
 
      if (!(field->flags & NOT_NULL_FLAG))
4599
 
      {
4600
 
        seg->null_bit= field->null_bit;
4601
 
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) record[0]);
4602
 
        /*
4603
 
          We are using a GROUP BY on something that contains NULL
4604
 
          In this case we have to tell MyISAM that two NULL should
4605
 
          on INSERT be regarded at the same value
4606
 
        */
4607
 
        if (!using_unique_constraint)
4608
 
          keydef.flag|= HA_NULL_ARE_EQUAL;
4609
 
      }
4610
 
    }
4611
 
  }
4612
 
  MI_CREATE_INFO create_info;
4613
 
  memset(&create_info, 0, sizeof(create_info));
4614
 
 
4615
 
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
4616
 
      OPTION_BIG_TABLES)
4617
 
    create_info.data_file_length= ~(uint64_t) 0;
4618
 
 
4619
 
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
4620
 
                       (uint) (*recinfo-start_recinfo),
4621
 
                       start_recinfo,
4622
 
                       share->uniques, &uniquedef,
4623
 
                       &create_info,
4624
 
                       HA_CREATE_TMP_TABLE)))
4625
 
  {
4626
 
    file->print_error(error,MYF(0));    /* purecov: inspected */
4627
 
    db_stat=0;
4628
 
    goto err;
4629
 
  }
4630
 
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
4631
 
  share->db_record_offset= 1;
4632
 
  return false;
4633
 
 err:
4634
 
  return true;
4635
 
}
4636
 
 
4637
 
 
4638
 
void Table::free_tmp_table(Session *session)
4639
 
{
4640
 
  MEM_ROOT own_root= mem_root;
4641
 
  const char *save_proc_info;
4642
 
 
4643
 
  save_proc_info=session->get_proc_info();
4644
 
  session->set_proc_info("removing tmp table");
4645
 
 
4646
 
  if (file)
4647
 
  {
4648
 
    if (db_stat)
4649
 
      file->ha_drop_table(s->table_name.str);
4650
 
    else
4651
 
      file->ha_delete_table(s->table_name.str);
4652
 
    delete file;
4653
 
  }
4654
 
 
4655
 
  /* free blobs */
4656
 
  for (Field **ptr= field ; *ptr ; ptr++)
4657
 
    (*ptr)->free();
4658
 
  free_io_cache(this);
4659
 
 
4660
 
  if (temp_pool_slot != MY_BIT_NONE)
4661
 
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4662
 
 
4663
 
  plugin_unlock(0, s->db_plugin);
4664
 
 
4665
 
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4666
 
  session->set_proc_info(save_proc_info);
4667
 
 
4668
 
  return;
4669
 
}
4670
 
 
4671
 
/**
4672
 
  If a HEAP table gets full, create a MyISAM table and copy all rows
4673
 
  to this.
4674
 
*/
4675
 
 
4676
 
bool create_myisam_from_heap(Session *session, Table *table,
4677
 
                             MI_COLUMNDEF *start_recinfo,
4678
 
                             MI_COLUMNDEF **recinfo, 
4679
 
                             int error, bool ignore_last_dupp_key_error)
4680
 
{
4681
 
  Table new_table;
4682
 
  TABLE_SHARE share;
4683
 
  const char *save_proc_info;
4684
 
  int write_err;
4685
 
 
4686
 
  if (table->s->db_type() != heap_hton || 
4687
 
      error != HA_ERR_RECORD_FILE_FULL)
4688
 
  {
4689
 
    table->file->print_error(error,MYF(0));
4690
 
    return(1);
4691
 
  }
4692
 
  new_table= *table;
4693
 
  share= *table->s;
4694
 
  new_table.s= &share;
4695
 
  new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
4696
 
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4697
 
                                        new_table.s->db_type())))
4698
 
    return(1);                          // End of memory
4699
 
 
4700
 
  save_proc_info=session->get_proc_info();
4701
 
  session->set_proc_info("converting HEAP to MyISAM");
4702
 
 
4703
 
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4704
 
                                        recinfo, session->lex->select_lex.options | 
4705
 
                                        session->options))
4706
 
    goto err2;
4707
 
  if (new_table.open_tmp_table())
4708
 
    goto err1;
4709
 
  if (table->file->indexes_are_disabled())
4710
 
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
4711
 
  table->file->ha_index_or_rnd_end();
4712
 
  table->file->ha_rnd_init(1);
4713
 
  if (table->no_rows)
4714
 
  {
4715
 
    new_table.file->extra(HA_EXTRA_NO_ROWS);
4716
 
    new_table.no_rows=1;
4717
 
  }
4718
 
 
4719
 
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
4720
 
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
4721
 
 
4722
 
  /*
4723
 
    copy all old rows from heap table to MyISAM table
4724
 
    This is the only code that uses record[1] to read/write but this
4725
 
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
4726
 
  */
4727
 
  while (!table->file->rnd_next(new_table.record[1]))
4728
 
  {
4729
 
    write_err= new_table.file->ha_write_row(new_table.record[1]);
4730
 
    if (write_err)
4731
 
      goto err;
4732
 
  }
4733
 
  /* copy row that filled HEAP table */
4734
 
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
4735
 
  {
4736
 
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
4737
 
        !ignore_last_dupp_key_error)
4738
 
      goto err;
4739
 
  }
4740
 
 
4741
 
  /* remove heap table and change to use myisam table */
4742
 
  (void) table->file->ha_rnd_end();
4743
 
  (void) table->file->close();                  // This deletes the table !
4744
 
  delete table->file;
4745
 
  table->file=0;
4746
 
  plugin_unlock(0, table->s->db_plugin);
4747
 
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
4748
 
  new_table.s= table->s;                       // Keep old share
4749
 
  *table= new_table;
4750
 
  *table->s= share;
4751
 
  
4752
 
  table->file->change_table_ptr(table, table->s);
4753
 
  table->use_all_columns();
4754
 
  if (save_proc_info)
4755
 
  {
4756
 
    const char *new_proc_info=
4757
 
      (!strcmp(save_proc_info,"Copying to tmp table") ?
4758
 
      "Copying to tmp table on disk" : save_proc_info);
4759
 
    session->set_proc_info(new_proc_info);
4760
 
  }
4761
 
  return(0);
4762
 
 
4763
 
 err:
4764
 
  table->file->print_error(write_err, MYF(0));
4765
 
  (void) table->file->ha_rnd_end();
4766
 
  (void) new_table.file->close();
4767
 
 err1:
4768
 
  new_table.file->ha_delete_table(new_table.s->table_name.str);
4769
 
 err2:
4770
 
  delete new_table.file;
4771
 
  session->set_proc_info(save_proc_info);
4772
 
  table->mem_root= new_table.mem_root;
4773
 
  return(1);
4774
 
}
4775
 
 
4776
 
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
4777
 
{
4778
 
  my_bitmap_map *old= bitmap->bitmap;
4779
 
  bitmap->bitmap= s->all_set.bitmap;
 
1335
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
 
1336
                               boost::dynamic_bitset<>& write_set_arg)
 
1337
{
 
1338
  read_set= &read_set_arg;
 
1339
  write_set= &write_set_arg;
 
1340
}
 
1341
 
 
1342
 
 
1343
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
 
1344
{
 
1345
  const boost::dynamic_bitset<> old= in_map;
 
1346
  in_map= getShare()->all_set;
4780
1347
  return old;
4781
1348
}
4782
1349
 
4783
 
void Table::restore_column_map(my_bitmap_map *old)
 
1350
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
4784
1351
{
4785
 
  read_set->bitmap= old;
 
1352
  for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
 
1353
  {
 
1354
    if (old.test(i))
 
1355
    {
 
1356
      read_set->set(i);
 
1357
    }
 
1358
    else
 
1359
    {
 
1360
      read_set->reset(i);
 
1361
    }
 
1362
  }
4786
1363
}
4787
1364
 
4788
1365
uint32_t Table::find_shortest_key(const key_map *usable_keys)
4789
1366
{
4790
1367
  uint32_t min_length= UINT32_MAX;
4791
1368
  uint32_t best= MAX_KEY;
4792
 
  if (!usable_keys->is_clear_all())
 
1369
  if (usable_keys->any())
4793
1370
  {
4794
 
    for (uint32_t nr=0; nr < s->keys ; nr++)
 
1371
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
4795
1372
    {
4796
 
      if (usable_keys->is_set(nr))
 
1373
      if (usable_keys->test(nr))
4797
1374
      {
4798
1375
        if (key_info[nr].key_length < min_length)
4799
1376
        {
4818
1395
{
4819
1396
  for (; *ptr ; ptr++)
4820
1397
  {
4821
 
    if ((*ptr)->cmp_offset(s->rec_buff_length))
 
1398
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
4822
1399
      return true;
4823
1400
  }
4824
1401
  return false;
4825
1402
}
4826
1403
 
4827
 
/* Return false if row hasn't changed */
4828
 
 
4829
 
bool Table::compare_record()
4830
 
{
4831
 
  if (s->blob_fields + s->varchar_fields == 0)
4832
 
    return cmp_record(this, record[1]);
 
1404
/**
 
1405
   True if the table's input and output record buffers are comparable using
 
1406
   compare_records(TABLE*).
 
1407
 */
 
1408
bool Table::records_are_comparable()
 
1409
{
 
1410
  return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
 
1411
          write_set->is_subset_of(*read_set));
 
1412
}
 
1413
 
 
1414
/**
 
1415
   Compares the input and outbut record buffers of the table to see if a row
 
1416
   has changed. The algorithm iterates over updated columns and if they are
 
1417
   nullable compares NULL bits in the buffer before comparing actual
 
1418
   data. Special care must be taken to compare only the relevant NULL bits and
 
1419
   mask out all others as they may be undefined. The storage engine will not
 
1420
   and should not touch them.
 
1421
 
 
1422
   @param table The table to evaluate.
 
1423
 
 
1424
   @return true if row has changed.
 
1425
   @return false otherwise.
 
1426
*/
 
1427
bool Table::compare_records()
 
1428
{
 
1429
  if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
 
1430
  {
 
1431
    /*
 
1432
      Storage engine may not have read all columns of the record.  Fields
 
1433
      (including NULL bits) not in the write_set may not have been read and
 
1434
      can therefore not be compared.
 
1435
    */
 
1436
    for (Field **ptr= this->field ; *ptr != NULL; ptr++)
 
1437
    {
 
1438
      Field *f= *ptr;
 
1439
      if (write_set->test(f->position()))
 
1440
      {
 
1441
        if (f->real_maybe_null())
 
1442
        {
 
1443
          unsigned char null_byte_index= f->null_ptr - record[0];
 
1444
 
 
1445
          if (((record[0][null_byte_index]) & f->null_bit) !=
 
1446
              ((record[1][null_byte_index]) & f->null_bit))
 
1447
            return true;
 
1448
        }
 
1449
        if (f->cmp_binary_offset(getShare()->rec_buff_length))
 
1450
          return true;
 
1451
      }
 
1452
    }
 
1453
    return false;
 
1454
  }
 
1455
 
 
1456
  /*
 
1457
    The storage engine has read all columns, so it's safe to compare all bits
 
1458
    including those not in the write_set. This is cheaper than the
 
1459
    field-by-field comparison done above.
 
1460
  */
 
1461
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
 
1462
    // Fixed-size record: do bitwise comparison of the records
 
1463
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
1464
 
4833
1465
  /* Compare null bits */
4834
 
  if (memcmp(null_flags,
4835
 
             null_flags + s->rec_buff_length,
4836
 
             s->null_bytes))
4837
 
    return true;                                // Diff in NULL value
 
1466
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
 
1467
    return true; /* Diff in NULL value */
 
1468
 
4838
1469
  /* Compare updated fields */
4839
1470
  for (Field **ptr= field ; *ptr ; ptr++)
4840
1471
  {
4841
 
    if (bitmap_is_set(write_set, (*ptr)->field_index) &&
4842
 
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
 
1472
    if (isWriteSet((*ptr)->position()) &&
 
1473
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
4843
1474
      return true;
4844
1475
  }
4845
1476
  return false;
4846
1477
}
4847
1478
 
4848
 
 
4849
 
 
4850
 
 
 
1479
/*
 
1480
 * Store a record from previous record into next
 
1481
 *
 
1482
 */
 
1483
void Table::storeRecord()
 
1484
{
 
1485
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1486
}
 
1487
 
 
1488
/*
 
1489
 * Store a record as an insert
 
1490
 *
 
1491
 */
 
1492
void Table::storeRecordAsInsert()
 
1493
{
 
1494
  assert(insert_values.size() >= getShare()->getRecordLength());
 
1495
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1496
}
 
1497
 
 
1498
/*
 
1499
 * Store a record with default values
 
1500
 *
 
1501
 */
 
1502
void Table::storeRecordAsDefault()
 
1503
{
 
1504
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
1505
}
 
1506
 
 
1507
/*
 
1508
 * Restore a record from previous record into next
 
1509
 *
 
1510
 */
 
1511
void Table::restoreRecord()
 
1512
{
 
1513
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
1514
}
 
1515
 
 
1516
/*
 
1517
 * Restore a record with default values
 
1518
 *
 
1519
 */
 
1520
void Table::restoreRecordAsDefault()
 
1521
{
 
1522
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
1523
}
 
1524
 
 
1525
/*
 
1526
 * Empty a record
 
1527
 *
 
1528
 */
 
1529
void Table::emptyRecord()
 
1530
{
 
1531
  restoreRecordAsDefault();
 
1532
  memset(null_flags, 255, getShare()->null_bytes);
 
1533
}
 
1534
 
 
1535
Table::Table() : 
 
1536
  field(NULL),
 
1537
  cursor(NULL),
 
1538
  next(NULL),
 
1539
  prev(NULL),
 
1540
  read_set(NULL),
 
1541
  write_set(NULL),
 
1542
  tablenr(0),
 
1543
  db_stat(0),
 
1544
  def_read_set(),
 
1545
  def_write_set(),
 
1546
  tmp_set(),
 
1547
  in_use(NULL),
 
1548
  key_info(NULL),
 
1549
  next_number_field(NULL),
 
1550
  found_next_number_field(NULL),
 
1551
  timestamp_field(NULL),
 
1552
  pos_in_table_list(NULL),
 
1553
  group(NULL),
 
1554
  null_flags(NULL),
 
1555
  lock_position(0),
 
1556
  lock_data_start(0),
 
1557
  lock_count(0),
 
1558
  used_fields(0),
 
1559
  status(0),
 
1560
  derived_select_number(0),
 
1561
  current_lock(F_UNLCK),
 
1562
  copy_blobs(false),
 
1563
  maybe_null(false),
 
1564
  null_row(false),
 
1565
  force_index(false),
 
1566
  distinct(false),
 
1567
  const_table(false),
 
1568
  no_rows(false),
 
1569
  key_read(false),
 
1570
  no_keyread(false),
 
1571
  open_placeholder(false),
 
1572
  locked_by_name(false),
 
1573
  no_cache(false),
 
1574
  auto_increment_field_not_null(false),
 
1575
  alias_name_used(false),
 
1576
  query_id(0),
 
1577
  quick_condition_rows(0),
 
1578
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
 
1579
  map(0),
 
1580
  quick_rows(),
 
1581
  const_key_parts(),
 
1582
  quick_key_parts(),
 
1583
  quick_n_ranges()
 
1584
{
 
1585
  record[0]= (unsigned char *) 0;
 
1586
  record[1]= (unsigned char *) 0;
 
1587
}
4851
1588
 
4852
1589
/*****************************************************************************
4853
1590
  The different ways to read a record
4854
1591
  Returns -1 if row was not found, 0 if row was found and 1 on errors
4855
1592
*****************************************************************************/
4856
1593
 
4857
 
/** Help function when we get some an error from the table handler. */
 
1594
/** Help function when we get some an error from the table Cursor. */
4858
1595
 
4859
1596
int Table::report_error(int error)
4860
1597
{
4868
1605
    print them to the .err log
4869
1606
  */
4870
1607
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
4871
 
    sql_print_error(_("Got error %d when reading table '%s'"),
4872
 
                    error, s->path.str);
4873
 
  file->print_error(error,MYF(0));
 
1608
    errmsg_printf(error::ERROR, _("Got error %d when reading table '%s'"),
 
1609
                  error, getShare()->getPath());
 
1610
  print_error(error, MYF(0));
4874
1611
 
4875
1612
  return 1;
4876
1613
}
4877
1614
 
4878
1615
 
 
1616
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
 
1617
{
 
1618
  used_fields= 0;
 
1619
  const_table= 0;
 
1620
  null_row= 0;
 
1621
  status= STATUS_NO_RECORD;
 
1622
  maybe_null= table_list->outer_join;
 
1623
  TableList *embedding= table_list->getEmbedding();
 
1624
  while (!maybe_null && embedding)
 
1625
  {
 
1626
    maybe_null= embedding->outer_join;
 
1627
    embedding= embedding->getEmbedding();
 
1628
  }
 
1629
  tablenr= table_number;
 
1630
  map= (table_map) 1 << table_number;
 
1631
  force_index= table_list->force_index;
 
1632
  covering_keys= getShare()->keys_for_keyread;
 
1633
  merge_keys.reset();
 
1634
}
 
1635
 
 
1636
 
 
1637
void Table::fill_item_list(List<Item>& items) const
 
1638
{
 
1639
  /*
 
1640
    All Item_field's created using a direct pointer to a field
 
1641
    are fixed in Item_field constructor.
 
1642
  */
 
1643
  for (Field **ptr= field; *ptr; ptr++)
 
1644
    items.push_back(new Item_field(*ptr));
 
1645
}
 
1646
 
 
1647
 
 
1648
void Table::filesort_free_buffers(bool full)
 
1649
{
 
1650
  free(sort.record_pointers);
 
1651
  sort.record_pointers=0;
 
1652
  if (full)
 
1653
  {
 
1654
    free(sort.sort_keys);
 
1655
    sort.sort_keys= 0;
 
1656
    free(sort.buffpek);
 
1657
    sort.buffpek= 0;
 
1658
    sort.buffpek_len= 0;
 
1659
  }
 
1660
  free(sort.addon_buf);
 
1661
  free(sort.addon_field);
 
1662
  sort.addon_buf=0;
 
1663
  sort.addon_field=0;
 
1664
}
 
1665
 
4879
1666
/*
4880
 
  Calculate data for each virtual field marked for write in the
4881
 
  corresponding column map.
4882
 
 
4883
 
  SYNOPSIS
4884
 
    update_virtual_fields_marked_for_write()
4885
 
    table                  The Table object
4886
 
    ignore_stored          Indication whether physically stored virtual
4887
 
                           fields do not need updating.
4888
 
                           This value is false when during INSERT and UPDATE
4889
 
                           and true in all other cases.
4890
 
 
4891
 
  RETURN
4892
 
    0  - Success
4893
 
    >0 - Error occurred during the generation/calculation of a virtual field value
4894
 
 
 
1667
  Is this instance of the table should be reopen or represents a name-lock?
4895
1668
*/
4896
 
 
4897
 
int update_virtual_fields_marked_for_write(Table *table,
4898
 
                                           bool ignore_stored)
4899
 
{
4900
 
  Field **vfield_ptr, *vfield;
4901
 
  int error= 0;
4902
 
  if ((not table) or (not table->vfield))
4903
 
    return(0);
4904
 
 
4905
 
  /* Iterate over virtual fields in the table */
4906
 
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
4907
 
  {
4908
 
    vfield= (*vfield_ptr);
4909
 
    assert(vfield->vcol_info && vfield->vcol_info->expr_item);
4910
 
    /*
4911
 
      Only update those fields that are marked in the write_set bitmap
4912
 
      and not _already_ physically stored in the database.
4913
 
    */
4914
 
    if (bitmap_is_set(table->write_set, vfield->field_index) &&
4915
 
        (not (ignore_stored && vfield->is_stored))
4916
 
       )
4917
 
    {
4918
 
      /* Generate the actual value of the virtual fields */
4919
 
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
4920
 
    }
4921
 
  }
4922
 
  return(0);
4923
 
}
4924
 
 
4925
 
 
4926
 
void setup_table_map(Table *table, TableList *table_list, uint32_t tablenr)
4927
 
{
4928
 
  table->used_fields= 0;
4929
 
  table->const_table= 0;
4930
 
  table->null_row= 0;
4931
 
  table->status= STATUS_NO_RECORD;
4932
 
  table->maybe_null= table_list->outer_join;
4933
 
  TableList *embedding= table_list->embedding;
4934
 
  while (!table->maybe_null && embedding)
4935
 
  {
4936
 
    table->maybe_null= embedding->outer_join;
4937
 
    embedding= embedding->embedding;
4938
 
  }
4939
 
  table->tablenr= tablenr;
4940
 
  table->map= (table_map) 1 << tablenr;
4941
 
  table->force_index= table_list->force_index;
4942
 
  table->covering_keys= table->s->keys_for_keyread;
4943
 
  table->merge_keys.clear_all();
4944
 
}
4945
 
 
4946
 
 
4947
 
/*****************************************************************************
4948
 
** Instansiate templates
4949
 
*****************************************************************************/
4950
 
 
4951
 
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4952
 
template class List<String>;
4953
 
template class List_iterator<String>;
4954
 
#endif
 
1669
bool Table::needs_reopen_or_name_lock() const
 
1670
 
1671
  return getShare()->getVersion() != g_refresh_version;
 
1672
}
 
1673
 
 
1674
uint32_t Table::index_flags(uint32_t idx) const
 
1675
{
 
1676
  return getShare()->getEngine()->index_flags(getShare()->getKeyInfo(idx).algorithm);
 
1677
}
 
1678
 
 
1679
void Table::print_error(int error, myf errflag) const
 
1680
{
 
1681
  getShare()->getEngine()->print_error(error, errflag, *this);
 
1682
}
 
1683
 
 
1684
} /* namespace drizzled */