~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-01-08 22:38:15 UTC
  • Revision ID: brian@tangent.org-20090108223815-i7p6uaajqxapge8a
func_timestamp now working.

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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/* Some general useful functions */
18
18
 
19
 
#include "config.h"
20
 
 
21
 
#include <float.h>
22
 
#include <fcntl.h>
23
 
 
24
 
#include <string>
25
 
#include <vector>
26
 
#include <algorithm>
27
 
 
 
19
#include <drizzled/server_includes.h>
28
20
#include <drizzled/error.h>
29
21
#include <drizzled/gettext.h>
30
22
 
31
 
#include "drizzled/plugin/transactional_storage_engine.h"
32
 
#include "drizzled/plugin/authorization.h"
 
23
#include <drizzled/tmp_table.h>
 
24
#include <drizzled/sj_tmp_table.h>
33
25
#include <drizzled/nested_join.h>
 
26
#include <drizzled/data_home.h>
34
27
#include <drizzled/sql_parse.h>
35
28
#include <drizzled/item/sum.h>
 
29
#include <drizzled/virtual_column_info.h>
36
30
#include <drizzled/table_list.h>
37
31
#include <drizzled/session.h>
38
32
#include <drizzled/sql_base.h>
39
 
#include <drizzled/sql_select.h>
40
33
#include <drizzled/field/blob.h>
41
34
#include <drizzled/field/varstring.h>
42
35
#include <drizzled/field/double.h>
43
 
#include <drizzled/unireg.h>
44
 
#include <drizzled/message/table.pb.h>
45
 
#include "drizzled/sql_table.h"
46
 
#include "drizzled/charset.h"
47
 
#include "drizzled/internal/m_string.h"
48
 
#include "plugin/myisam/myisam.h"
49
 
 
50
 
#include <drizzled/item/string.h>
51
 
#include <drizzled/item/int.h>
52
 
#include <drizzled/item/decimal.h>
53
 
#include <drizzled/item/float.h>
54
 
#include <drizzled/item/null.h>
55
 
#include <drizzled/temporal.h>
56
 
 
57
 
#include "drizzled/table/instance.h"
58
 
 
59
 
#include "drizzled/table_proto.h"
 
36
#include <string>
60
37
 
61
38
using namespace std;
62
39
 
63
 
namespace drizzled
64
 
{
65
 
 
66
 
extern pid_t current_pid;
67
 
extern plugin::StorageEngine *heap_engine;
68
 
extern plugin::StorageEngine *myisam_engine;
69
 
 
70
 
/* Functions defined in this cursor */
71
 
 
72
 
void open_table_error(TableShare *share, int error, int db_errno,
 
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,
73
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);
74
53
 
75
54
/*************************************************************************/
76
55
 
77
 
// @note this should all be the destructor
78
 
int Table::delete_table(bool free_share)
79
 
{
80
 
  int error= 0;
81
 
 
82
 
  if (db_stat)
83
 
    error= cursor->close();
84
 
  _alias.clear();
85
 
  if (field)
86
 
  {
87
 
    for (Field **ptr=field ; *ptr ; ptr++)
88
 
    {
 
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
    strcpy(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
    strcpy(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= current_mem_root_ptr();
 
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
  lseek(file,pos,SEEK_SET);
 
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
      errmsg_printf(ERRMSG_LVL_WARN, _("'%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
  lseek(file,(ulong) uint2korr(head+6),SEEK_SET);
 
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+= (strcpy(keynames, (char*)strpos)+strlen((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*) malloc(n_length)))
 
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
  lseek(file,pos+288,SEEK_SET);
 
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= current_mem_root_ptr();
 
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= strdup(alias)))
 
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++)
89
1853
      delete *ptr;
90
 
    }
91
 
    field= 0;
 
1854
    table->field= 0;
92
1855
  }
93
 
  delete cursor;
94
 
  cursor= 0;                            /* For easier errorchecking */
95
 
 
 
1856
  delete table->file;
 
1857
  table->file= 0;                               /* For easier errorchecking */
96
1858
  if (free_share)
97
1859
  {
98
 
    release();
 
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);
99
1864
  }
100
 
 
101
 
  return error;
102
 
}
103
 
 
104
 
Table::~Table()
105
 
{
106
 
  mem_root.free_root(MYF(0));
107
 
}
108
 
 
109
 
 
110
 
void Table::resetTable(Session *session,
111
 
                       TableShare *share,
112
 
                       uint32_t db_stat_arg)
113
 
{
114
 
  setShare(share);
115
 
  field= NULL;
116
 
 
117
 
  cursor= NULL;
118
 
  next= NULL;
119
 
  prev= NULL;
120
 
 
121
 
  read_set= NULL;
122
 
  write_set= NULL;
123
 
 
124
 
  tablenr= 0;
125
 
  db_stat= db_stat_arg;
126
 
 
127
 
  in_use= session;
128
 
  record[0]= (unsigned char *) NULL;
129
 
  record[1]= (unsigned char *) NULL;
130
 
 
131
 
  insert_values.clear();
132
 
  key_info= NULL;
133
 
  next_number_field= NULL;
134
 
  found_next_number_field= NULL;
135
 
  timestamp_field= NULL;
136
 
 
137
 
  pos_in_table_list= NULL;
138
 
  group= NULL;
139
 
  _alias.clear();
140
 
  null_flags= NULL;
141
 
 
142
 
  lock_position= 0;
143
 
  lock_data_start= 0;
144
 
  lock_count= 0;
145
 
  used_fields= 0;
146
 
  status= 0;
147
 
  derived_select_number= 0;
148
 
  current_lock= F_UNLCK;
149
 
  copy_blobs= false;
150
 
 
151
 
  maybe_null= false;
152
 
 
153
 
  null_row= false;
154
 
 
155
 
  force_index= false;
156
 
  distinct= false;
157
 
  const_table= false;
158
 
  no_rows= false;
159
 
  key_read= false;
160
 
  no_keyread= false;
161
 
 
162
 
  open_placeholder= false;
163
 
  locked_by_name= false;
164
 
  no_cache= false;
165
 
 
166
 
  auto_increment_field_not_null= false;
167
 
  alias_name_used= false;
168
 
 
169
 
  query_id= 0;
170
 
  quick_condition_rows= 0;
171
 
 
172
 
  timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
173
 
  map= 0;
174
 
 
175
 
  reginfo.reset();
176
 
 
177
 
  covering_keys.reset();
178
 
 
179
 
  quick_keys.reset();
180
 
  merge_keys.reset();
181
 
 
182
 
  keys_in_use_for_query.reset();
183
 
  keys_in_use_for_group_by.reset();
184
 
  keys_in_use_for_order_by.reset();
185
 
 
186
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
187
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
188
 
 
189
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
190
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
191
 
 
192
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
193
 
}
194
 
 
 
1865
  free_root(&table->mem_root, MYF(0));
 
1866
  return(error);
 
1867
}
195
1868
 
196
1869
 
197
1870
/* Deallocate temporary blob storage */
202
1875
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
203
1876
       ptr != end ;
204
1877
       ptr++)
205
 
  {
206
 
    ((Field_blob*) table->getField(*ptr))->free();
207
 
  }
208
 
}
209
 
 
210
 
 
211
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
212
 
{
213
 
  TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
 
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
    lseek(file,64,SEEK_SET);
 
1903
    if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
 
1904
        my_read(file, buf+a_length, (size_t) (length+names*4),
 
1905
                MYF(MY_NABP)))
 
1906
    {                                           /* purecov: inspected */
 
1907
      if (buf)
 
1908
        free(buf);
 
1909
      return(0L);                               /* purecov: inspected */
 
1910
    }
 
1911
    pos= buf+a_length+length;
 
1912
    ret_value=uint4korr(pos);
 
1913
  }
 
1914
  if (! save_names)
 
1915
  {
 
1916
    if (names)
 
1917
      free((unsigned char*) buf);
 
1918
  }
 
1919
  else if (!names)
 
1920
    memset(save_names, 0, sizeof(save_names));
 
1921
  else
 
1922
  {
 
1923
    char *str;
 
1924
    str=(char *) (buf+a_length);
 
1925
    fix_type_pointers((const char ***) &buf,save_names,1,&str);
 
1926
  }
 
1927
  return(ret_value);
 
1928
}
 
1929
 
 
1930
 
 
1931
/*
 
1932
  Read string from a file with malloc
 
1933
 
 
1934
  NOTES:
 
1935
    We add an \0 at end of the read string to make reading of C strings easier
 
1936
*/
 
1937
 
 
1938
int read_string(File file, unsigned char**to, size_t length)
 
1939
{
 
1940
 
 
1941
  if (*to)
 
1942
    free(*to);
 
1943
  if (!(*to= (unsigned char*) malloc(length+1)) ||
 
1944
      my_read(file, *to, length,MYF(MY_NABP)))
 
1945
  {
 
1946
    if (*to)
 
1947
      free(*to);
 
1948
    *to= NULL;
 
1949
    return(1);                           /* purecov: inspected */
 
1950
  }
 
1951
  *((char*) *to+length)= '\0';
 
1952
  return (0);
 
1953
} /* read_string */
 
1954
 
 
1955
 
 
1956
        /* Add a new form to a form file */
 
1957
 
 
1958
ulong make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
 
1959
                     const char *newname)
 
1960
{
 
1961
  uint32_t i,bufflength,maxlength,n_length,length,names;
 
1962
  off_t endpos,newpos;
 
1963
  unsigned char buff[IO_SIZE];
 
1964
  unsigned char *pos;
 
1965
 
 
1966
  length=(uint) strlen(newname)+1;
 
1967
  n_length=uint2korr(fileinfo+4);
 
1968
  maxlength=uint2korr(fileinfo+6);
 
1969
  names=uint2korr(fileinfo+8);
 
1970
  newpos=uint4korr(fileinfo+10);
 
1971
 
 
1972
  if (64+length+n_length+(names+1)*4 > maxlength)
 
1973
  {                                             /* Expand file */
 
1974
    newpos+=IO_SIZE;
 
1975
    int4store(fileinfo+10,newpos);
 
1976
    endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
 
1977
    bufflength= (uint) (endpos & (IO_SIZE-1));  /* IO_SIZE is a power of 2 */
 
1978
 
 
1979
    while (endpos > maxlength)
 
1980
    {
 
1981
      lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
 
1982
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
 
1983
        return(0L);
 
1984
      lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
 
1985
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
 
1986
        return(0);
 
1987
      endpos-=bufflength; bufflength=IO_SIZE;
 
1988
    }
 
1989
    memset(buff, 0, IO_SIZE);                   /* Null new block */
 
1990
    lseek(file,(ulong) maxlength,SEEK_SET);
 
1991
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
 
1992
      return(0L);
 
1993
    maxlength+=IO_SIZE;                         /* Fix old ref */
 
1994
    int2store(fileinfo+6,maxlength);
 
1995
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
 
1996
         pos+=4)
 
1997
    {
 
1998
      endpos=uint4korr(pos)+IO_SIZE;
 
1999
      int4store(pos,endpos);
 
2000
    }
 
2001
  }
 
2002
 
 
2003
  if (n_length == 1 )
 
2004
  {                                             /* First name */
 
2005
    length++;
 
2006
    sprintf((char*)buff,"/%s/",newname);
 
2007
  }
 
2008
  else
 
2009
    sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
 
2010
  lseek(file, 63 + n_length,SEEK_SET);
 
2011
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
 
2012
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
 
2013
                         names*4, MYF(MY_NABP+MY_WME))) ||
 
2014
      my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
 
2015
    return(0L); /* purecov: inspected */
 
2016
 
 
2017
  int2store(fileinfo+8,names+1);
 
2018
  int2store(fileinfo+4,n_length+length);
 
2019
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
 
2020
  return(newpos);
 
2021
} /* make_new_entry */
 
2022
 
 
2023
 
 
2024
        /* error message when opening a form file */
 
2025
 
 
2026
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
 
2027
{
 
2028
  int err_no;
 
2029
  char buff[FN_REFLEN];
 
2030
  myf errortype= ME_ERROR+ME_WAITTANG;
 
2031
 
 
2032
  switch (error) {
 
2033
  case 7:
 
2034
  case 1:
 
2035
    if (db_errno == ENOENT)
 
2036
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
 
2037
    else
 
2038
    {
 
2039
      sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
 
2040
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
 
2041
               errortype, buff, db_errno);
 
2042
    }
 
2043
    break;
 
2044
  case 2:
 
2045
  {
 
2046
    handler *file= 0;
 
2047
    const char *datext= "";
 
2048
 
 
2049
    if (share->db_type() != NULL)
 
2050
    {
 
2051
      if ((file= get_new_handler(share, current_session->mem_root,
 
2052
                                 share->db_type())))
 
2053
      {
 
2054
        if (!(datext= *file->bas_ext()))
 
2055
          datext= "";
 
2056
      }
 
2057
    }
 
2058
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
 
2059
      ER_FILE_USED : ER_CANT_OPEN_FILE;
 
2060
    sprintf(buff,"%s%s", share->normalized_path.str,datext);
 
2061
    my_error(err_no,errortype, buff, db_errno);
 
2062
    delete file;
 
2063
    break;
 
2064
  }
 
2065
  case 5:
 
2066
  {
 
2067
    const char *csname= get_charset_name((uint) errarg);
 
2068
    char tmp[10];
 
2069
    if (!csname || csname[0] =='?')
 
2070
    {
 
2071
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
 
2072
      csname= tmp;
 
2073
    }
 
2074
    my_printf_error(ER_UNKNOWN_COLLATION,
 
2075
                    _("Unknown collation '%s' in table '%-.64s' definition"),
 
2076
                    MYF(0), csname, share->table_name.str);
 
2077
    break;
 
2078
  }
 
2079
  case 6:
 
2080
    sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
 
2081
    my_printf_error(ER_NOT_FORM_FILE,
 
2082
                    _("Table '%-.64s' was created with a different version "
 
2083
                    "of Drizzle and cannot be read"),
 
2084
                    MYF(0), buff);
 
2085
    break;
 
2086
  case 8:
 
2087
    break;
 
2088
  default:                              /* Better wrong error than none */
 
2089
  case 4:
 
2090
    sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
 
2091
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
 
2092
    break;
 
2093
  }
 
2094
  return;
 
2095
} /* open_table_error */
 
