~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Jay Pipes
  • Date: 2009-01-30 04:01:12 UTC
  • mto: This revision was merged to the branch mainline in revision 830.
  • Revision ID: jpipes@serialcoder-20090130040112-svbn774guj98pwi4
To remain in compatibility with MySQL, added ability to interpret
decimal arguments as datetime strings for temporal functions.

Fixed YEAR(), MONTH(), DAYOFMONTH(), DAYOFYEAR(), HOUR(), MINUTE(), SECOND(), and MICROSECOND()
to accept decimal parameters and interpret them the same way as MySQL.

Fixed an issue with the TemporalFormat::matches() method which was 
incorrectly assuming all microsecond arguments were specified as 6 digits.
Added power of 10 multiplier to usecond calculation. This fixes issues with
failures in type_date and func_sapdb test cases.

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