2096
 
 
2097
 
 
2098
        /*
 
2099
        ** fix a str_type to a array type
 
2100
        ** typeparts separated with some char. differents types are separated
 
2101
        ** with a '\0'
 
2102
        */
 
2103
 
 
2104
static void
 
2105
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
 
2106
                  char **names)
 
2107
{
 
2108
  char *type_name, *ptr;
 
2109
  char chr;
 
2110
 
 
2111
  ptr= *names;
 
2112
  while (types--)
 
2113
  {
 
2114
    point_to_type->name=0;
 
2115
    point_to_type->type_names= *array;
 
2116
 
 
2117
    if ((chr= *ptr))                    /* Test if empty type */
 
2118
    {
 
2119
      while ((type_name=strchr(ptr+1,chr)) != NULL)
 
2120
      {
 
2121
        *((*array)++) = ptr+1;
 
2122
        *type_name= '\0';               /* End string */
 
2123
        ptr=type_name;
 
2124
      }
 
2125
      ptr+=2;                           /* Skip end mark and last 0 */
 
2126
    }
 
2127
    else
 
2128
      ptr++;
 
2129
    point_to_type->count= (uint) (*array - point_to_type->type_names);
 
2130
    point_to_type++;
 
2131
    *((*array)++)= NULL;                /* End of type */
 
2132
  }
 
2133
  *names=ptr;                           /* Update end */
 
2134
  return;
 
2135
} /* fix_type_pointers */
 
2136
 
 
2137
 
 
2138
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
 
2139
{
 
2140
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
214
2141
  if (!result)
215
2142
    return 0;
216
 
  result->count= strings.elements;
217
 
  result->name= "";
218
 
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
219
 
  
220
 
  if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
 
2143
  result->count=strings.elements;
 
2144
  result->name="";
 
2145
  uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
 
2146
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
221
2147
    return 0;
222
 
    
223
2148
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
224
 
 
225
2149
  List_iterator<String> it(strings);
226
2150
  String *tmp;
227
 
  for (uint32_t i= 0; (tmp= it++); i++)
 
2151
  for (uint32_t i=0; (tmp=it++) ; i++)
228
2152
  {
229
2153
    result->type_names[i]= tmp->ptr();
230
2154
    result->type_lengths[i]= tmp->length();
231
2155
  }
232
 
 
233
 
  result->type_names[result->count]= 0;   // End marker
 
2156
  result->type_names[result->count]= 0;         // End marker
234
2157
  result->type_lengths[result->count]= 0;
235
 
 
236
2158
  return result;
237
2159
}
238
2160
 
 
2161
 
 
2162
/*
 
2163
 Search after a field with given start & length
 
2164
 If an exact field isn't found, return longest field with starts
 
2165
 at right position.
 
2166
 
 
2167
 NOTES
 
2168
   This is needed because in some .frm fields 'fieldnr' was saved wrong
 
2169
 
 
2170
 RETURN
 
2171
   0  error
 
2172
   #  field number +1
 
2173
*/
 
2174
 
 
2175
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length)
 
2176
{
 
2177
  Field **field;
 
2178
  uint32_t i, pos;
 
2179
 
 
2180
  pos= 0;
 
2181
  for (field= fields, i=1 ; *field ; i++,field++)
 
2182
  {
 
2183
    if ((*field)->offset(record) == start)
 
2184
    {
 
2185
      if ((*field)->key_length() == length)
 
2186
        return (i);
 
2187
      if (!pos || fields[pos-1]->pack_length() <
 
2188
          (*field)->pack_length())
 
2189
        pos= i;
 
2190
    }
 
2191
  }
 
2192
  return (pos);
 
2193
}
 
2194
 
 
2195
 
239
2196
        /* Check that the integer is in the internal */
240
2197
 
241
2198
int set_zone(register int nr, int min_zone, int max_zone)
247
2204
  return (nr);
248
2205
} /* set_zone */
249
2206
 
 
2207
        /* Adjust number to next larger disk buffer */
 
2208
 
 
2209
ulong next_io_size(register ulong pos)
 
2210
{
 
2211
  register ulong offset;
 
2212
  if ((offset= pos & (IO_SIZE-1)))
 
2213
    return pos-offset+IO_SIZE;
 
2214
  return pos;
 
2215
} /* next_io_size */
 
2216
 
250
2217
 
251
2218
/*
252
2219
  Store an SQL quoted string.
269
2236
 
270
2237
  for (; pos != end ; pos++)
271
2238
  {
 
2239
#if defined(USE_MB)
272
2240
    uint32_t mblen;
273
2241
    if (use_mb(default_charset_info) &&
274
2242
        (mblen= my_ismbchar(default_charset_info, pos, end)))
275
2243
    {
276
2244
      res->append(pos, mblen);
277
 
      pos+= mblen - 1;
278
 
      if (pos >= end)
279
 
        break;
 
2245
      pos+= mblen;
280
2246
      continue;
281
2247
    }
 
2248
#endif
282
2249
 
283
2250
    switch (*pos) {
284
2251
    case 0:                             /* Must be escaped for 'mysql' */
310
2277
}
311
2278
 
312
2279
 
 
2280
        /* Create a .frm file */
 
2281
 
 
2282
File create_frm(Session *session, const char *name, const char *db,
 
2283
                const char *table, uint32_t reclength, unsigned char *fileinfo,
 
2284
                HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
 
2285
{
 
2286
  register File file;
 
2287
  ulong length;
 
2288
  unsigned char fill[IO_SIZE];
 
2289
  int create_flags= O_RDWR | O_TRUNC;
 
2290
  ulong key_comment_total_bytes= 0;
 
2291
  uint32_t i;
 
2292
 
 
2293
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
 
2294
    create_flags|= O_EXCL;
 
2295
 
 
2296
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
 
2297
  if (create_info->max_rows > UINT32_MAX)
 
2298
    create_info->max_rows= UINT32_MAX;
 
2299
  if (create_info->min_rows > UINT32_MAX)
 
2300
    create_info->min_rows= UINT32_MAX;
 
2301
 
 
2302
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
 
2303
  {
 
2304
    uint32_t key_length, tmp_key_length;
 
2305
    uint32_t tmp;
 
2306
    memset(fileinfo, 0, 64);
 
2307
    /* header */
 
2308
    fileinfo[0]=(unsigned char) 254;
 
2309
    fileinfo[1]= 1;
 
2310
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
 
2311
 
 
2312
    fileinfo[3]= (unsigned char) ha_legacy_type(
 
2313
          ha_checktype(session,ha_legacy_type(create_info->db_type),0,0));
 
2314
    fileinfo[4]=1;
 
2315
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
 
2316
    for (i= 0; i < keys; i++)
 
2317
    {
 
2318
      assert(test(key_info[i].flags & HA_USES_COMMENT) ==
 
2319
                 (key_info[i].comment.length > 0));
 
2320
      if (key_info[i].flags & HA_USES_COMMENT)
 
2321
        key_comment_total_bytes += 2 + key_info[i].comment.length;
 
2322
    }
 
2323
    /*
 
2324
      Keep in sync with pack_keys() in unireg.cc
 
2325
      For each key:
 
2326
      8 bytes for the key header
 
2327
      9 bytes for each key-part (MAX_REF_PARTS)
 
2328
      NAME_LEN bytes for the name
 
2329
      1 byte for the NAMES_SEP_CHAR (before the name)
 
2330
      For all keys:
 
2331
      6 bytes for the header
 
2332
      1 byte for the NAMES_SEP_CHAR (after the last name)
 
2333
      9 extra bytes (padding for safety? alignment?)
 
2334
      comments
 
2335
    */
 
2336
    key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
 
2337
                 key_comment_total_bytes);
 
2338
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
 
2339
                                  create_info->extra_size));
 
2340
    int4store(fileinfo+10,length);
 
2341
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
 
2342
    int2store(fileinfo+14,tmp_key_length);
 
2343
    int2store(fileinfo+16,reclength);
 
2344
    int4store(fileinfo+18,create_info->max_rows);
 
2345
    int4store(fileinfo+22,create_info->min_rows);
 
2346
    /* fileinfo[26] is set in mysql_create_frm() */
 
2347
    fileinfo[27]=2;                             // Use long pack-fields
 
2348
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
 
2349
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
 
2350
    int2store(fileinfo+30,create_info->table_options);
 
2351
    fileinfo[32]=0;                             // No filename anymore
 
2352
    fileinfo[33]=5;                             // Mark for 5.0 frm file
 
2353
    int4store(fileinfo+34,create_info->avg_row_length);
 
2354
    fileinfo[38]= (create_info->default_table_charset ?
 
2355
                   create_info->default_table_charset->number : 0);
 
2356
    fileinfo[39]= (unsigned char) create_info->page_checksum;
 
2357
    fileinfo[40]= (unsigned char) create_info->row_type;
 
2358
    /* Next few bytes were for RAID support */
 
2359
    fileinfo[41]= 0;
 
2360
    fileinfo[42]= 0;
 
2361
    int4store(fileinfo+43,create_info->block_size);
 
2362
 
 
2363
    fileinfo[44]= 0;
 
2364
    fileinfo[45]= 0;
 
2365
    fileinfo[46]= 0;
 
2366
    int4store(fileinfo+47, key_length);
 
2367
    tmp= DRIZZLE_VERSION_ID;          // Store to avoid warning from int4store
 
2368
    int4store(fileinfo+51, tmp);
 
2369
    int4store(fileinfo+55, create_info->extra_size);
 
2370
    /*
 
2371
      59-60 is reserved for extra_rec_buf_length,
 
2372
      61 for default_part_db_type
 
2373
    */
 
2374
    int2store(fileinfo+62, create_info->key_block_size);
 
2375
    memset(fill, 0, IO_SIZE);
 
2376
    for (; length > IO_SIZE ; length-= IO_SIZE)
 
2377
    {
 
2378
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
 
2379
      {
 
2380
        my_close(file,MYF(0));
 
2381
        my_delete(name,MYF(0));
 
2382
        return(-1);
 
2383
      }
 
2384
    }
 
2385
  }
 
2386
  else
 
2387
  {
 
2388
    if (my_errno == ENOENT)
 
2389
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
2390
    else
 
2391
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
 
2392
  }
 
2393
  return (file);
 
2394
} /* create_frm */
 
2395
 
 
2396
/*
 
2397
  Set up column usage bitmaps for a temporary table
 
2398
 
 
2399
  IMPLEMENTATION
 
2400
    For temporary tables, we need one bitmap with all columns set and
 
2401
    a tmp_set bitmap to be used by things like filesort.
 
2402
*/
 
2403
 
 
2404
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
2405
{
 
2406
  uint32_t field_count= s->fields;
 
2407
 
 
2408
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count, false);
 
2409
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count, false);
 
2410
 
 
2411
  /* write_set and all_set are copies of read_set */
 
2412
  def_write_set= def_read_set;
 
2413
  s->all_set= def_read_set;
 
2414
  bitmap_set_all(&this->s->all_set);
 
2415
  default_column_bitmaps();
 
2416
}
 
2417
 
 
2418
 
 
2419
 
 
2420
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
 
2421
{
 
2422
  create_info->max_rows= s->max_rows;
 
2423
  create_info->min_rows= s->min_rows;
 
2424
  create_info->table_options= s->db_create_options;
 
2425
  create_info->avg_row_length= s->avg_row_length;
 
2426
  create_info->block_size= s->block_size;
 
2427
  create_info->row_type= s->row_type;
 
2428
  create_info->default_table_charset= s->table_charset;
 
2429
  create_info->table_charset= 0;
 
2430
  create_info->comment= s->comment;
 
2431
 
 
2432
  return;
 
2433
}
 
2434
 
313
2435
int rename_file_ext(const char * from,const char * to,const char * ext)
314
2436
{
315
2437
  string from_s, to_s;
318
2440
  from_s.append(ext);
319
2441
  to_s.append(to);
320
2442
  to_s.append(ext);
321
 
  return (internal::my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
2443
  return (my_rename(from_s.c_str(),to_s.c_str(),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;
322
2532
}
323
2533
 
324
2534
/*
328
2538
    check_db_name()
329
2539
    org_name            Name of database and length
330
2540
 
 
2541
  NOTES
 
2542
    If lower_case_table_names is set then database is converted to lower case
 
2543
 
331
2544
  RETURN
332
 
    false error
333
 
    true ok
 
2545
    0   ok
 
2546
    1   error
334
2547
*/
335
2548
 
336
 
bool check_db_name(Session *session, SchemaIdentifier &schema_identifier)
 
2549
bool check_db_name(LEX_STRING *org_name)
337
2550
{
338
 
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
339
 
  {
340
 
    return false;
341
 
  }
342
 
 
343
 
  return schema_identifier.isValid();
 
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);
344
2561
}
345
2562
 
 
2563
 
346
2564
/*
347
2565
  Allow anything as a table name, as long as it doesn't contain an
348
2566
  ' ' at the end
349
2567
  returns 1 on error
350
2568
*/
 
2569
 
 
2570
 
351
2571
bool check_table_name(const char *name, uint32_t length)
352
2572
{
353
2573
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
371
2591
 
372
2592
  while (*name)
373
2593
  {
 
2594
#if defined(USE_MB) && defined(USE_MB_IDENT)
374
2595
    last_char_is_space= my_isspace(system_charset_info, *name);
375
2596
    if (use_mb(system_charset_info))
376
2597
    {
385
2606
        continue;
386
2607
      }
387
2608
    }
 
2609
#else
 
2610
    last_char_is_space= *name==' ';
 
2611
#endif
388
2612
    /*
389
2613
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
390
2614
      It is defined as 0xFF, which is a not valid byte in utf8.
396
2620
    name_length++;
397
2621
  }
398
2622
  /* Error if empty or too long column name */
399
 
  return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
 
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
      errmsg_printf(ERRMSG_LVL_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
      errmsg_printf(ERRMSG_LVL_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
        errmsg_printf(ERRMSG_LVL_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
        errmsg_printf(ERRMSG_LVL_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
        errmsg_printf(ERRMSG_LVL_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
        errmsg_printf(ERRMSG_LVL_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
      errmsg_printf(ERRMSG_LVL_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
}
 
2860
 
 
2861
 
 
2862
bool TableList::placeholder()
 
2863
{
 
2864
  return derived || schema_table || (create && !table->getDBStat()) || !table;
 
2865
}
 
2866
 
 
2867
 
 
2868
/*
 
2869
  Set insert_values buffer
 
2870
 
 
2871
  SYNOPSIS
 
2872
    set_insert_values()
 
2873
    mem_root   memory pool for allocating
 
2874
 
 
2875
  RETURN
 
2876
    false - OK
 
2877
    TRUE  - out of memory
 
2878
*/
 
2879
 
 
2880
bool TableList::set_insert_values(MEM_ROOT *mem_root)
 
2881
{
 
2882
  if (table)
 
2883
  {
 
2884
    if (!table->insert_values &&
 
2885
        !(table->insert_values= (unsigned char *)alloc_root(mem_root,
 
2886
                                                   table->s->rec_buff_length)))
 
2887
      return true;
 
2888
  }
 
2889
 
 
2890
  return false;
 
2891
}
 
2892
 
 
2893
 
 
2894
/*
 
2895
  Test if this is a leaf with respect to name resolution.
 
2896
 
 
2897
  SYNOPSIS
 
2898
    TableList::is_leaf_for_name_resolution()
 
2899
 
 
2900
  DESCRIPTION
 
2901
    A table reference is a leaf with respect to name resolution if
 
2902
    it is either a leaf node in a nested join tree (table, view,
 
2903
    schema table, subquery), or an inner node that represents a
 
2904
    NATURAL/USING join, or a nested join with materialized join
 
2905
    columns.
 
2906
 
 
2907
  RETURN
 
2908
    TRUE if a leaf, false otherwise.
 
2909
*/
 
2910
bool TableList::is_leaf_for_name_resolution()
 
2911
{
 
2912
  return (is_natural_join || is_join_columns_complete || !nested_join);
 
2913
}
 
2914
 
 
2915
 
 
2916
/*
 
2917
  Retrieve the first (left-most) leaf in a nested join tree with
 
2918
  respect to name resolution.
 
2919
 
 
2920
  SYNOPSIS
 
2921
    TableList::first_leaf_for_name_resolution()
 
2922
 
 
2923
  DESCRIPTION
 
2924
    Given that 'this' is a nested table reference, recursively walk
 
2925
    down the left-most children of 'this' until we reach a leaf
 
2926
    table reference with respect to name resolution.
 
2927
 
 
2928
  IMPLEMENTATION
 
2929
    The left-most child of a nested table reference is the last element
 
2930
    in the list of children because the children are inserted in
 
2931
    reverse order.
 
2932
 
 
2933
  RETURN
 
2934
    If 'this' is a nested table reference - the left-most child of
 
2935
      the tree rooted in 'this',
 
2936
    else return 'this'
 
2937
*/
 
2938
 
 
2939
TableList *TableList::first_leaf_for_name_resolution()
 
2940
{
 
2941
  TableList *cur_table_ref= NULL;
 
2942
  nested_join_st *cur_nested_join;
 
2943
 
 
2944
  if (is_leaf_for_name_resolution())
 
2945
    return this;
 
2946
  assert(nested_join);
 
2947
 
 
2948
  for (cur_nested_join= nested_join;
 
2949
       cur_nested_join;
 
2950
       cur_nested_join= cur_table_ref->nested_join)
 
2951
  {
 
2952
    List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
2953
    cur_table_ref= it++;
 
2954
    /*
 
2955
      If the current nested join is a RIGHT JOIN, the operands in
 
2956
      'join_list' are in reverse order, thus the first operand is
 
2957
      already at the front of the list. Otherwise the first operand
 
2958
      is in the end of the list of join operands.
 
2959
    */
 
2960
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
2961
    {
 
2962
      TableList *next;
 
2963
      while ((next= it++))
 
2964
        cur_table_ref= next;
 
2965
    }
 
2966
    if (cur_table_ref->is_leaf_for_name_resolution())
 
2967
      break;
 
2968
  }
 
2969
  return cur_table_ref;
 
2970
}
 
2971
 
 
2972
 
 
2973
/*
 
2974
  Retrieve the last (right-most) leaf in a nested join tree with
 
2975
  respect to name resolution.
 
2976
 
 
2977
  SYNOPSIS
 
2978
    TableList::last_leaf_for_name_resolution()
 
2979
 
 
2980
  DESCRIPTION
 
2981
    Given that 'this' is a nested table reference, recursively walk
 
2982
    down the right-most children of 'this' until we reach a leaf
 
2983
    table reference with respect to name resolution.
 
2984
 
 
2985
  IMPLEMENTATION
 
2986
    The right-most child of a nested table reference is the first
 
2987
    element in the list of children because the children are inserted
 
2988
    in reverse order.
 
2989
 
 
2990
  RETURN
 
2991
    - If 'this' is a nested table reference - the right-most child of
 
2992
      the tree rooted in 'this',
 
2993
    - else - 'this'
 
2994
*/
 
2995
 
 
2996
TableList *TableList::last_leaf_for_name_resolution()
 
2997
{
 
2998
  TableList *cur_table_ref= this;
 
2999
  nested_join_st *cur_nested_join;
 
3000
 
 
3001
  if (is_leaf_for_name_resolution())
 
3002
    return this;
 
3003
  assert(nested_join);
 
3004
 
 
3005
  for (cur_nested_join= nested_join;
 
3006
       cur_nested_join;
 
3007
       cur_nested_join= cur_table_ref->nested_join)
 
3008
  {
 
3009
    cur_table_ref= cur_nested_join->join_list.head();
 
3010
    /*
 
3011
      If the current nested is a RIGHT JOIN, the operands in
 
3012
      'join_list' are in reverse order, thus the last operand is in the
 
3013
      end of the list.
 
3014
    */
 
3015
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
3016
    {
 
3017
      List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
3018
      TableList *next;
 
3019
      cur_table_ref= it++;
 
3020
      while ((next= it++))
 
3021
        cur_table_ref= next;
 
3022
    }
 
3023
    if (cur_table_ref->is_leaf_for_name_resolution())
 
3024
      break;
 
3025
  }
 
3026
  return cur_table_ref;
400
3027
}
401
3028
 
402
3029
 
413
3040
    bitmap_clear_all(&table->def_read_set);
414
3041
    bitmap_clear_all(&table->def_write_set);
415
3042
  */
416
 
  def_read_set.reset();
417
 
  def_write_set.reset();
418
 
  column_bitmaps_set(def_read_set, def_write_set);
 
3043
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
 
3044
  column_bitmaps_set(&def_read_set, &def_write_set);
419
3045
}
420
3046
 
421
3047
 
422
3048
/*
423
 
  Tell Cursor we are going to call position() and rnd_pos() later.
 
3049
  Tell handler we are going to call position() and rnd_pos() later.
424
3050
 
425
3051
  NOTES:
426
3052
  This is needed for handlers that uses the primary key to find the
431
3057
void Table::prepare_for_position()
432
3058
{
433
3059
 
434
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
435
 
      getShare()->hasPrimaryKey())
 
3060
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
 
3061
      s->primary_key < MAX_KEY)
436
3062
  {
437
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
3063
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3064
    /* signal change */
 
3065
    file->column_bitmaps_signal();
438
3066
  }
439
3067
  return;
440
3068
}
452
3080
 
453
3081
void Table::mark_columns_used_by_index(uint32_t index)
454
3082
{
455
 
  boost::dynamic_bitset<> *bitmap= &tmp_set;
 
3083
  MY_BITMAP *bitmap= &tmp_set;
456
3084
 
457
 
  (void) cursor->extra(HA_EXTRA_KEYREAD);
458
 
  bitmap->reset();
459
 
  mark_columns_used_by_index_no_reset(index, *bitmap);
460
 
  column_bitmaps_set(*bitmap, *bitmap);
 
3085
  (void) file->extra(HA_EXTRA_KEYREAD);
 
3086
  bitmap_clear_all(bitmap);
 
3087
  mark_columns_used_by_index_no_reset(index, bitmap);
 
3088
  column_bitmaps_set(bitmap, bitmap);
461
3089
  return;
462
3090
}
463
3091
 
477
3105
{
478
3106
 
479
3107
  key_read= 0;
480
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3108
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
481
3109
  default_column_bitmaps();
 
3110
  file->column_bitmaps_signal();
482
3111
  return;
483
3112
}
484
3113
 
487
3116
  mark columns used by key, but don't reset other fields
488
3117
*/
489
3118
 
490
 
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
491
 
{
492
 
    mark_columns_used_by_index_no_reset(index, *read_set);
493
 
}
494
 
 
495
 
 
496
3119
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
497
 
                                                boost::dynamic_bitset<>& bitmap)
 
3120
                                                   MY_BITMAP *bitmap)
498
3121
{
499
 
  KeyPartInfo *key_part= key_info[index].key_part;
500
 
  KeyPartInfo *key_part_end= (key_part + key_info[index].key_parts);
501
 
  for (; key_part != key_part_end; key_part++)
 
3122
  KEY_PART_INFO *key_part= key_info[index].key_part;
 
3123
  KEY_PART_INFO *key_part_end= (key_part +
 
3124
                                key_info[index].key_parts);
 
3125
  for (;key_part != key_part_end; key_part++)
502
3126
  {
503
 
    if (! bitmap.empty())
504
 
      bitmap.set(key_part->fieldnr-1);
 
3127
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
 
3128
    if (key_part->field->vcol_info &&
 
3129
        key_part->field->vcol_info->expr_item)
 
3130
      key_part->field->vcol_info->
 
3131
               expr_item->walk(&Item::register_field_in_bitmap,
 
3132
                               1, (unsigned char *) bitmap);
505
3133
  }
506
3134
}
507
3135
 
521
3149
    We must set bit in read set as update_auto_increment() is using the
522
3150
    store() to check overflow of auto_increment values
523
3151
  */
524
 
  setReadSet(found_next_number_field->position());
525
 
  setWriteSet(found_next_number_field->position());
526
 
  if (getShare()->next_number_keypart)
527
 
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
 
3152
  bitmap_set_bit(read_set, found_next_number_field->field_index);
 
3153
  bitmap_set_bit(write_set, found_next_number_field->field_index);
 
3154
  if (s->next_number_keypart)
 
3155
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
 
3156
  file->column_bitmaps_signal();
528
3157
}
529
3158
 
530
3159
 
548
3177
 
549
3178
void Table::mark_columns_needed_for_delete()
550
3179
{
551
 
  /*
552
 
    If the Cursor has no cursor capabilites, or we have row-based
553
 
    replication active for the current statement, we have to read
554
 
    either the primary key, the hidden primary key or all columns to
555
 
    be able to do an delete
556
 
 
557
 
  */
558
 
  if (not getShare()->hasPrimaryKey())
559
 
  {
560
 
    /* fallback to use all columns in the table to identify row */
561
 
    use_all_columns();
562
 
    return;
563
 
  }
564
 
  else
565
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
566
 
 
567
 
  /* If we the engine wants all predicates we mark all keys */
568
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
3180
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
569
3181
  {
570
3182
    Field **reg_field;
571
3183
    for (reg_field= field ; *reg_field ; reg_field++)
572
3184
    {
573
3185
      if ((*reg_field)->flags & PART_KEY_FLAG)
574
 
        setReadSet((*reg_field)->position());
 
3186
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
3187
    }
 
3188
    file->column_bitmaps_signal();
 
3189
  }
 
3190
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE || (drizzle_bin_log.is_open() && in_use))
 
3191
  {
 
3192
    /*
 
3193
      If the handler has no cursor capabilites, or we have row-based
 
3194
      replication active for the current statement, we have to read
 
3195
      either the primary key, the hidden primary key or all columns to
 
3196
      be able to do an delete
 
3197
    */
 
3198
    if (s->primary_key == MAX_KEY)
 
3199
      file->use_hidden_primary_key();
 
3200
    else
 
3201
    {
 
3202
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3203
      file->column_bitmaps_signal();
575
3204
    }
576
3205
  }
577
3206
}
589
3218
    if neeed, either the primary key column or all columns to be read.
590
3219
    (see mark_columns_needed_for_delete() for details)
591
3220
 
592
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
3221
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
593
3222
    mark all USED key columns as 'to-be-read'. This allows the engine to
594
3223
    loop over the given record to find all changed keys and doesn't have to
595
3224
    retrieve the row again.
597
3226
 
598
3227
void Table::mark_columns_needed_for_update()
599
3228
{
600
 
  /*
601
 
    If the Cursor has no cursor capabilites, or we have row-based
602
 
    logging active for the current statement, we have to read either
603
 
    the primary key, the hidden primary key or all columns to be
604
 
    able to do an update
605
 
  */
606
 
  if (not getShare()->hasPrimaryKey())
607
 
  {
608
 
    /* fallback to use all columns in the table to identify row */
609
 
    use_all_columns();
610
 
    return;
611
 
  }
612
 
  else
613
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
614
 
 
615
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
3229
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
616
3230
  {
617
3231
    /* Mark all used key columns for read */
618
3232
    Field **reg_field;
619
3233
    for (reg_field= field ; *reg_field ; reg_field++)
620
3234
    {
621
3235
      /* Merge keys is all keys that had a column refered to in the query */
622
 
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
623
 
        setReadSet((*reg_field)->position());
624
 
    }
625
 
  }
626
 
 
 
3236
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
 
3237
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
3238
    }
 
3239
    file->column_bitmaps_signal();
 
3240
  }
 
3241
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) ||
 
3242
      (drizzle_bin_log.is_open() && in_use))
 
3243
  {
 
3244
    /*
 
3245
      If the handler has no cursor capabilites, or we have row-based
 
3246
      logging active for the current statement, we have to read either
 
3247
      the primary key, the hidden primary key or all columns to be
 
3248
      able to do an update
 
3249
    */
 
3250
    if (s->primary_key == MAX_KEY)
 
3251
      file->use_hidden_primary_key();
 
3252
    else
 
3253
    {
 
3254
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3255
      file->column_bitmaps_signal();
 
3256
    }
 
3257
  }
 
3258
  /* Mark all virtual columns as writable */
 
3259
  mark_virtual_columns();
 
3260
  return;
627
3261
}
628
3262
 
629
3263
 
630
3264
/*
631
 
  Mark columns the Cursor needs for doing an insert
 
3265
  Mark columns the handler needs for doing an insert
632
3266
 
633
3267
  For now, this is used to mark fields used by the trigger
634
3268
  as changed.
638
3272
{
639
3273
  if (found_next_number_field)
640
3274
    mark_auto_increment_column();
641
 
}
642
 
 
 
3275
  /* Mark all virtual columns as writable */
 
3276
  mark_virtual_columns();
 
3277
}
 
3278
 
 
3279
/*
 
3280
  @brief Update the write and read table bitmap to allow
 
3281
         using procedure save_in_field for all virtual columns
 
3282
         in the table.
 
3283
 
 
3284
  @return       void
 
3285
 
 
3286
  @detail
 
3287
    Each virtual field is set in the write column map.
 
3288
    All fields that the virtual columns are based on are set in the
 
3289
    read bitmap.
 
3290
*/
 
3291
 
 
3292
void Table::mark_virtual_columns(void)
 
3293
{
 
3294
  Field **vfield_ptr, *tmp_vfield;
 
3295
  bool bitmap_updated= false;
 
3296
 
 
3297
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
 
3298
  {
 
3299
    tmp_vfield= *vfield_ptr;
 
3300
    assert(tmp_vfield->vcol_info && tmp_vfield->vcol_info->expr_item);
 
3301
    tmp_vfield->vcol_info->expr_item->walk(&Item::register_field_in_read_map,
 
3302
                                           1, (unsigned char *) 0);
 
3303
    bitmap_set_bit(read_set, tmp_vfield->field_index);
 
3304
    bitmap_set_bit(write_set, tmp_vfield->field_index);
 
3305
    bitmap_updated= true;
 
3306
  }
 
3307
  if (bitmap_updated)
 
3308
    file->column_bitmaps_signal();
 
3309
}
 
3310
 
 
3311
 
 
3312
/*
 
3313
  Cleanup this table for re-execution.
 
3314
 
 
3315
  SYNOPSIS
 
3316
    TableList::reinit_before_use()
 
3317
*/
 
3318
 
 
3319
void TableList::reinit_before_use(Session *session)
 
3320
{
 
3321
  /*
 
3322
    Reset old pointers to TABLEs: they are not valid since the tables
 
3323
    were closed in the end of previous prepare or execute call.
 
3324
  */
 
3325
  table= 0;
 
3326
  /* Reset is_schema_table_processed value(needed for I_S tables */
 
3327
  schema_table_state= NOT_PROCESSED;
 
3328
 
 
3329
  TableList *embedded; /* The table at the current level of nesting. */
 
3330
  TableList *parent_embedding= this; /* The parent nested table reference. */
 
3331
  do
 
3332
  {
 
3333
    embedded= parent_embedding;
 
3334
    if (embedded->prep_on_expr)
 
3335
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
 
3336
    parent_embedding= embedded->embedding;
 
3337
  }
 
3338
  while (parent_embedding &&
 
3339
         parent_embedding->nested_join->join_list.head() == embedded);
 
3340
}
 
3341
 
 
3342
/*
 
3343
  Return subselect that contains the FROM list this table is taken from
 
3344
 
 
3345
  SYNOPSIS
 
3346
    TableList::containing_subselect()
 
3347
 
 
3348
  RETURN
 
3349
    Subselect item for the subquery that contains the FROM list
 
3350
    this table is taken from if there is any
 
3351
    0 - otherwise
 
3352
 
 
3353
*/
 
3354
 
 
3355
Item_subselect *TableList::containing_subselect()
 
3356
{
 
3357
  return (select_lex ? select_lex->master_unit()->item : 0);
 
3358
}
 
3359
 
 
3360
/*
 
3361
  Compiles the tagged hints list and fills up the bitmasks.
 
3362
 
 
3363
  SYNOPSIS
 
3364
    process_index_hints()
 
3365
      table         the Table to operate on.
 
3366
 
 
3367
  DESCRIPTION
 
3368
    The parser collects the index hints for each table in a "tagged list"
 
3369
    (TableList::index_hints). Using the information in this tagged list
 
3370
    this function sets the members Table::keys_in_use_for_query,
 
3371
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
 
3372
    Table::force_index and Table::covering_keys.
 
3373
 
 
3374
    Current implementation of the runtime does not allow mixing FORCE INDEX
 
3375
    and USE INDEX, so this is checked here. Then the FORCE INDEX list
 
3376
    (if non-empty) is appended to the USE INDEX list and a flag is set.
 
3377
 
 
3378
    Multiple hints of the same kind are processed so that each clause
 
3379
    is applied to what is computed in the previous clause.
 
3380
    For example:
 
3381
        USE INDEX (i1) USE INDEX (i2)
 
3382
    is equivalent to
 
3383
        USE INDEX (i1,i2)
 
3384
    and means "consider only i1 and i2".
 
3385
 
 
3386
    Similarly
 
3387
        USE INDEX () USE INDEX (i1)
 
3388
    is equivalent to
 
3389
        USE INDEX (i1)
 
3390
    and means "consider only the index i1"
 
3391
 
 
3392
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
 
3393
    not an error.
 
3394
 
 
3395
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
 
3396
    order:
 
3397
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
 
3398
      2. All IGNORE INDEX
 
3399
 
 
3400
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
 
3401
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
 
3402
 
 
3403
    As an optimization if there is a covering index, and we have
 
3404
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
 
3405
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
 
3406
 
 
3407
  RETURN VALUE
 
3408
    false                no errors found
 
3409
    TRUE                 found and reported an error.
 
3410
*/
 
3411
bool TableList::process_index_hints(Table *tbl)
 
3412
{
 
3413
  /* initialize the result variables */
 
3414
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
 
3415
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
 
3416
 
 
3417
  /* index hint list processing */
 
3418
  if (index_hints)
 
3419
  {
 
3420
    key_map index_join[INDEX_HINT_FORCE + 1];
 
3421
    key_map index_order[INDEX_HINT_FORCE + 1];
 
3422
    key_map index_group[INDEX_HINT_FORCE + 1];
 
3423
    Index_hint *hint;
 
3424
    int type;
 
3425
    bool have_empty_use_join= false, have_empty_use_order= false,
 
3426
         have_empty_use_group= false;
 
3427
    List_iterator <Index_hint> iter(*index_hints);
 
3428
 
 
3429
    /* initialize temporary variables used to collect hints of each kind */
 
3430
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
 
3431
    {
 
3432
      index_join[type].clear_all();
 
3433
      index_order[type].clear_all();
 
3434
      index_group[type].clear_all();
 
3435
    }
 
3436
 
 
3437
    /* iterate over the hints list */
 
3438
    while ((hint= iter++))
 
3439
    {
 
3440
      uint32_t pos;
 
3441
 
 
3442
      /* process empty USE INDEX () */
 
3443
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
 
3444
      {
 
3445
        if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3446
        {
 
3447
          index_join[hint->type].clear_all();
 
3448
          have_empty_use_join= true;
 
3449
        }
 
3450
        if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3451
        {
 
3452
          index_order[hint->type].clear_all();
 
3453
          have_empty_use_order= true;
 
3454
        }
 
3455
        if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3456
        {
 
3457
          index_group[hint->type].clear_all();
 
3458
          have_empty_use_group= true;
 
3459
        }
 
3460
        continue;
 
3461
      }
 
3462
 
 
3463
      /*
 
3464
        Check if an index with the given name exists and get his offset in
 
3465
        the keys bitmask for the table
 
3466
      */
 
3467
      if (tbl->s->keynames.type_names == 0 ||
 
3468
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
 
3469
                          hint->key_name.length, 1)) <= 0)
 
3470
      {
 
3471
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
 
3472
        return 1;
 
3473
      }
 
3474
 
 
3475
      pos--;
 
3476
 
 
3477
      /* add to the appropriate clause mask */
 
3478
      if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3479
        index_join[hint->type].set_bit (pos);
 
3480
      if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3481
        index_order[hint->type].set_bit (pos);
 
3482
      if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3483
        index_group[hint->type].set_bit (pos);
 
3484
    }
 
3485
 
 
3486
    /* cannot mix USE INDEX and FORCE INDEX */
 
3487
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3488
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3489
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
 
3490
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
 
3491
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
 
3492
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
 
3493
    {
 
3494
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
 
3495
               index_hint_type_name[INDEX_HINT_FORCE]);
 
3496
      return 1;
 
3497
    }
 
3498
 
 
3499
    /* process FORCE INDEX as USE INDEX with a flag */
 
3500
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3501
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3502
        !index_group[INDEX_HINT_FORCE].is_clear_all())
 
3503
    {
 
3504
      tbl->force_index= true;
 
3505
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
 
3506
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
 
3507
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
 
3508
    }
 
3509
 
 
3510
    /* apply USE INDEX */
 
3511
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
 
3512
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
 
3513
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
 
3514
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
 
3515
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
 
3516
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
 
3517
 
 
3518
    /* apply IGNORE INDEX */
 
3519
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
 
3520
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
 
3521
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
 
3522
  }
 
3523
 
 
3524
  /* make sure covering_keys don't include indexes disabled with a hint */
 
3525
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
 
3526
  return 0;
 
3527
}
643
3528
 
644
3529
 
645
3530
size_t Table::max_row_length(const unsigned char *data)
652
3537
  {
653
3538
    Field_blob* const blob= (Field_blob*) field[*ptr];
654
3539
    length+= blob->get_length((const unsigned char*)
655
 
                              (data + blob->offset(getInsertRecord()))) +
 
3540
                              (data + blob->offset(record[0]))) +
656
3541
      HA_KEY_BLOB_LENGTH;
657
3542
  }
658
3543
  return length;
659
3544
}
660
3545
 
661
 
void Table::setVariableWidth(void)
662
 
{
663
 
  assert(in_use);
664
 
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
665
 
  {
666
 
    getMutableShare()->setVariableWidth();
667
 
    return;
668
 
  }
669
 
 
670
 
  assert(0); // Programming error, you can't set this on a plain old Table.
671
 
}
672
 
 
673
3546
/****************************************************************************
674
3547
 Functions for creating temporary tables.
675
3548
****************************************************************************/
 
3549
 
 
3550
 
 
3551
/* Prototypes */
 
3552
void free_tmp_table(Session *session, Table *entry);
 
3553
 
676
3554
/**
677
3555
  Create field for temporary table from given field.
678
3556
 
679
 
  @param session               Thread Cursor
 
3557
  @param session               Thread handler
680
3558
  @param org_field    field from which new field will be created
681
3559
  @param name         New field name
682
3560
  @param table         Temporary table
707
3585
  */
708
3586
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
709
3587
      (org_field->flags & BLOB_FLAG))
710
 
  {
711
 
    table->setVariableWidth();
712
3588
    new_field= new Field_varstring(convert_blob_length,
713
3589
                                   org_field->maybe_null(),
714
 
                                   org_field->field_name,
 
3590
                                   org_field->field_name, table->s,
715
3591
                                   org_field->charset());
716
 
  }
717
3592
  else
718
 
  {
719
3593
    new_field= org_field->new_field(session->mem_root, table,
720
 
                                    table == org_field->getTable());
721
 
  }
 
3594
                                    table == org_field->table);
722
3595
  if (new_field)
723
3596
  {
724
3597
    new_field->init(table);
731
3604
    if (org_field->maybe_null() || (item && item->maybe_null))
732
3605
      new_field->flags&= ~NOT_NULL_FLAG;        // Because of outer join
733
3606
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
734
 
      table->getMutableShare()->db_create_options|= HA_OPTION_PACK_RECORD;
 
3607
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
735
3608
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
736
3609
      ((Field_double *) new_field)->not_fixed= true;
737
3610
  }
740
3613
 
741
3614
 
742
3615
/**
 
3616
  Create field for information schema table.
 
3617
 
 
3618
  @param session                Thread handler
 
3619
  @param table          Temporary table
 
3620
  @param item           Item to create a field for
 
3621
 
 
3622
  @retval
 
3623
    0                   on error
 
3624
  @retval
 
3625
    new_created field
 
3626
*/
 
3627
 
 
3628
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
 
3629
{
 
3630
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
3631
  {
 
3632
    Field *field;
 
3633
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
3634
      field= new Field_blob(item->max_length, item->maybe_null,
 
3635
                            item->name, item->collation.collation);
 
3636
    else
 
3637
      field= new Field_varstring(item->max_length, item->maybe_null,
 
3638
                                 item->name,
 
3639
                                 table->s, item->collation.collation);
 
3640
    if (field)
 
3641
      field->init(table);
 
3642
    return field;
 
3643
  }
 
3644
  return item->tmp_table_field_from_field_type(table, 0);
 
3645
}
 
3646
 
 
3647
 
 
3648
/**
743
3649
  Create a temp table according to a field list.
744
3650
 
745
3651
  Given field pointers are changed to point at tmp_table for
770
3676
#define RATIO_TO_PACK_ROWS             2
771
3677
 
772
3678
Table *
773
 
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
774
 
                 Order *group, bool distinct, bool save_sum_fields,
 
3679
create_tmp_table(Session *session,TMP_TABLE_PARAM *param,List<Item> &fields,
 
3680
                 order_st *group, bool distinct, bool save_sum_fields,
775
3681
                 uint64_t select_options, ha_rows rows_limit,
776
 
                 const char *table_alias)
 
3682
                 char *table_alias)
777
3683
{
778
 
  memory::Root *mem_root_save;
 
3684
  MEM_ROOT *mem_root_save, own_root;
 
3685
  Table *table;
 
3686
  TABLE_SHARE *share;
779
3687
  uint  i,field_count,null_count,null_pack_length;
780
3688
  uint32_t  copy_func_count= param->func_count;
781
3689
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
782
3690
  uint32_t  blob_count,group_null_items, string_count;
 
3691
  uint32_t  temp_pool_slot=MY_BIT_NONE;
783
3692
  uint32_t fieldnr= 0;
784
3693
  ulong reclength, string_total_length;
785
 
  bool  using_unique_constraint= false;
786
 
  bool  use_packed_rows= true;
 
3694
  bool  using_unique_constraint= 0;
 
3695
  bool  use_packed_rows= 0;
787
3696
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
788
 
  unsigned char *pos, *group_buff;
 
3697
  char  *tmpname,path[FN_REFLEN];
 
3698
  unsigned char *pos, *group_buff, *bitmaps;
789
3699
  unsigned char *null_flags;
790
3700
  Field **reg_field, **from_field, **default_field;
791
 
  CopyField *copy= 0;
792
 
  KeyInfo *keyinfo;
793
 
  KeyPartInfo *key_part_info;
 
3701
  uint32_t *blob_field;
 
3702
  Copy_field *copy=0;
 
3703
  KEY *keyinfo;
 
3704
  KEY_PART_INFO *key_part_info;
794
3705
  Item **copy_func;
795
3706
  MI_COLUMNDEF *recinfo;
796
3707
  uint32_t total_uneven_bit_length= 0;
797
3708
  bool force_copy_fields= param->force_copy_fields;
798
 
  uint64_t max_rows= 0;
799
 
 
800
 
  session->status_var.created_tmp_tables++;
 
3709
 
 
3710
  status_var_increment(session->status_var.created_tmp_tables);
 
3711
 
 
3712
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
 
3713
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
 
3714
 
 
3715
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
 
3716
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
 
3717
            (unsigned long)current_pid, temp_pool_slot);
 
3718
  else
 
3719
  {
 
3720
    /* if we run out of slots or we are not using tempool */
 
3721
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
3722
            session->thread_id, session->tmp_table++);
 
3723
  }
 
3724
 
 
3725
  /*
 
3726
    No need to change table name to lower case as we are only creating
 
3727
    MyISAM or HEAP tables here
 
3728
  */
 
3729
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3730
 
801
3731
 
802
3732
  if (group)
803
3733
  {
804
 
    if (! param->quick_group)
805
 
    {
806
 
      group= 0;                                 // Can't use group key
807
 
    }
808
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
3734
    if (!param->quick_group)
 
3735
      group=0;                                  // Can't use group key
 
3736
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
809
3737
    {
810
3738
      /*
811
3739
        marker == 4 means two things:
815
3743
      */
816
3744
      (*tmp->item)->marker= 4;
817
3745
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
818
 
        using_unique_constraint= true;
 
3746
        using_unique_constraint=1;
819
3747
    }
820
3748
    if (param->group_length >= MAX_BLOB_WIDTH)
821
 
      using_unique_constraint= true;
 
3749
      using_unique_constraint=1;
822
3750
    if (group)
823
 
      distinct= 0;                              // Can't use distinct
 
3751
      distinct=0;                               // Can't use distinct
824
3752
  }
825
3753
 
826
3754
  field_count=param->field_count+param->func_count+param->sum_func_count;
830
3758
    When loose index scan is employed as access method, it already
831
3759
    computes all groups and the result of all aggregate functions. We
832
3760
    make space for the items of the aggregate function in the list of
833
 
    functions Tmp_Table_Param::items_to_copy, so that the values of
 
3761
    functions TMP_TABLE_PARAM::items_to_copy, so that the values of
834
3762
    these items are stored in the temporary table.
835
3763
  */
836
3764
  if (param->precomputed_group_by)
837
 
  {
838
3765
    copy_func_count+= param->sum_func_count;
839
 
  }
840
 
 
841
 
  table::Instance *table;
842
 
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
843
 
 
844
 
  if (not table->getMemRoot()->multi_alloc_root(0,
845
 
                                                &default_field, sizeof(Field*) * (field_count),
846
 
                                                &from_field, sizeof(Field*)*field_count,
847
 
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
848
 
                                                &param->keyinfo, sizeof(*param->keyinfo),
849
 
                                                &key_part_info, sizeof(*key_part_info)*(param->group_parts+1),
850
 
                                                &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
851
 
                                                &group_buff, (group && ! using_unique_constraint ?
852
 
                                                              param->group_length : 0),
853
 
                                                NULL))
854
 
  {
855
 
    return NULL;
856
 
  }
857
 
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
858
 
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
859
 
  {
860
 
    return NULL;
 
3766
 
 
3767
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
3768
 
 
3769
  if (!multi_alloc_root(&own_root,
 
3770
                        &table, sizeof(*table),
 
3771
                        &share, sizeof(*share),
 
3772
                        &reg_field, sizeof(Field*) * (field_count+1),
 
3773
                        &default_field, sizeof(Field*) * (field_count),
 
3774
                        &blob_field, sizeof(uint)*(field_count+1),
 
3775
                        &from_field, sizeof(Field*)*field_count,
 
3776
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
 
3777
                        &param->keyinfo, sizeof(*param->keyinfo),
 
3778
                        &key_part_info,
 
3779
                        sizeof(*key_part_info)*(param->group_parts+1),
 
3780
                        &param->start_recinfo,
 
3781
                        sizeof(*param->recinfo)*(field_count*2+4),
 
3782
                        &tmpname, (uint) strlen(path)+1,
 
3783
                        &group_buff, (group && ! using_unique_constraint ?
 
3784
                                      param->group_length : 0),
 
3785
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
3786
                        NULL))
 
3787
  {
 
3788
    if (temp_pool_slot != MY_BIT_NONE)
 
3789
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3790
    return(NULL);                               /* purecov: inspected */
 
3791
  }
 
3792
  /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in Session mem_root */
 
3793
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
 
3794
  {
 
3795
    if (temp_pool_slot != MY_BIT_NONE)
 
3796
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3797
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
3798
    return(NULL);                               /* purecov: inspected */
861
3799
  }
862
3800
  param->items_to_copy= copy_func;
 
3801
  strcpy(tmpname,path);
863
3802
  /* make table according to fields */
864
3803
 
 
3804
  memset(table, 0, sizeof(*table));
 
3805
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
865
3806
  memset(default_field, 0, sizeof(Field*) * (field_count));
866
3807
  memset(from_field, 0, sizeof(Field*)*field_count);
867
3808
 
 
3809
  table->mem_root= own_root;
868
3810
  mem_root_save= session->mem_root;
869
 
  session->mem_root= table->getMemRoot();
 
3811
  session->mem_root= &table->mem_root;
870
3812
 
871
 
  table->getMutableShare()->setFields(field_count+1);
872
 
  table->setFields(table->getMutableShare()->getFields(true));
873
 
  reg_field= table->getMutableShare()->getFields(true);
874
 
  table->setAlias(table_alias);
 
3813
  table->field=reg_field;
 
3814
  table->alias= table_alias;
875
3815
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
876
3816
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
877
3817
  table->map=1;
 
3818
  table->temp_pool_slot = temp_pool_slot;
878
3819
  table->copy_blobs= 1;
879
 
  assert(session);
880
3820
  table->in_use= session;
881
 
  table->quick_keys.reset();
882
 
  table->covering_keys.reset();
883
 
  table->keys_in_use_for_query.reset();
 
3821
  table->quick_keys.init();
 
3822
  table->covering_keys.init();
 
3823
  table->keys_in_use_for_query.init();
884
3824
 
885
 
  table->getMutableShare()->blob_field.resize(field_count+1);
886
 
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
887
 
  table->getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
888
 
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
889
 
  table->getMutableShare()->table_charset= param->table_charset;
890
 
  table->getMutableShare()->keys_for_keyread.reset();
891
 
  table->getMutableShare()->keys_in_use.reset();
 
3825
  table->setShare(share);
 
3826
  init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
 
3827
  share->blob_field= blob_field;
 
3828
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
3829
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
3830
  share->table_charset= param->table_charset;
 
3831
  share->primary_key= MAX_KEY;               // Indicate no primary key
 
3832
  share->keys_for_keyread.init();
 
3833
  share->keys_in_use.init();
892
3834
 
893
3835
  /* Calculate which type of fields we will store in the temporary table */
894
3836
 
895
3837
  reclength= string_total_length= 0;
896
3838
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
897
 
  param->using_indirect_summary_function= 0;
 
3839
  param->using_indirect_summary_function=0;
898
3840
 
899
3841
  List_iterator_fast<Item> li(fields);
900
3842
  Item *item;
925
3867
    }
926
3868
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
927
3869
    {                                           /* Can't calc group yet */
928
 
      ((Item_sum*) item)->result_field= 0;
929
 
      for (i= 0 ; i < ((Item_sum*) item)->arg_count ; i++)
 
3870
      ((Item_sum*) item)->result_field=0;
 
3871
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
930
3872
      {
931
3873
        Item **argp= ((Item_sum*) item)->args + i;
932
3874
        Item *arg= *argp;
936
3878
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
937
3879
                             tmp_from_field, &default_field[fieldnr],
938
3880
                             group != 0,not_all_columns,
939
 
                             false,
 
3881
                             distinct, 0,
940
3882
                             param->convert_blob_length);
941
3883
          if (!new_field)
942
3884
            goto err;                                   // Should be OOM
955
3897
          }
956
3898
          session->mem_root= mem_root_save;
957
3899
          session->change_item_tree(argp, new Item_field(new_field));
958
 
          session->mem_root= table->getMemRoot();
 
3900
          session->mem_root= &table->mem_root;
959
3901
          if (!(new_field->flags & NOT_NULL_FLAG))
960
3902
          {
961
3903
            null_count++;
965
3907
            */
966
3908
            (*argp)->maybe_null=1;
967
3909
          }
968
 
          new_field->setPosition(fieldnr++);
 
3910
          new_field->field_index= fieldnr++;
969
3911
        }
970
3912
      }
971
3913
    }
981
3923
        We here distinguish between UNION and multi-table-updates by the fact
982
3924
        that in the later case group is set to the row pointer.
983
3925
      */
984
 
      Field *new_field=
 
3926
      Field *new_field= (param->schema_table) ?
 
3927
        create_tmp_field_for_schema(session, item, table) :
985
3928
        create_tmp_field(session, table, item, type, &copy_func,
986
3929
                         tmp_from_field, &default_field[fieldnr],
987
3930
                         group != 0,
988
3931
                         !force_copy_fields &&
989
 
                           (not_all_columns || group != 0),
 
3932
                           (not_all_columns || group !=0),
 
3933
                         /*
 
3934
                           If item->marker == 4 then we force create_tmp_field
 
3935
                           to create a 64-bit longs for BIT fields because HEAP
 
3936
                           tables can't index BIT fields directly. We do the same
 
3937
                           for distinct, as we want the distinct index to be
 
3938
                           usable in this case too.
 
3939
                         */
 
3940
                         item->marker == 4 || param->bit_fields_as_long,
990
3941
                         force_copy_fields,
991
3942
                         param->convert_blob_length);
992
3943
 
1012
3963
        group_null_items++;
1013
3964
        new_field->flags|= GROUP_FLAG;
1014
3965
      }
1015
 
      new_field->setPosition(fieldnr++);
 
3966
      new_field->field_index= fieldnr++;
1016
3967
      *(reg_field++)= new_field;
1017
3968
    }
1018
3969
    if (!--hidden_field_count)
1030
3981
      null_count= 0;
1031
3982
    }
1032
3983
  }
1033
 
  assert(fieldnr == (uint32_t) (reg_field - table->getFields()));
1034
 
  assert(field_count >= (uint32_t) (reg_field - table->getFields()));
 
3984
  assert(fieldnr == (uint) (reg_field - table->field));
 
3985
  assert(field_count >= (uint) (reg_field - table->field));
1035
3986
  field_count= fieldnr;
1036
3987
  *reg_field= 0;
1037
3988
  *blob_field= 0;                               // End marker
1038
 
  table->getMutableShare()->fields= field_count;
 
3989
  share->fields= field_count;
1039
3990
 
1040
3991
  /* If result table is small; use a heap */
1041
3992
  /* future: storage engine selection can be made dynamic? */
1042
 
  if (blob_count || using_unique_constraint || 
1043
 
      (session->lex->select_lex.options & SELECT_BIG_RESULT) ||
1044
 
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
1045
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
 
3993
  if (blob_count || using_unique_constraint ||
 
3994
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
3995
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
1046
3996
  {
1047
 
    table->getMutableShare()->storage_engine= myisam_engine;
1048
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
3997
    share->db_plugin= ha_lock_engine(0, myisam_hton);
 
3998
    table->file= get_new_handler(share, &table->mem_root,
 
3999
                                 share->db_type());
1049
4000
    if (group &&
1050
 
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1051
 
         param->group_length > table->cursor->getEngine()->max_key_length()))
1052
 
    {
1053
 
      using_unique_constraint= true;
1054
 
    }
 
4001
        (param->group_parts > table->file->max_key_parts() ||
 
4002
         param->group_length > table->file->max_key_length()))
 
4003
      using_unique_constraint=1;
1055
4004
  }
1056
4005
  else
1057
4006
  {
1058
 
    table->getMutableShare()->storage_engine= heap_engine;
1059
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
4007
    share->db_plugin= ha_lock_engine(0, heap_hton);
 
4008
    table->file= get_new_handler(share, &table->mem_root,
 
4009
                                 share->db_type());
1060
4010
  }
1061
 
  if (! table->cursor)
 
4011
  if (!table->file)
1062
4012
    goto err;
1063
4013
 
1064
4014
 
1065
 
  if (! using_unique_constraint)
 
4015
  if (!using_unique_constraint)
1066
4016
    reclength+= group_null_items;       // null flag is stored separately
1067
4017
 
1068
 
  table->getMutableShare()->blob_fields= blob_count;
 
4018
  share->blob_fields= blob_count;
1069
4019
  if (blob_count == 0)
1070
4020
  {
1071
4021
    /* We need to ensure that first byte is not 0 for the delete link */
1084
4034
  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)))
1085
4035
    use_packed_rows= 1;
1086
4036
 
1087
 
  table->getMutableShare()->setRecordLength(reclength);
 
4037
  share->reclength= reclength;
1088
4038
  {
1089
4039
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
1090
 
    table->getMutableShare()->rec_buff_length= alloc_length;
1091
 
    if (!(table->record[0]= (unsigned char*) table->alloc_root(alloc_length*2)))
1092
 
    {
 
4040
    share->rec_buff_length= alloc_length;
 
4041
    if (!(table->record[0]= (unsigned char*)
 
4042
                            alloc_root(&table->mem_root, alloc_length*3)))
1093
4043
      goto err;
1094
 
    }
1095
 
    table->record[1]= table->getInsertRecord()+alloc_length;
1096
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
4044
    table->record[1]= table->record[0]+alloc_length;
 
4045
    share->default_values= table->record[1]+alloc_length;
1097
4046
  }
1098
 
  copy_func[0]= 0;                              // End marker
 
4047
  copy_func[0]=0;                               // End marker
1099
4048
  param->func_count= copy_func - param->items_to_copy;
1100
4049
 
1101
 
  table->setup_tmp_table_column_bitmaps();
 
4050
  table->setup_tmp_table_column_bitmaps(bitmaps);
1102
4051
 
1103
4052
  recinfo=param->start_recinfo;
1104
 
  null_flags=(unsigned char*) table->getInsertRecord();
1105
 
  pos=table->getInsertRecord()+ null_pack_length;
 
4053
  null_flags=(unsigned char*) table->record[0];
 
4054
  pos=table->record[0]+ null_pack_length;
1106
4055
  if (null_pack_length)
1107
4056
  {
1108
4057
    memset(recinfo, 0, sizeof(*recinfo));
1111
4060
    recinfo++;
1112
4061
    memset(null_flags, 255, null_pack_length);  // Set null fields
1113
4062
 
1114
 
    table->null_flags= (unsigned char*) table->getInsertRecord();
1115
 
    table->getMutableShare()->null_fields= null_count+ hidden_null_count;
1116
 
    table->getMutableShare()->null_bytes= null_pack_length;
 
4063
    table->null_flags= (unsigned char*) table->record[0];
 
4064
    share->null_fields= null_count+ hidden_null_count;
 
4065
    share->null_bytes= null_pack_length;
1117
4066
  }
1118
4067
  null_count= (blob_count == 0) ? 1 : 0;
1119
4068
  hidden_field_count=param->hidden_field_count;
1120
 
  for (i= 0,reg_field= table->getFields(); i < field_count; i++,reg_field++,recinfo++)
 
4069
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
1121
4070
  {
1122
4071
    Field *field= *reg_field;
1123
4072
    uint32_t length;
1131
4080
          We have to reserve one byte here for NULL bits,
1132
4081
          as this is updated by 'end_update()'
1133
4082
        */
1134
 
        *pos++= '\0';                           // Null is stored here
1135
 
        recinfo->length= 1;
 
4083
        *pos++=0;                               // Null is stored here
 
4084
        recinfo->length=1;
1136
4085
        recinfo->type=FIELD_NORMAL;
1137
4086
        recinfo++;
1138
4087
        memset(recinfo, 0, sizeof(*recinfo));
1161
4110
         inherit the default value that is defined for the field referred
1162
4111
         by the Item_field object from which 'field' has been created.
1163
4112
      */
1164
 
      ptrdiff_t diff;
 
4113
      my_ptrdiff_t diff;
1165
4114
      Field *orig_field= default_field[i];
1166
4115
      /* Get the value from default_values */
1167
 
      diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
 
4116
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
 
4117
                            orig_field->table->record[0]);
1168
4118
      orig_field->move_field_offset(diff);      // Points now at default_values
1169
4119
      if (orig_field->is_real_null())
1170
4120
        field->set_null();
1173
4123
        field->set_notnull();
1174
4124
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
1175
4125
      }
1176
 
      orig_field->move_field_offset(-diff);     // Back to getInsertRecord()
 
4126
      orig_field->move_field_offset(-diff);     // Back to record[0]
1177
4127
    }
1178
4128
 
1179
4129
    if (from_field[i])
1192
4142
      recinfo->type=FIELD_NORMAL;
1193
4143
    if (!--hidden_field_count)
1194
4144
      null_count=(null_count+7) & ~7;           // move to next byte
 
4145
 
 
4146
    // fix table name in field entry
 
4147
    field->table_name= &table->alias;
1195
4148
  }
1196
4149
 
1197
4150
  param->copy_field_end=copy;
1198
4151
  param->recinfo=recinfo;
1199
 
  table->storeRecordAsDefault();        // Make empty default record
 
4152
  store_record(table,s->default_values);        // Make empty default record
1200
4153
 
1201
4154
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
1202
 
  {
1203
 
    max_rows= ~(uint64_t) 0;
1204
 
  }
 
4155
    share->max_rows= ~(ha_rows) 0;
1205
4156
  else
1206
 
  {
1207
 
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
1208
 
                           min(session->variables.tmp_table_size,
1209
 
                               session->variables.max_heap_table_size) :
1210
 
                           session->variables.tmp_table_size) /
1211
 
                          table->getMutableShare()->getRecordLength());
1212
 
  }
1213
 
 
1214
 
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
 
4157
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
 
4158
                                 cmin(session->variables.tmp_table_size,
 
4159
                                     session->variables.max_heap_table_size) :
 
4160
                                 session->variables.tmp_table_size) /
 
4161
                                 share->reclength);
 
4162
  set_if_bigger(share->max_rows,1);             // For dummy start options
1215
4163
  /*
1216
4164
    Push the LIMIT clause to the temporary table creation, so that we
1217
4165
    materialize only up to 'rows_limit' records instead of all result records.
1218
4166
  */
1219
 
  set_if_smaller(max_rows, rows_limit);
1220
 
 
1221
 
  table->getMutableShare()->setMaxRows(max_rows);
1222
 
 
 
4167
  set_if_smaller(share->max_rows, rows_limit);
1223
4168
  param->end_write_records= rows_limit;
1224
4169
 
1225
4170
  keyinfo= param->keyinfo;
1228
4173
  {
1229
4174
    table->group=group;                         /* Table is grouped by key */
1230
4175
    param->group_buff=group_buff;
1231
 
    table->getMutableShare()->keys=1;
1232
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
4176
    share->keys=1;
 
4177
    share->uniques= test(using_unique_constraint);
1233
4178
    table->key_info=keyinfo;
1234
4179
    keyinfo->key_part=key_part_info;
1235
4180
    keyinfo->flags=HA_NOSAME;
1236
4181
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
1237
 
    keyinfo->key_length= 0;
1238
 
    keyinfo->rec_per_key= 0;
 
4182
    keyinfo->key_length=0;
 
4183
    keyinfo->rec_per_key=0;
1239
4184
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1240
4185
    keyinfo->name= (char*) "group_key";
1241
 
    Order *cur_group= group;
 
4186
    order_st *cur_group= group;
1242
4187
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1243
4188
    {
1244
4189
      Field *field=(*cur_group->item)->get_tmp_table_field();
1245
4190
      bool maybe_null=(*cur_group->item)->maybe_null;
1246
 
      key_part_info->null_bit= 0;
 
4191
      key_part_info->null_bit=0;
1247
4192
      key_part_info->field=  field;
1248
 
      key_part_info->offset= field->offset(table->getInsertRecord());
 
4193
      key_part_info->offset= field->offset(table->record[0]);
1249
4194
      key_part_info->length= (uint16_t) field->key_length();
1250
4195
      key_part_info->type=   (uint8_t) field->key_type();
1251
 
      key_part_info->key_type= 
 
4196
      key_part_info->key_type =
1252
4197
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1253
4198
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1254
4199
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1255
 
        0 : 1;
 
4200
        0 : FIELDFLAG_BINARY;
1256
4201
      if (!using_unique_constraint)
1257
4202
      {
1258
4203
        cur_group->buff=(char*) group_buff;
1261
4206
                                                     test(maybe_null),
1262
4207
                                                     field->null_ptr,
1263
4208
                                                     field->null_bit)))
1264
 
          goto err;
 
4209
          goto err; /* purecov: inspected */
1265
4210
        if (maybe_null)
1266
4211
        {
1267
4212
          /*
1272
4217
          */
1273
4218
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
1274
4219
          key_part_info->null_bit=field->null_bit;
1275
 
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
1276
 
                                              (unsigned char*) table->getInsertRecord());
 
4220
          key_part_info->null_offset= (uint) (field->null_ptr -
 
4221
                                              (unsigned char*) table->record[0]);
1277
4222
          cur_group->buff++;                        // Pointer to field data
1278
4223
          group_buff++;                         // Skipp null flag
1279
4224
        }
1300
4245
        indexes on blobs with arbitrary length. Such indexes cannot be
1301
4246
        used for lookups.
1302
4247
      */
1303
 
      table->getMutableShare()->uniques= 1;
 
4248
      share->uniques= 1;
1304
4249
    }
1305
4250
    null_pack_length-=hidden_null_pack_length;
1306
4251
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1307
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
4252
                         (share->uniques ? test(null_pack_length) : 0));
1308
4253
    table->distinct= 1;
1309
 
    table->getMutableShare()->keys= 1;
1310
 
    if (!(key_part_info= (KeyPartInfo*)
1311
 
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
 
4254
    share->keys= 1;
 
4255
    if (!(key_part_info= (KEY_PART_INFO*)
 
4256
          alloc_root(&table->mem_root,
 
4257
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
1312
4258
      goto err;
1313
 
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KeyPartInfo));
 
4259
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
1314
4260
    table->key_info=keyinfo;
1315
4261
    keyinfo->key_part=key_part_info;
1316
4262
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
1317
4263
    keyinfo->key_length=(uint16_t) reclength;
1318
4264
    keyinfo->name= (char*) "distinct_key";
1319
4265
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1320
 
    keyinfo->rec_per_key= 0;
 
4266
    keyinfo->rec_per_key=0;
1321
4267
 
1322
4268
    /*
1323
4269
      Create an extra field to hold NULL bits so that unique indexes on
1324
4270
      blobs can distinguish NULL from 0. This extra field is not needed
1325
4271
      when we do not use UNIQUE indexes for blobs.
1326
4272
    */
1327
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
4273
    if (null_pack_length && share->uniques)
1328
4274
    {
1329
 
      key_part_info->null_bit= 0;
 
4275
      key_part_info->null_bit=0;
1330
4276
      key_part_info->offset=hidden_null_pack_length;
1331
4277
      key_part_info->length=null_pack_length;
1332
 
      table->setVariableWidth();
1333
 
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
 
4278
      key_part_info->field= new Field_varstring(table->record[0],
1334
4279
                                                (uint32_t) key_part_info->length,
1335
4280
                                                0,
1336
4281
                                                (unsigned char*) 0,
1337
 
                                                (uint32_t) 0,
 
4282
                                                (uint) 0,
 
4283
                                                Field::NONE,
1338
4284
                                                NULL,
 
4285
                                                table->s,
1339
4286
                                                &my_charset_bin);
1340
4287
      if (!key_part_info->field)
1341
4288
        goto err;
1342
4289
      key_part_info->field->init(table);
1343
 
      key_part_info->key_type= 1; /* binary comparison */
 
4290
      key_part_info->key_type=FIELDFLAG_BINARY;
1344
4291
      key_part_info->type=    HA_KEYTYPE_BINARY;
1345
4292
      key_part_info++;
1346
4293
    }
1347
4294
    /* Create a distinct key over the columns we are going to return */
1348
 
    for (i=param->hidden_field_count, reg_field=table->getFields() + i ;
 
4295
    for (i=param->hidden_field_count, reg_field=table->field + i ;
1349
4296
         i < field_count;
1350
4297
         i++, reg_field++, key_part_info++)
1351
4298
    {
1352
 
      key_part_info->null_bit= 0;
 
4299
      key_part_info->null_bit=0;
1353
4300
      key_part_info->field=    *reg_field;
1354
 
      key_part_info->offset=   (*reg_field)->offset(table->getInsertRecord());
 
4301
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
1355
4302
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
1356
 
      /* @todo The below method of computing the key format length of the
1357
 
        key part is a copy/paste from optimizer/range.cc, and table.cc.
 
4303
      /* TODO:
 
4304
        The below method of computing the key format length of the
 
4305
        key part is a copy/paste from opt_range.cc, and table.cc.
1358
4306
        This should be factored out, e.g. as a method of Field.
1359
4307
        In addition it is not clear if any of the Field::*_length
1360
4308
        methods is supposed to compute the same length. If so, it
1373
4321
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1374
4322
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1375
4323
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1376
 
        0 : 1;
 
4324
        0 : FIELDFLAG_BINARY;
1377
4325
    }
1378
4326
  }
1379
4327
 
1380
4328
  if (session->is_fatal_error)                          // If end of memory
1381
 
    goto err;
1382
 
  table->getMutableShare()->db_record_offset= 1;
1383
 
  if (table->getShare()->db_type() == myisam_engine)
 
4329
    goto err;                                    /* purecov: inspected */
 
4330
  share->db_record_offset= 1;
 
4331
  if (share->db_type() == myisam_hton)
1384
4332
  {
1385
4333
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1386
4334
                                       &param->recinfo, select_options))
1387
4335
      goto err;
1388
4336
  }
1389
 
  assert(table->in_use);
1390
4337
  if (table->open_tmp_table())
1391
4338
    goto err;
1392
4339
 
1396
4343
 
1397
4344
err:
1398
4345
  session->mem_root= mem_root_save;
1399
 
  table= NULL;
1400
 
 
1401
 
  return NULL;
 
4346
  table->free_tmp_table(session);                    /* purecov: inspected */
 
4347
  if (temp_pool_slot != MY_BIT_NONE)
 
4348
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
4349
  return(NULL);                         /* purecov: inspected */
1402
4350
}
1403
4351
 
1404
4352
/****************************************************************************/
1405
4353
 
1406
 
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1407
 
                               boost::dynamic_bitset<>& write_set_arg)
1408
 
{
1409
 
  read_set= &read_set_arg;
1410
 
  write_set= &write_set_arg;
1411
 
}
1412
 
 
1413
 
 
1414
 
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
1415
 
{
1416
 
  const boost::dynamic_bitset<> old= in_map;
1417
 
  in_map= getShare()->all_set;
 
4354
/**
 
4355
  Create a reduced Table object with properly set up Field list from a
 
4356
  list of field definitions.
 
4357
 
 
4358
    The created table doesn't have a table handler associated with
 
4359
    it, has no keys, no group/distinct, no copy_funcs array.
 
4360
    The sole purpose of this Table object is to use the power of Field
 
4361
    class to read/write data to/from table->record[0]. Then one can store
 
4362
    the record in any container (RB tree, hash, etc).
 
4363
    The table is created in Session mem_root, so are the table's fields.
 
4364
    Consequently, if you don't BLOB fields, you don't need to free it.
 
4365
 
 
4366
  @param session         connection handle
 
4367
  @param field_list  list of column definitions
 
4368
 
 
4369
  @return
 
4370
    0 if out of memory, Table object in case of success
 
4371
*/
 
4372
 
 
4373
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
 
4374
{
 
4375
  uint32_t field_count= field_list.elements;
 
4376
  uint32_t blob_count= 0;
 
4377
  Field **field;
 
4378
  Create_field *cdef;                           /* column definition */
 
4379
  uint32_t record_length= 0;
 
4380
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
4381
  uint32_t null_pack_length;              /* NULL representation array length */
 
4382
  uint32_t *blob_field;
 
4383
  unsigned char *bitmaps;
 
4384
  Table *table;
 
4385
  TABLE_SHARE *share;
 
4386
 
 
4387
  if (!multi_alloc_root(session->mem_root,
 
4388
                        &table, sizeof(*table),
 
4389
                        &share, sizeof(*share),
 
4390
                        &field, (field_count + 1) * sizeof(Field*),
 
4391
                        &blob_field, (field_count+1) *sizeof(uint),
 
4392
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
4393
                        NULL))
 
4394
    return 0;
 
4395
 
 
4396
  memset(table, 0, sizeof(*table));
 
4397
  memset(share, 0, sizeof(*share));
 
4398
  table->field= field;
 
4399
  table->s= share;
 
4400
  share->blob_field= blob_field;
 
4401
  share->fields= field_count;
 
4402
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
4403
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
4404
 
 
4405
  /* Create all fields and calculate the total length of record */
 
4406
  List_iterator_fast<Create_field> it(field_list);
 
4407
  while ((cdef= it++))
 
4408
  {
 
4409
    *field= make_field(share, 0, cdef->length,
 
4410
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
4411
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
4412
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
 
4413
                       cdef->unireg_check,
 
4414
                       cdef->interval, cdef->field_name);
 
4415
    if (!*field)
 
4416
      goto error;
 
4417
    (*field)->init(table);
 
4418
    record_length+= (*field)->pack_length();
 
4419
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
4420
      null_count++;
 
4421
 
 
4422
    if ((*field)->flags & BLOB_FLAG)
 
4423
      share->blob_field[blob_count++]= (uint) (field - table->field);
 
4424
 
 
4425
    field++;
 
4426
  }
 
4427
  *field= NULL;                             /* mark the end of the list */
 
4428
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
4429
  share->blob_fields= blob_count;
 
4430
 
 
4431
  null_pack_length= (null_count + 7)/8;
 
4432
  share->reclength= record_length + null_pack_length;
 
4433
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
4434
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
 
4435
  if (!table->record[0])
 
4436
    goto error;
 
4437
 
 
4438
  if (null_pack_length)
 
4439
  {
 
4440
    table->null_flags= (unsigned char*) table->record[0];
 
4441
    share->null_fields= null_count;
 
4442
    share->null_bytes= null_pack_length;
 
4443
  }
 
4444
 
 
4445
  table->in_use= session;           /* field->reset() may access table->in_use */
 
4446
  {
 
4447
    /* Set up field pointers */
 
4448
    unsigned char *null_pos= table->record[0];
 
4449
    unsigned char *field_pos= null_pos + share->null_bytes;
 
4450
    uint32_t null_bit= 1;
 
4451
 
 
4452
    for (field= table->field; *field; ++field)
 
4453
    {
 
4454
      Field *cur_field= *field;
 
4455
      if ((cur_field->flags & NOT_NULL_FLAG))
 
4456
        cur_field->move_field(field_pos);
 
4457
      else
 
4458
      {
 
4459
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
4460
        null_bit<<= 1;
 
4461
        if (null_bit == (1 << 8))
 
4462
        {
 
4463
          ++null_pos;
 
4464
          null_bit= 1;
 
4465
        }
 
4466
      }
 
4467
      cur_field->reset();
 
4468
 
 
4469
      field_pos+= cur_field->pack_length();
 
4470
    }
 
4471
  }
 
4472
  return table;
 
4473
error:
 
4474
  for (field= table->field; *field; ++field)
 
4475
    delete *field;                         /* just invokes field destructor */
 
4476
  return 0;
 
4477
}
 
4478
 
 
4479
 
 
4480
bool Table::open_tmp_table()
 
4481
{
 
4482
  int error;
 
4483
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
 
4484
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
4485
  {
 
4486
    file->print_error(error,MYF(0)); /* purecov: inspected */
 
4487
    db_stat=0;
 
4488
    return(1);
 
4489
  }
 
4490
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
4491
  return(0);
 
4492
}
 
4493
 
 
4494
 
 
4495
/*
 
4496
  Create MyISAM temporary table
 
4497
 
 
4498
  SYNOPSIS
 
4499
    create_myisam_tmp_table()
 
4500
      keyinfo         Description of the index (there is always one index)
 
4501
      start_recinfo   MyISAM's column descriptions
 
4502
      recinfo INOUT   End of MyISAM's column descriptions
 
4503
      options         Option bits
 
4504
 
 
4505
  DESCRIPTION
 
4506
    Create a MyISAM temporary table according to passed description. The is
 
4507
    assumed to have one unique index or constraint.
 
4508
 
 
4509
    The passed array or MI_COLUMNDEF structures must have this form:
 
4510
 
 
4511
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
4512
         when there are many nullable columns)
 
4513
      2. Table columns
 
4514
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
4515
 
 
4516
    This function may use the free element to create hash column for unique
 
4517
    constraint.
 
4518
 
 
4519
   RETURN
 
4520
     false - OK
 
4521
     true  - Error
 
4522
*/
 
4523
 
 
4524
bool Table::create_myisam_tmp_table(KEY *keyinfo,
 
4525
                                    MI_COLUMNDEF *start_recinfo,
 
4526
                                    MI_COLUMNDEF **recinfo,
 
4527
                                    uint64_t options)
 
4528
{
 
4529
  int error;
 
4530
  MI_KEYDEF keydef;
 
4531
  MI_UNIQUEDEF uniquedef;
 
4532
  TABLE_SHARE *share= s;
 
4533
 
 
4534
  if (share->keys)
 
4535
  {                                             // Get keys for ni_create
 
4536
    bool using_unique_constraint=0;
 
4537
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
 
4538
                                            sizeof(*seg) * keyinfo->key_parts);
 
4539
    if (!seg)
 
4540
      goto err;
 
4541
 
 
4542
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
4543
    if (keyinfo->key_length >= file->max_key_length() ||
 
4544
        keyinfo->key_parts > file->max_key_parts() ||
 
4545
        share->uniques)
 
4546
    {
 
4547
      /* Can't create a key; Make a unique constraint instead of a key */
 
4548
      share->keys=    0;
 
4549
      share->uniques= 1;
 
4550
      using_unique_constraint=1;
 
4551
      memset(&uniquedef, 0, sizeof(uniquedef));
 
4552
      uniquedef.keysegs=keyinfo->key_parts;
 
4553
      uniquedef.seg=seg;
 
4554
      uniquedef.null_are_equal=1;
 
4555
 
 
4556
      /* Create extra column for hash value */
 
4557
      memset(*recinfo, 0, sizeof(**recinfo));
 
4558
      (*recinfo)->type= FIELD_CHECK;
 
4559
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
4560
      (*recinfo)++;
 
4561
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
 
4562
    }
 
4563
    else
 
4564
    {
 
4565
      /* Create an unique key */
 
4566
      memset(&keydef, 0, sizeof(keydef));
 
4567
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
4568
      keydef.keysegs=  keyinfo->key_parts;
 
4569
      keydef.seg= seg;
 
4570
    }
 
4571
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
 
4572
    {
 
4573
      Field *field=keyinfo->key_part[i].field;
 
4574
      seg->flag=     0;
 
4575
      seg->language= field->charset()->number;
 
4576
      seg->length=   keyinfo->key_part[i].length;
 
4577
      seg->start=    keyinfo->key_part[i].offset;
 
4578
      if (field->flags & BLOB_FLAG)
 
4579
      {
 
4580
        seg->type=
 
4581
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
 
4582
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
4583
        seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
 
4584
        seg->flag= HA_BLOB_PART;
 
4585
        seg->length=0;                  // Whole blob in unique constraint
 
4586
      }
 
4587
      else
 
4588
      {
 
4589
        seg->type= keyinfo->key_part[i].type;
 
4590
      }
 
4591
      if (!(field->flags & NOT_NULL_FLAG))
 
4592
      {
 
4593
        seg->null_bit= field->null_bit;
 
4594
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) record[0]);
 
4595
        /*
 
4596
          We are using a GROUP BY on something that contains NULL
 
4597
          In this case we have to tell MyISAM that two NULL should
 
4598
          on INSERT be regarded at the same value
 
4599
        */
 
4600
        if (!using_unique_constraint)
 
4601
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
4602
      }
 
4603
    }
 
4604
  }
 
4605
  MI_CREATE_INFO create_info;
 
4606
  memset(&create_info, 0, sizeof(create_info));
 
4607
 
 
4608
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
4609
      OPTION_BIG_TABLES)
 
4610
    create_info.data_file_length= ~(uint64_t) 0;
 
4611
 
 
4612
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
 
4613
                       (uint) (*recinfo-start_recinfo),
 
4614
                       start_recinfo,
 
4615
                       share->uniques, &uniquedef,
 
4616
                       &create_info,
 
4617
                       HA_CREATE_TMP_TABLE)))
 
4618
  {
 
4619
    file->print_error(error,MYF(0));    /* purecov: inspected */
 
4620
    db_stat=0;
 
4621
    goto err;
 
4622
  }
 
4623
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
 
4624
  share->db_record_offset= 1;
 
4625
  return false;
 
4626
 err:
 
4627
  return true;
 
4628
}
 
4629
 
 
4630
 
 
4631
void Table::free_tmp_table(Session *session)
 
4632
{
 
4633
  MEM_ROOT own_root= mem_root;
 
4634
  const char *save_proc_info;
 
4635
 
 
4636
  save_proc_info=session->get_proc_info();
 
4637
  session->set_proc_info("removing tmp table");
 
4638
 
 
4639
  if (file)
 
4640
  {
 
4641
    if (db_stat)
 
4642
      file->ha_drop_table(s->table_name.str);
 
4643
    else
 
4644
      file->ha_delete_table(s->table_name.str);
 
4645
    delete file;
 
4646
  }
 
4647
 
 
4648
  /* free blobs */
 
4649
  for (Field **ptr= field ; *ptr ; ptr++)
 
4650
    (*ptr)->free();
 
4651
  free_io_cache(this);
 
4652
 
 
4653
  if (temp_pool_slot != MY_BIT_NONE)
 
4654
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
4655
 
 
4656
  plugin_unlock(0, s->db_plugin);
 
4657
 
 
4658
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
 
4659
  session->set_proc_info(save_proc_info);
 
4660
 
 
4661
  return;
 
4662
}
 
4663
 
 
4664
/**
 
4665
  If a HEAP table gets full, create a MyISAM table and copy all rows
 
4666
  to this.
 
4667
*/
 
4668
 
 
4669
bool create_myisam_from_heap(Session *session, Table *table,
 
4670
                             MI_COLUMNDEF *start_recinfo,
 
4671
                             MI_COLUMNDEF **recinfo,
 
4672
                             int error, bool ignore_last_dupp_key_error)
 
4673
{
 
4674
  Table new_table;
 
4675
  TABLE_SHARE share;
 
4676
  const char *save_proc_info;
 
4677
  int write_err;
 
4678
 
 
4679
  if (table->s->db_type() != heap_hton ||
 
4680
      error != HA_ERR_RECORD_FILE_FULL)
 
4681
  {
 
4682
    table->file->print_error(error,MYF(0));
 
4683
    return(1);
 
4684
  }
 
4685
  new_table= *table;
 
4686
  share= *table->s;
 
4687
  new_table.s= &share;
 
4688
  new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
 
4689
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
4690
                                        new_table.s->db_type())))
 
4691
    return(1);                          // End of memory
 
4692
 
 
4693
  save_proc_info=session->get_proc_info();
 
4694
  session->set_proc_info("converting HEAP to MyISAM");
 
4695
 
 
4696
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
 
4697
                                        recinfo, session->lex->select_lex.options |
 
4698
                                        session->options))
 
4699
    goto err2;
 
4700
  if (new_table.open_tmp_table())
 
4701
    goto err1;
 
4702
  if (table->file->indexes_are_disabled())
 
4703
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
4704
  table->file->ha_index_or_rnd_end();
 
4705
  table->file->ha_rnd_init(1);
 
4706
  if (table->no_rows)
 
4707
  {
 
4708
    new_table.file->extra(HA_EXTRA_NO_ROWS);
 
4709
    new_table.no_rows=1;
 
4710
  }
 
4711
 
 
4712
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
 
4713
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
 
4714
 
 
4715
  /*
 
4716
    copy all old rows from heap table to MyISAM table
 
4717
    This is the only code that uses record[1] to read/write but this
 
4718
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
 
4719
  */
 
4720
  while (!table->file->rnd_next(new_table.record[1]))
 
4721
  {
 
4722
    write_err= new_table.file->ha_write_row(new_table.record[1]);
 
4723
    if (write_err)
 
4724
      goto err;
 
4725
  }
 
4726
  /* copy row that filled HEAP table */
 
4727
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
 
4728
  {
 
4729
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
4730
        !ignore_last_dupp_key_error)
 
4731
      goto err;
 
4732
  }
 
4733
 
 
4734
  /* remove heap table and change to use myisam table */
 
4735
  (void) table->file->ha_rnd_end();
 
4736
  (void) table->file->close();                  // This deletes the table !
 
4737
  delete table->file;
 
4738
  table->file=0;
 
4739
  plugin_unlock(0, table->s->db_plugin);
 
4740
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
 
4741
  new_table.s= table->s;                       // Keep old share
 
4742
  *table= new_table;
 
4743
  *table->s= share;
 
4744
 
 
4745
  table->file->change_table_ptr(table, table->s);
 
4746
  table->use_all_columns();
 
4747
  if (save_proc_info)
 
4748
  {
 
4749
    const char *new_proc_info=
 
4750
      (!strcmp(save_proc_info,"Copying to tmp table") ?
 
4751
      "Copying to tmp table on disk" : save_proc_info);
 
4752
    session->set_proc_info(new_proc_info);
 
4753
  }
 
4754
  return(0);
 
4755
 
 
4756
 err:
 
4757
  table->file->print_error(write_err, MYF(0));
 
4758
  (void) table->file->ha_rnd_end();
 
4759
  (void) new_table.file->close();
 
4760
 err1:
 
4761
  new_table.file->ha_delete_table(new_table.s->table_name.str);
 
4762
 err2:
 
4763
  delete new_table.file;
 
4764
  session->set_proc_info(save_proc_info);
 
4765
  table->mem_root= new_table.mem_root;
 
4766
  return(1);
 
4767
}
 
4768
 
 
4769
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
 
4770
{
 
4771
  my_bitmap_map *old= bitmap->bitmap;
 
4772
  bitmap->bitmap= s->all_set.bitmap;
1418
4773
  return old;
1419
4774
}
1420
4775
 
1421
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
4776
void Table::restore_column_map(my_bitmap_map *old)
1422
4777
{
1423
 
  for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
1424
 
  {
1425
 
    if (old.test(i))
1426
 
    {
1427
 
      read_set->set(i);
1428
 
    }
1429
 
    else
1430
 
    {
1431
 
      read_set->reset(i);
1432
 
    }
1433
 
  }
 
4778
  read_set->bitmap= old;
1434
4779
}
1435
4780
 
1436
4781
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1437
4782
{
1438
4783
  uint32_t min_length= UINT32_MAX;
1439
4784
  uint32_t best= MAX_KEY;
1440
 
  if (usable_keys->any())
 
4785
  if (!usable_keys->is_clear_all())
1441
4786
  {
1442
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
4787
    for (uint32_t nr=0; nr < s->keys ; nr++)
1443
4788
    {
1444
 
      if (usable_keys->test(nr))
 
4789
      if (usable_keys->is_set(nr))
1445
4790
      {
1446
4791
        if (key_info[nr].key_length < min_length)
1447
4792
        {
1466
4811
{
1467
4812
  for (; *ptr ; ptr++)
1468
4813
  {
1469
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
4814
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1470
4815
      return true;
1471
4816
  }
1472
4817
  return false;
1473
4818
}
1474
4819
 
1475
 
/**
1476
 
   True if the table's input and output record buffers are comparable using
1477
 
   compare_records(TABLE*).
1478
 
 */
1479
 
bool Table::records_are_comparable()
1480
 
{
1481
 
  return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
1482
 
          write_set->is_subset_of(*read_set));
1483
 
}
1484
 
 
1485
 
/**
1486
 
   Compares the input and outbut record buffers of the table to see if a row
1487
 
   has changed. The algorithm iterates over updated columns and if they are
1488
 
   nullable compares NULL bits in the buffer before comparing actual
1489
 
   data. Special care must be taken to compare only the relevant NULL bits and
1490
 
   mask out all others as they may be undefined. The storage engine will not
1491
 
   and should not touch them.
1492
 
 
1493
 
   @param table The table to evaluate.
1494
 
 
1495
 
   @return true if row has changed.
1496
 
   @return false otherwise.
1497
 
*/
1498
 
bool Table::compare_records()
1499
 
{
1500
 
  if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
1501
 
  {
1502
 
    /*
1503
 
      Storage engine may not have read all columns of the record.  Fields
1504
 
      (including NULL bits) not in the write_set may not have been read and
1505
 
      can therefore not be compared.
1506
 
    */
1507
 
    for (Field **ptr= this->field ; *ptr != NULL; ptr++)
1508
 
    {
1509
 
      Field *f= *ptr;
1510
 
      if (write_set->test(f->position()))
1511
 
      {
1512
 
        if (f->real_maybe_null())
1513
 
        {
1514
 
          unsigned char null_byte_index= f->null_ptr - record[0];
1515
 
 
1516
 
          if (((record[0][null_byte_index]) & f->null_bit) !=
1517
 
              ((record[1][null_byte_index]) & f->null_bit))
1518
 
            return true;
1519
 
        }
1520
 
        if (f->cmp_binary_offset(getShare()->rec_buff_length))
1521
 
          return true;
1522
 
      }
1523
 
    }
1524
 
    return false;
1525
 
  }
1526
 
 
1527
 
  /*
1528
 
    The storage engine has read all columns, so it's safe to compare all bits
1529
 
    including those not in the write_set. This is cheaper than the
1530
 
    field-by-field comparison done above.
1531
 
  */
1532
 
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
1533
 
    // Fixed-size record: do bitwise comparison of the records
1534
 
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
1535
 
 
 
4820
/* Return false if row hasn't changed */
 
4821
 
 
4822
bool Table::compare_record()
 
4823
{
 
4824
  if (s->blob_fields + s->varchar_fields == 0)
 
4825
    return cmp_record(this, record[1]);
1536
4826
  /* Compare null bits */
1537
 
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
1538
 
    return true; /* Diff in NULL value */
1539
 
 
 
4827
  if (memcmp(null_flags,
 
4828
             null_flags + s->rec_buff_length,
 
4829
             s->null_bytes))
 
4830
    return true;                                // Diff in NULL value
1540
4831
  /* Compare updated fields */
1541
4832
  for (Field **ptr= field ; *ptr ; ptr++)
1542
4833
  {
1543
 
    if (isWriteSet((*ptr)->position()) &&
1544
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
4834
    if (bitmap_is_set(write_set, (*ptr)->field_index) &&
 
4835
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1545
4836
      return true;
1546
4837
  }
1547
4838
  return false;
1548
4839
}
1549
4840
 
1550
 
/*
1551
 
 * Store a record from previous record into next
1552
 
 *
1553
 
 */
1554
 
void Table::storeRecord()
1555
 
{
1556
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
1557
 
}
1558
 
 
1559
 
/*
1560
 
 * Store a record as an insert
1561
 
 *
1562
 
 */
1563
 
void Table::storeRecordAsInsert()
1564
 
{
1565
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1566
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
1567
 
}
1568
 
 
1569
 
/*
1570
 
 * Store a record with default values
1571
 
 *
1572
 
 */
1573
 
void Table::storeRecordAsDefault()
1574
 
{
1575
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
1576
 
}
1577
 
 
1578
 
/*
1579
 
 * Restore a record from previous record into next
1580
 
 *
1581
 
 */
1582
 
void Table::restoreRecord()
1583
 
{
1584
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
1585
 
}
1586
 
 
1587
 
/*
1588
 
 * Restore a record with default values
1589
 
 *
1590
 
 */
1591
 
void Table::restoreRecordAsDefault()
1592
 
{
1593
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
1594
 
}
1595
 
 
1596
 
/*
1597
 
 * Empty a record
1598
 
 *
1599
 
 */
1600
 
void Table::emptyRecord()
1601
 
{
1602
 
  restoreRecordAsDefault();
1603
 
  memset(null_flags, 255, getShare()->null_bytes);
1604
 
}
1605
 
 
1606
 
Table::Table() : 
1607
 
  field(NULL),
1608
 
  cursor(NULL),
1609
 
  next(NULL),
1610
 
  prev(NULL),
1611
 
  read_set(NULL),
1612
 
  write_set(NULL),
1613
 
  tablenr(0),
1614
 
  db_stat(0),
1615
 
  def_read_set(),
1616
 
  def_write_set(),
1617
 
  tmp_set(),
1618
 
  in_use(NULL),
1619
 
  key_info(NULL),
1620
 
  next_number_field(NULL),
1621
 
  found_next_number_field(NULL),
1622
 
  timestamp_field(NULL),
1623
 
  pos_in_table_list(NULL),
1624
 
  group(NULL),
1625
 
  null_flags(NULL),
1626
 
  lock_position(0),
1627
 
  lock_data_start(0),
1628
 
  lock_count(0),
1629
 
  used_fields(0),
1630
 
  status(0),
1631
 
  derived_select_number(0),
1632
 
  current_lock(F_UNLCK),
1633
 
  copy_blobs(false),
1634
 
  maybe_null(false),
1635
 
  null_row(false),
1636
 
  force_index(false),
1637
 
  distinct(false),
1638
 
  const_table(false),
1639
 
  no_rows(false),
1640
 
  key_read(false),
1641
 
  no_keyread(false),
1642
 
  open_placeholder(false),
1643
 
  locked_by_name(false),
1644
 
  no_cache(false),
1645
 
  auto_increment_field_not_null(false),
1646
 
  alias_name_used(false),
1647
 
  query_id(0),
1648
 
  quick_condition_rows(0),
1649
 
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1650
 
  map(0)
1651
 
{
1652
 
  record[0]= (unsigned char *) 0;
1653
 
  record[1]= (unsigned char *) 0;
1654
 
 
1655
 
  reginfo.reset();
1656
 
  covering_keys.reset();
1657
 
  quick_keys.reset();
1658
 
  merge_keys.reset();
1659
 
 
1660
 
  keys_in_use_for_query.reset();
1661
 
  keys_in_use_for_group_by.reset();
1662
 
  keys_in_use_for_order_by.reset();
1663
 
 
1664
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
1665
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
1666
 
 
1667
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
1668
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1669
 
}
 
4841
 
 
4842
 
 
4843
 
1670
4844
 
1671
4845
/*****************************************************************************
1672
4846
  The different ways to read a record
1673
4847
  Returns -1 if row was not found, 0 if row was found and 1 on errors
1674
4848
*****************************************************************************/
1675
4849
 
1676
 
/** Help function when we get some an error from the table Cursor. */
 
4850
/** Help function when we get some an error from the table handler. */
1677
4851
 
1678
4852
int Table::report_error(int error)
1679
4853
{
1688
4862
  */
1689
4863
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1690
4864
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
1691
 
                  error, getShare()->getPath());
1692
 
  print_error(error, MYF(0));
 
4865
                    error, s->path.str);
 
4866
  file->print_error(error,MYF(0));
1693
4867
 
1694
4868
  return 1;
1695
4869
}
1696
4870
 
1697
4871
 
1698
 
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
1699
 
{
1700
 
  used_fields= 0;
1701
 
  const_table= 0;
1702
 
  null_row= 0;
1703
 
  status= STATUS_NO_RECORD;
1704
 
  maybe_null= table_list->outer_join;
1705
 
  TableList *embedding= table_list->getEmbedding();
1706
 
  while (!maybe_null && embedding)
1707
 
  {
1708
 
    maybe_null= embedding->outer_join;
1709
 
    embedding= embedding->getEmbedding();
1710
 
  }
1711
 
  tablenr= table_number;
1712
 
  map= (table_map) 1 << table_number;
1713
 
  force_index= table_list->force_index;
1714
 
  covering_keys= getShare()->keys_for_keyread;
1715
 
  merge_keys.reset();
1716
 
}
1717
 
 
1718
 
 
1719
 
bool Table::fill_item_list(List<Item> *item_list) const
1720
 
{
1721
 
  /*
1722
 
    All Item_field's created using a direct pointer to a field
1723
 
    are fixed in Item_field constructor.
1724
 
  */
1725
 
  for (Field **ptr= field; *ptr; ptr++)
1726
 
  {
1727
 
    Item_field *item= new Item_field(*ptr);
1728
 
    if (!item || item_list->push_back(item))
1729
 
      return true;
1730
 
  }
1731
 
  return false;
1732
 
}
1733
 
 
1734
 
 
1735
 
void Table::filesort_free_buffers(bool full)
1736
 
{
1737
 
  if (sort.record_pointers)
1738
 
  {
1739
 
    free((unsigned char*) sort.record_pointers);
1740
 
    sort.record_pointers=0;
1741
 
  }
1742
 
  if (full)
1743
 
  {
1744
 
    if (sort.sort_keys )
1745
 
    {
1746
 
      if ((unsigned char*) sort.sort_keys)
1747
 
        free((unsigned char*) sort.sort_keys);
1748
 
      sort.sort_keys= 0;
1749
 
    }
1750
 
    if (sort.buffpek)
1751
 
    {
1752
 
      if ((unsigned char*) sort.buffpek)
1753
 
        free((unsigned char*) sort.buffpek);
1754
 
      sort.buffpek= 0;
1755
 
      sort.buffpek_len= 0;
1756
 
    }
1757
 
  }
1758
 
 
1759
 
  if (sort.addon_buf)
1760
 
  {
1761
 
    free((char *) sort.addon_buf);
1762
 
    free((char *) sort.addon_field);
1763
 
    sort.addon_buf=0;
1764
 
    sort.addon_field=0;
1765
 
  }
1766
 
}
1767
 
 
1768
 
} /* namespace drizzled */
 
4872
/*
 
4873
  Calculate data for each virtual field marked for write in the
 
4874
  corresponding column map.
 
4875
 
 
4876
  SYNOPSIS
 
4877
    update_virtual_fields_marked_for_write()
 
4878
    table                  The Table object
 
4879
    ignore_stored          Indication whether physically stored virtual
 
4880
                           fields do not need updating.
 
4881
                           This value is false when during INSERT and UPDATE
 
4882
                           and true in all other cases.
 
4883
 
 
4884
  RETURN
 
4885
    0  - Success
 
4886
    >0 - Error occurred during the generation/calculation of a virtual field value
 
4887
 
 
4888
*/
 
4889
 
 
4890
int update_virtual_fields_marked_for_write(Table *table,
 
4891
                                           bool ignore_stored)
 
4892
{
 
4893
  Field **vfield_ptr, *vfield;
 
4894
  int error= 0;
 
4895
  if ((not table) or (not table->vfield))
 
4896
    return(0);
 
4897
 
 
4898
  /* Iterate over virtual fields in the table */
 
4899
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
 
4900
  {
 
4901
    vfield= (*vfield_ptr);
 
4902
    assert(vfield->vcol_info && vfield->vcol_info->expr_item);
 
4903
    /*
 
4904
      Only update those fields that are marked in the write_set bitmap
 
4905
      and not _already_ physically stored in the database.
 
4906
    */
 
4907
    if (bitmap_is_set(table->write_set, vfield->field_index) &&
 
4908
        (not (ignore_stored && vfield->is_stored))
 
4909
       )
 
4910
    {
 
4911
      /* Generate the actual value of the virtual fields */
 
4912
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
 
4913
    }
 
4914
  }
 
4915
  return(0);
 
4916
}
 
4917
 
 
4918
 
 
4919
void setup_table_map(Table *table, TableList *table_list, uint32_t tablenr)
 
4920
{
 
4921
  table->used_fields= 0;
 
4922
  table->const_table= 0;
 
4923
  table->null_row= 0;
 
4924
  table->status= STATUS_NO_RECORD;
 
4925
  table->maybe_null= table_list->outer_join;
 
4926
  TableList *embedding= table_list->embedding;
 
4927
  while (!table->maybe_null && embedding)
 
4928
  {
 
4929
    table->maybe_null= embedding->outer_join;
 
4930
    embedding= embedding->embedding;
 
4931
  }
 
4932
  table->tablenr= tablenr;
 
4933
  table->map= (table_map) 1 << tablenr;
 
4934
  table->force_index= table_list->force_index;
 
4935
  table->covering_keys= table->s->keys_for_keyread;
 
4936
  table->merge_keys.clear_all();
 
4937
}
 
4938
 
 
4939
 
 
4940
/*****************************************************************************
 
4941
** Instansiate templates
 
4942
*****************************************************************************/
 
4943
 
 
4944
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
4945
template class List<String>;
 
4946
template class List_iterator<String>;
 
4947
#endif