~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-01-21 23:38:47 UTC
  • mto: This revision was merged to the branch mainline in revision 801.
  • Revision ID: brian@tangent.org-20090121233847-jzjpp910j73ch3tw
Factor test-run for binlog removal

Show diffs side-by-side

added added

removed removed

Lines of Context:
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_proto.h"
 
36
#include <string>
58
37
 
59
38
using namespace std;
60
39
 
61
 
namespace drizzled
62
 
{
63
 
 
64
 
extern pid_t current_pid;
65
 
extern plugin::StorageEngine *heap_engine;
66
 
extern plugin::StorageEngine *myisam_engine;
67
 
 
68
 
/* Functions defined in this cursor */
69
 
 
70
 
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,
71
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);
72
53
 
73
54
/*************************************************************************/
74
55
 
76
57
 
77
58
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
78
59
{
79
 
  *length= (uint32_t) strlen((*buff)->field_name);
 
60
  *length= (uint) strlen((*buff)->field_name);
80
61
  return (unsigned char*) (*buff)->field_name;
81
62
}
82
63
 
83
 
static TABLE_CATEGORY get_table_category(const LEX_STRING *db)
 
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)
84
95
{
85
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
  }
86
106
 
87
107
  return TABLE_CATEGORY_USER;
88
108
}
89
109
 
90
110
 
91
111
/*
92
 
  Allocate a setup TableShare structure
 
112
  Allocate a setup TABLE_SHARE structure
93
113
 
94
114
  SYNOPSIS
95
115
    alloc_table_share()
102
122
    #  Share
103
123
*/
104
124
 
105
 
TableShare *alloc_table_share(TableList *table_list, char *key,
 
125
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
106
126
                               uint32_t key_length)
107
127
{
108
 
  memory::Root mem_root;
109
 
  TableShare *share;
 
128
  MEM_ROOT mem_root;
 
129
  TABLE_SHARE *share;
110
130
  char *key_buff, *path_buff;
111
131
  char path[FN_REFLEN];
112
132
  uint32_t path_length;
113
133
 
114
134
  path_length= build_table_filename(path, sizeof(path) - 1,
115
135
                                    table_list->db,
116
 
                                    table_list->table_name, false);
117
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
136
                                    table_list->table_name, "", 0);
 
137
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
118
138
  if (multi_alloc_root(&mem_root,
119
139
                       &share, sizeof(*share),
120
140
                       &key_buff, key_length,
133
153
 
134
154
    share->version=       refresh_version;
135
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
 
136
173
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
137
174
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
138
175
    pthread_cond_init(&share->cond, NULL);
141
178
}
142
179
 
143
180
 
144
 
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
145
 
{
146
 
  enum_field_types field_type;
147
 
 
148
 
  switch(proto_field_type)
149
 
  {
150
 
  case message::Table::Field::INTEGER:
151
 
    field_type= DRIZZLE_TYPE_LONG;
152
 
    break;
153
 
  case message::Table::Field::DOUBLE:
154
 
    field_type= DRIZZLE_TYPE_DOUBLE;
155
 
    break;
156
 
  case message::Table::Field::TIMESTAMP:
157
 
    field_type= DRIZZLE_TYPE_TIMESTAMP;
158
 
    break;
159
 
  case message::Table::Field::BIGINT:
160
 
    field_type= DRIZZLE_TYPE_LONGLONG;
161
 
    break;
162
 
  case message::Table::Field::DATETIME:
163
 
    field_type= DRIZZLE_TYPE_DATETIME;
164
 
    break;
165
 
  case message::Table::Field::DATE:
166
 
    field_type= DRIZZLE_TYPE_DATE;
167
 
    break;
168
 
  case message::Table::Field::VARCHAR:
169
 
    field_type= DRIZZLE_TYPE_VARCHAR;
170
 
    break;
171
 
  case message::Table::Field::DECIMAL:
172
 
    field_type= DRIZZLE_TYPE_DECIMAL;
173
 
    break;
174
 
  case message::Table::Field::ENUM:
175
 
    field_type= DRIZZLE_TYPE_ENUM;
176
 
    break;
177
 
  case message::Table::Field::BLOB:
178
 
    field_type= DRIZZLE_TYPE_BLOB;
179
 
    break;
180
 
  default:
181
 
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
 
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
182
408
    assert(1);
183
 
  }
184
 
 
185
 
  return field_type;
186
 
}
187
 
 
188
 
static Item *default_value_item(enum_field_types field_type,
189
 
                                const CHARSET_INFO *charset,
190
 
                                bool default_null, const string *default_value,
191
 
                                const string *default_bin_value)
192
 
{
193
 
  Item *default_item= NULL;
194
 
  int error= 0;
195
 
 
196
 
  if (default_null)
197
 
  {
198
 
    return new Item_null();
199
 
  }
200
 
 
201
 
  switch(field_type)
202
 
  {
203
 
  case DRIZZLE_TYPE_LONG:
204
 
  case DRIZZLE_TYPE_LONGLONG:
205
 
    default_item= new Item_int(default_value->c_str(),
206
 
                               (int64_t) internal::my_strtoll10(default_value->c_str(),
207
 
                                                                NULL,
208
 
                                                                &error),
209
 
                               default_value->length());
210
 
    break;
211
 
  case DRIZZLE_TYPE_DOUBLE:
212
 
    default_item= new Item_float(default_value->c_str(),
213
 
                                 default_value->length());
214
 
    break;
215
 
  case DRIZZLE_TYPE_NULL:
216
 
    assert(false);
217
 
  case DRIZZLE_TYPE_TIMESTAMP:
218
 
  case DRIZZLE_TYPE_DATETIME:
219
 
  case DRIZZLE_TYPE_DATE:
220
 
    if (default_value->compare("NOW()") == 0)
221
 
      break;
222
 
  case DRIZZLE_TYPE_ENUM:
223
 
    default_item= new Item_string(default_value->c_str(),
224
 
                                  default_value->length(),
225
 
                                  system_charset_info);
226
 
    break;
227
 
  case DRIZZLE_TYPE_VARCHAR:
228
 
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
229
 
    if (charset==&my_charset_bin)
230
 
    {
231
 
      default_item= new Item_string(default_bin_value->c_str(),
232
 
                                    default_bin_value->length(),
233
 
                                    &my_charset_bin);
234
 
    }
235
 
    else
236
 
    {
237
 
      default_item= new Item_string(default_value->c_str(),
238
 
                                    default_value->length(),
239
 
                                    system_charset_info);
240
 
    }
241
 
    break;
242
 
  case DRIZZLE_TYPE_DECIMAL:
243
 
    default_item= new Item_decimal(default_value->c_str(),
244
 
                                   default_value->length(),
245
 
                                   system_charset_info);
246
 
    break;
247
 
  }
248
 
 
249
 
  return default_item;
250
 
}
251
 
 
252
 
int parse_table_proto(Session& session,
253
 
                      message::Table &table,
254
 
                      TableShare *share)
255
 
{
256
 
  int error= 0;
257
 
 
258
 
  if (! table.IsInitialized())
259
 
  {
260
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
261
 
    return ER_CORRUPT_TABLE_DEFINITION;
262
 
  }
263
 
 
264
 
  share->setTableProto(new(nothrow) message::Table(table));
265
 
 
266
 
  share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
267
 
  assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
268
 
 
269
 
  message::Table::TableOptions table_options;
270
 
 
271
 
  if (table.has_options())
272
 
    table_options= table.options();
273
 
 
274
 
  uint32_t db_create_options= 0;
275
 
 
276
 
  if (table_options.has_pack_keys())
277
 
  {
278
 
    if (table_options.pack_keys())
279
 
      db_create_options|= HA_OPTION_PACK_KEYS;
280
 
    else
281
 
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
282
 
  }
283
 
 
284
 
  if (table_options.pack_record())
285
 
    db_create_options|= HA_OPTION_PACK_RECORD;
286
 
 
287
 
  /* db_create_options was stored as 2 bytes in FRM
288
 
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
289
 
   */
290
 
  share->db_create_options= (db_create_options & 0x0000FFFF);
 
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);
291
483
  share->db_options_in_use= share->db_create_options;
292
 
 
293
 
  share->row_type= table_options.has_row_type() ?
294
 
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
295
 
 
296
 
  share->block_size= table_options.has_block_size() ?
297
 
    table_options.block_size() : 0;
298
 
 
299
 
  share->table_charset= get_charset(table_options.has_collation_id()?
300
 
                                    table_options.collation_id() : 0);
301
 
 
 
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
  }
302
496
  if (!share->table_charset)
303
497
  {
304
498
    /* unknown charset in head[38] or pre-3.23 frm */
305
499
    if (use_mb(default_charset_info))
306
500
    {
307
501
      /* Warn that we may be changing the size of character columns */
308
 
      errmsg_printf(ERRMSG_LVL_WARN,
309
 
                    _("'%s' had no or invalid character set, "
310
 
                      "and default character set is multi-byte, "
311
 
                      "so character column sizes may have changed"),
312
 
                    share->path.str);
 
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);
313
506
    }
314
507
    share->table_charset= default_charset_info;
315
508
  }
316
 
 
317
509
  share->db_record_offset= 1;
318
 
 
319
 
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
320
 
 
321
 
  share->keys= table.indexes_size();
322
 
 
323
 
  share->key_parts= 0;
324
 
  for (int indx= 0; indx < table.indexes_size(); indx++)
325
 
    share->key_parts+= table.indexes(indx).index_part_size();
326
 
 
327
 
  share->key_info= (KEY*) alloc_root(&share->mem_root,
328
 
                                     table.indexes_size() * sizeof(KEY)
329
 
                                     +share->key_parts*sizeof(KEY_PART_INFO));
330
 
 
331
 
  KEY_PART_INFO *key_part;
332
 
 
333
 
  key_part= reinterpret_cast<KEY_PART_INFO*>
334
 
    (share->key_info+table.indexes_size());
335
 
 
336
 
 
337
 
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
338
 
                                            sizeof(ulong*)*share->key_parts);
339
 
 
340
 
  share->keynames.count= table.indexes_size();
341
 
  share->keynames.name= NULL;
342
 
  share->keynames.type_names= (const char**)
343
 
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
344
 
 
345
 
  share->keynames.type_lengths= (unsigned int*)
346
 
    alloc_root(&share->mem_root,
347
 
               sizeof(unsigned int) * (table.indexes_size()+1));
348
 
 
349
 
  share->keynames.type_names[share->keynames.count]= NULL;
350
 
  share->keynames.type_lengths[share->keynames.count]= 0;
351
 
 
352
 
  KEY* keyinfo= share->key_info;
353
 
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
354
 
  {
355
 
    message::Table::Index indx= table.indexes(keynr);
356
 
 
357
 
    keyinfo->table= 0;
358
 
    keyinfo->flags= 0;
359
 
 
360
 
    if (indx.is_unique())
361
 
      keyinfo->flags|= HA_NOSAME;
362
 
 
363
 
    if (indx.has_options())
364
 
    {
365
 
      message::Table::Index::IndexOptions indx_options= indx.options();
366
 
      if (indx_options.pack_key())
367
 
        keyinfo->flags|= HA_PACK_KEY;
368
 
 
369
 
      if (indx_options.var_length_key())
370
 
        keyinfo->flags|= HA_VAR_LENGTH_PART;
371
 
 
372
 
      if (indx_options.null_part_key())
373
 
        keyinfo->flags|= HA_NULL_PART_KEY;
374
 
 
375
 
      if (indx_options.binary_pack_key())
376
 
        keyinfo->flags|= HA_BINARY_PACK_KEY;
377
 
 
378
 
      if (indx_options.has_partial_segments())
379
 
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
380
 
 
381
 
      if (indx_options.auto_generated_key())
382
 
        keyinfo->flags|= HA_GENERATED_KEY;
383
 
 
384
 
      if (indx_options.has_key_block_size())
385
 
      {
386
 
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
387
 
        keyinfo->block_size= indx_options.key_block_size();
388
 
      }
389
 
      else
390
 
      {
391
 
        keyinfo->block_size= 0;
392
 
      }
393
 
    }
394
 
 
395
 
    switch (indx.type())
396
 
    {
397
 
    case message::Table::Index::UNKNOWN_INDEX:
398
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
399
 
      break;
400
 
    case message::Table::Index::BTREE:
401
 
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
402
 
      break;
403
 
    case message::Table::Index::HASH:
404
 
      keyinfo->algorithm= HA_KEY_ALG_HASH;
405
 
      break;
406
 
 
407
 
    default:
408
 
      /* TODO: suitable warning ? */
409
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
410
 
      break;
411
 
    }
412
 
 
413
 
    keyinfo->key_length= indx.key_length();
414
 
 
415
 
    keyinfo->key_parts= indx.index_part_size();
416
 
 
417
 
    keyinfo->key_part= key_part;
 
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;
418
563
    keyinfo->rec_per_key= rec_per_key;
419
 
 
420
 
    for (unsigned int partnr= 0;
421
 
         partnr < keyinfo->key_parts;
422
 
         partnr++, key_part++)
423
 
    {
424
 
      message::Table::Index::IndexPart part;
425
 
      part= indx.index_part(partnr);
426
 
 
427
 
      *rec_per_key++= 0;
428
 
 
429
 
      key_part->field= NULL;
430
 
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
431
 
      key_part->null_bit= 0;
432
 
      /* key_part->null_offset is only set if null_bit (see later) */
433
 
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
434
 
      /* key_part->type ???? */
435
 
      key_part->key_part_flag= 0;
436
 
      if (part.has_in_reverse_order())
437
 
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
438
 
 
439
 
      key_part->length= part.compare_length();
440
 
 
441
 
      key_part->store_length= key_part->length;
442
 
 
443
 
      /* key_part->offset is set later */
444
 
      key_part->key_type= part.key_type();
445
 
    }
446
 
 
447
 
    if (! indx.has_comment())
448
 
    {
449
 
      keyinfo->comment.length= 0;
450
 
      keyinfo->comment.str= NULL;
451
 
    }
452
 
    else
453
 
    {
454
 
      keyinfo->flags|= HA_USES_COMMENT;
455
 
      keyinfo->comment.length= indx.comment().length();
456
 
      keyinfo->comment.str= strmake_root(&share->mem_root,
457
 
                                         indx.comment().c_str(),
458
 
                                         keyinfo->comment.length);
459
 
    }
460
 
 
461
 
    keyinfo->name= strmake_root(&share->mem_root,
462
 
                                indx.name().c_str(),
463
 
                                indx.name().length());
464
 
 
465
 
    share->keynames.type_names[keynr]= keyinfo->name;
466
 
    share->keynames.type_lengths[keynr]= indx.name().length();
467
 
  }
468
 
 
469
 
  share->keys_for_keyread.reset();
470
 
  set_prefix(share->keys_in_use, share->keys);
471
 
 
472
 
  share->fields= table.field_size();
473
 
 
474
 
  share->field= (Field**) alloc_root(&share->mem_root,
475
 
                                     ((share->fields+1) * sizeof(Field*)));
476
 
  share->field[share->fields]= NULL;
477
 
 
478
 
  uint32_t null_fields= 0;
479
 
  share->reclength= 0;
480
 
 
481
 
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
482
 
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
483
 
 
484
 
  assert(field_offsets && field_pack_length); // TODO: fixme
485
 
 
486
 
  uint32_t interval_count= 0;
487
 
  uint32_t interval_parts= 0;
488
 
 
489
 
  uint32_t stored_columns_reclength= 0;
490
 
 
491
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
492
 
  {
493
 
    message::Table::Field pfield= table.field(fieldnr);
494
 
    if (pfield.constraints().is_nullable())
495
 
      null_fields++;
496
 
 
497
 
    enum_field_types drizzle_field_type=
498
 
      proto_field_type_to_drizzle_type(pfield.type());
499
 
 
500
 
    field_offsets[fieldnr]= stored_columns_reclength;
501
 
 
502
 
    /* the below switch is very similar to
503
 
       CreateField::create_length_to_internal_length in field.cc
504
 
       (which should one day be replace by just this code)
505
 
    */
506
 
    switch(drizzle_field_type)
507
 
    {
508
 
    case DRIZZLE_TYPE_BLOB:
509
 
    case DRIZZLE_TYPE_VARCHAR:
510
 
      {
511
 
        message::Table::Field::StringFieldOptions field_options= pfield.string_options();
512
 
 
513
 
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
514
 
                                            field_options.collation_id() : 0);
515
 
 
516
 
        if (! cs)
517
 
          cs= default_charset_info;
518
 
 
519
 
        field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
520
 
                                                     field_options.length() * cs->mbmaxlen);
521
 
      }
522
 
      break;
523
 
    case DRIZZLE_TYPE_ENUM:
524
 
      {
525
 
        message::Table::Field::SetFieldOptions field_options= pfield.set_options();
526
 
 
527
 
        field_pack_length[fieldnr]=
528
 
          get_enum_pack_length(field_options.field_value_size());
529
 
 
530
 
        interval_count++;
531
 
        interval_parts+= field_options.field_value_size();
532
 
      }
533
 
      break;
534
 
    case DRIZZLE_TYPE_DECIMAL:
535
 
      {
536
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
537
 
 
538
 
        field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
539
 
      }
540
 
      break;
541
 
    default:
542
 
      /* Zero is okay here as length is fixed for other types. */
543
 
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
544
 
    }
545
 
 
546
 
    share->reclength+= field_pack_length[fieldnr];
547
 
    stored_columns_reclength+= field_pack_length[fieldnr];
548
 
  }
549
 
 
550
 
  /* data_offset added to stored_rec_length later */
551
 
  share->stored_rec_length= stored_columns_reclength;
552
 
 
553
 
  share->null_fields= null_fields;
554
 
 
555
 
  ulong null_bits= null_fields;
556
 
  if (! table_options.pack_record())
557
 
    null_bits++;
558
 
  ulong data_offset= (null_bits + 7)/8;
559
 
 
560
 
 
561
 
  share->reclength+= data_offset;
562
 
  share->stored_rec_length+= data_offset;
563
 
 
564
 
  ulong rec_buff_length;
565
 
 
566
 
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
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);
567
732
  share->rec_buff_length= rec_buff_length;
568
 
 
569
 
  unsigned char* record= NULL;
570
 
 
571
 
  if (! (record= (unsigned char *) alloc_root(&share->mem_root,
572
 
                                              rec_buff_length)))
573
 
    abort();
574
 
 
575
 
  memset(record, 0, rec_buff_length);
576
 
 
577
 
  int null_count= 0;
578
 
 
579
 
  if (! table_options.pack_record())
580
 
  {
581
 
    null_count++; // one bit for delete mark.
582
 
    *record|= 1;
583
 
  }
584
 
 
 
733
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
 
734
                                     rec_buff_length)))
 
735
    goto err;                                   /* purecov: inspected */
585
736
  share->default_values= record;
586
 
 
587
 
  if (interval_count)
 
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)
588
754
  {
589
 
    share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
590
 
                                           interval_count*sizeof(TYPELIB));
 
755
    share->comment.length=  (int) (forminfo[46]);
 
756
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
 
757
                                     share->comment.length);
591
758
  }
592
 
  else
593
 
    share->intervals= NULL;
594
 
 
595
 
  share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
596
 
                                                          (share->fields + 1) * sizeof(char*));
597
 
 
598
 
  share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
599
 
                                                             (share->fields + 1) * sizeof(unsigned int));
600
 
 
601
 
  share->fieldnames.type_names[share->fields]= NULL;
602
 
  share->fieldnames.type_lengths[share->fields]= 0;
603
 
  share->fieldnames.count= share->fields;
604
 
 
605
 
 
606
 
  /* Now fix the TYPELIBs for the intervals (enum values)
607
 
     and field names.
608
 
   */
609
 
 
610
 
  uint32_t interval_nr= 0;
611
 
 
612
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
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
 
613
797
  {
614
 
    message::Table::Field pfield= table.field(fieldnr);
615
 
 
616
 
    /* field names */
617
 
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
618
 
                                                        pfield.name().c_str(),
619
 
                                                        pfield.name().length());
620
 
 
621
 
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
622
 
 
623
 
    /* enum typelibs */
624
 
    if (pfield.type() != message::Table::Field::ENUM)
625
 
      continue;
626
 
 
627
 
    message::Table::Field::SetFieldOptions field_options= pfield.set_options();
628
 
 
629
 
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
630
 
                                             field_options.collation_id() : 0);
631
 
 
632
 
    if (! charset)
633
 
      charset= default_charset_info;
634
 
 
635
 
    TYPELIB *t= &(share->intervals[interval_nr]);
636
 
 
637
 
    t->type_names= (const char**)alloc_root(&share->mem_root,
638
 
                                            (field_options.field_value_size() + 1) * sizeof(char*));
639
 
 
640
 
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
641
 
                                                (field_options.field_value_size() + 1) * sizeof(unsigned int));
642
 
 
643
 
    t->type_names[field_options.field_value_size()]= NULL;
644
 
    t->type_lengths[field_options.field_value_size()]= 0;
645
 
 
646
 
    t->count= field_options.field_value_size();
647
 
    t->name= NULL;
648
 
 
649
 
    for (int n= 0; n < field_options.field_value_size(); n++)
 
798
    /* Set ENUM and SET lengths */
 
799
    TYPELIB *interval;
 
800
    for (interval= share->intervals;
 
801
         interval < share->intervals + interval_count;
 
802
         interval++)
650
803
    {
651
 
      t->type_names[n]= strmake_root(&share->mem_root,
652
 
                                     field_options.field_value(n).c_str(),
653
 
                                     field_options.field_value(n).length());
654
 
 
655
 
      /* 
656
 
       * Go ask the charset what the length is as for "" length=1
657
 
       * and there's stripping spaces or some other crack going on.
658
 
       */
659
 
      uint32_t lengthsp;
660
 
      lengthsp= charset->cset->lengthsp(charset,
661
 
                                        t->type_names[n],
662
 
                                        field_options.field_value(n).length());
663
 
      t->type_lengths[n]= lengthsp;
 
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;
664
814
    }
665
 
    interval_nr++;
666
 
  }
667
 
 
668
 
 
669
 
  /* and read the fields */
670
 
  interval_nr= 0;
671
 
 
672
 
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
673
 
 
 
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;
674
839
  if (use_hash)
675
 
    use_hash= ! hash_init(&share->name_hash,
676
 
                          system_charset_info,
677
 
                          share->fields,
678
 
                          0,
679
 
                          0,
680
 
                          (hash_get_key) get_field_name,
681
 
                          0,
682
 
                          0);
683
 
 
684
 
  unsigned char* null_pos= record;;
685
 
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
686
 
 
687
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
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++)
688
846
  {
689
 
    message::Table::Field pfield= table.field(fieldnr);
690
 
 
 
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;
691
850
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
692
 
 
693
 
    switch (pfield.format())
694
 
    {
695
 
    case message::Table::Field::DefaultFormat:
696
 
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
697
 
      break;
698
 
    case message::Table::Field::FixedFormat:
699
 
      column_format= COLUMN_FORMAT_TYPE_FIXED;
700
 
      break;
701
 
    case message::Table::Field::DynamicFormat:
702
 
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
703
 
      break;
704
 
    default:
705
 
      assert(1);
706
 
    }
707
 
 
708
 
    Field::utype unireg_type= Field::NONE;
709
 
 
710
 
    if (pfield.has_numeric_options() &&
711
 
        pfield.numeric_options().is_autoincrement())
712
 
    {
713
 
      unireg_type= Field::NEXT_NUMBER;
714
 
    }
715
 
 
716
 
    if (pfield.has_options() &&
717
 
        pfield.options().has_default_value() &&
718
 
        pfield.options().default_value().compare("NOW()") == 0)
719
 
    {
720
 
      if (pfield.options().has_update_value() &&
721
 
          pfield.options().update_value().compare("NOW()") == 0)
722
 
      {
723
 
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
724
 
      }
725
 
      else if (! pfield.options().has_update_value())
726
 
      {
727
 
        unireg_type= Field::TIMESTAMP_DN_FIELD;
728
 
      }
729
 
      else
730
 
        assert(1); // Invalid update value.
731
 
    }
732
 
    else if (pfield.has_options() &&
733
 
             pfield.options().has_update_value() &&
734
 
             pfield.options().update_value().compare("NOW()") == 0)
735
 
    {
736
 
      unireg_type= Field::TIMESTAMP_UN_FIELD;
737
 
    }
738
 
 
 
851
    const CHARSET_INFO *charset= NULL;
739
852
    LEX_STRING comment;
740
 
    if (!pfield.has_comment())
741
 
    {
742
 
      comment.str= (char*)"";
743
 
      comment.length= 0;
744
 
    }
745
 
    else
746
 
    {
747
 
      size_t len= pfield.comment().length();
748
 
      const char* str= pfield.comment().c_str();
749
 
 
750
 
      comment.str= strmake_root(&share->mem_root, str, len);
751
 
      comment.length= len;
752
 
    }
753
 
 
754
 
    enum_field_types field_type;
755
 
 
756
 
    field_type= proto_field_type_to_drizzle_type(pfield.type());
757
 
 
758
 
    const CHARSET_INFO *charset= &my_charset_bin;
759
 
 
760
 
    if (field_type == DRIZZLE_TYPE_BLOB ||
761
 
        field_type == DRIZZLE_TYPE_VARCHAR)
762
 
    {
763
 
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
764
 
 
765
 
      charset= get_charset(field_options.has_collation_id() ?
766
 
                           field_options.collation_id() : 0);
767
 
 
768
 
      if (! charset)
769
 
        charset= default_charset_info;
770
 
    }
771
 
 
772
 
    if (field_type == DRIZZLE_TYPE_ENUM)
773
 
    {
774
 
      message::Table::Field::SetFieldOptions field_options= pfield.set_options();
775
 
 
776
 
      charset= get_charset(field_options.has_collation_id()?
777
 
                           field_options.collation_id() : 0);
778
 
 
779
 
      if (! charset)
780
 
              charset= default_charset_info;
781
 
    }
782
 
 
783
 
    uint8_t decimals= 0;
784
 
    if (field_type == DRIZZLE_TYPE_DECIMAL
785
 
        || field_type == DRIZZLE_TYPE_DOUBLE)
786
 
    {
787
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
788
 
 
789
 
      if (! pfield.has_numeric_options() || ! fo.has_scale())
790
 
      {
 
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
791
886
        /*
792
 
          We don't write the default to table proto so
793
 
          if no decimals specified for DOUBLE, we use the default.
 
887
          The interval_id byte in the .frm file stores the length of the
 
888
          expression statement for a virtual column.
794
889
        */
795
 
        decimals= NOT_FIXED_DEC;
 
890
        vcol_info_length= interval_nr;
 
891
        interval_nr= 0;
 
892
      }
 
893
      if (!comment_length)
 
894
      {
 
895
        comment.str= (char*) "";
 
896
        comment.length=0;
796
897
      }
797
898
      else
798
899
      {
799
 
        if (fo.scale() > DECIMAL_MAX_SCALE)
 
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)
800
915
        {
801
916
          error= 4;
802
917
          goto err;
803
918
        }
804
 
        decimals= static_cast<uint8_t>(fo.scale());
 
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++;
805
929
      }
806
930
    }
807
 
 
808
 
    Item *default_value= NULL;
809
 
 
810
 
    if (pfield.options().has_default_value() ||
811
 
        pfield.options().has_default_null()  ||
812
 
        pfield.options().has_default_bin_value())
813
 
    {
814
 
      default_value= default_value_item(field_type,
815
 
                                        charset,
816
 
                                        pfield.options().default_null(),
817
 
                                        &pfield.options().default_value(),
818
 
                                        &pfield.options().default_bin_value());
819
 
    }
820
 
 
821
 
 
822
 
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
823
 
    memset(&temp_table, 0, sizeof(temp_table));
824
 
    temp_table.s= share;
825
 
    temp_table.in_use= &session;
826
 
    temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
827
 
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
828
 
 
829
 
    uint32_t field_length= 0; //Assignment is for compiler complaint.
830
 
 
831
 
    switch (field_type)
832
 
    {
833
 
    case DRIZZLE_TYPE_BLOB:
834
 
    case DRIZZLE_TYPE_VARCHAR:
835
 
    {
836
 
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
837
 
 
838
 
      charset= get_charset(field_options.has_collation_id() ?
839
 
                           field_options.collation_id() : 0);
840
 
 
841
 
      if (! charset)
842
 
        charset= default_charset_info;
843
 
 
844
 
      field_length= field_options.length() * charset->mbmaxlen;
845
 
    }
846
 
      break;
847
 
    case DRIZZLE_TYPE_DOUBLE:
848
 
    {
849
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
850
 
      if (!fo.has_precision() && !fo.has_scale())
 
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))
851
943
      {
852
 
        field_length= DBL_DIG+7;
 
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;
853
959
      }
854
960
      else
855
 
      {
856
 
        field_length= fo.precision();
857
 
      }
858
 
      if (field_length < decimals &&
859
 
          decimals != NOT_FIXED_DEC)
860
 
      {
861
 
        my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
862
 
        error= 1;
863
 
        goto err;
864
 
      }
865
 
      break;
866
 
    }
867
 
    case DRIZZLE_TYPE_DECIMAL:
868
 
    {
869
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
870
 
 
871
 
      field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
872
 
                                                   false);
873
 
      break;
874
 
    }
875
 
    case DRIZZLE_TYPE_TIMESTAMP:
876
 
    case DRIZZLE_TYPE_DATETIME:
877
 
      field_length= DateTime::MAX_STRING_LENGTH;
878
 
      break;
879
 
    case DRIZZLE_TYPE_DATE:
880
 
      field_length= Date::MAX_STRING_LENGTH;
881
 
      break;
882
 
    case DRIZZLE_TYPE_ENUM:
883
 
    {
884
 
      field_length= 0;
885
 
 
886
 
      message::Table::Field::SetFieldOptions fo= pfield.set_options();
887
 
 
888
 
      for(int valnr= 0; valnr < fo.field_value_size(); valnr++)
889
 
      {
890
 
        if (fo.field_value(valnr).length() > field_length)
891
 
          field_length= charset->cset->numchars(charset,
892
 
                                                fo.field_value(valnr).c_str(),
893
 
                                                fo.field_value(valnr).c_str()
894
 
                                                + fo.field_value(valnr).length())
895
 
            * charset->mbmaxlen;
896
 
      }
897
 
    }
898
 
      break;
899
 
    case DRIZZLE_TYPE_LONG:
900
 
      {
901
 
        uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
902
 
          field_length= MAX_INT_WIDTH+sign_len;
903
 
      }
904
 
      break;
905
 
    case DRIZZLE_TYPE_LONGLONG:
906
 
      field_length= MAX_BIGINT_WIDTH;
907
 
      break;
908
 
    case DRIZZLE_TYPE_NULL:
909
 
      abort(); // Programming error
910
 
    }
911
 
 
912
 
    Field* f= make_field(share,
913
 
                         &share->mem_root,
914
 
                         record + field_offsets[fieldnr] + data_offset,
915
 
                         field_length,
916
 
                         pfield.constraints().is_nullable(),
917
 
                         null_pos,
918
 
                         null_bit_pos,
919
 
                         decimals,
920
 
                         field_type,
921
 
                         charset,
922
 
                         (Field::utype) MTYP_TYPENR(unireg_type),
923
 
                         ((field_type == DRIZZLE_TYPE_ENUM) ?
924
 
                          share->intervals + (interval_nr++)
925
 
                          : (TYPELIB*) 0),
926
 
                         share->fieldnames.type_names[fieldnr]);
927
 
 
928
 
    share->field[fieldnr]= f;
929
 
 
930
 
    f->init(&temp_table); /* blob default values need table obj */
931
 
 
932
 
    if (! (f->flags & NOT_NULL_FLAG))
933
 
    {
934
 
      *f->null_ptr|= f->null_bit;
935
 
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
 
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))
936
998
        null_pos++;
937
 
      null_count++;
938
 
    }
939
 
 
940
 
    if (default_value)
941
 
    {
942
 
      enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
943
 
      session.count_cuted_fields= CHECK_FIELD_WARN;
944
 
      int res= default_value->save_in_field(f, 1);
945
 
      session.count_cuted_fields= old_count_cuted_fields;
946
 
      if (res != 0 && res != 3) /* @TODO Huh? */
947
 
      {
948
 
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
949
 
        error= 1;
950
 
        goto err;
951
 
      }
952
 
    }
953
 
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
954
 
             (f->flags & NOT_NULL_FLAG))
955
 
    {
956
 
      f->set_notnull();
957
 
      f->store((int64_t) 1, true);
958
 
    }
959
 
    else
960
 
      f->reset();
961
 
 
962
 
    /* hack to undo f->init() */
963
 
    f->table= NULL;
964
 
    f->orig_table= NULL;
965
 
 
966
 
    f->field_index= fieldnr;
967
 
    f->comment= comment;
968
 
    if (! default_value &&
969
 
        ! (f->unireg_check==Field::NEXT_NUMBER) &&
970
 
        (f->flags & NOT_NULL_FLAG) &&
971
 
        (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
972
 
    {
973
 
      f->flags|= NO_DEFAULT_VALUE_FLAG;
974
 
    }
975
 
 
976
 
    if (f->unireg_check == Field::NEXT_NUMBER)
977
 
      share->found_next_number_field= &(share->field[fieldnr]);
978
 
 
979
 
    if (share->timestamp_field == f)
980
 
      share->timestamp_field_offset= fieldnr;
981
 
 
982
 
    if (use_hash) /* supposedly this never fails... but comments lie */
 
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)
983
1009
      (void) my_hash_insert(&share->name_hash,
984
 
                            (unsigned char*)&(share->field[fieldnr]));
985
 
 
986
 
  }
987
 
 
988
 
  keyinfo= share->key_info;
989
 
  for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
990
 
  {
991
 
    key_part= keyinfo->key_part;
992
 
 
993
 
    for (unsigned int partnr= 0;
994
 
         partnr < keyinfo->key_parts;
995
 
         partnr++, key_part++)
 
1010
                            (unsigned char*) field_ptr); // never fail
 
1011
    if (!reg_field->is_stored)
996
1012
    {
997
 
      /* 
998
 
       * Fix up key_part->offset by adding data_offset.
999
 
       * We really should compute offset as well.
1000
 
       * But at least this way we are a little better.
1001
 
       */
1002
 
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
1013
      share->stored_fields--;
 
1014
      if (share->stored_rec_length>=recpos)
 
1015
        share->stored_rec_length= recpos-1;
1003
1016
    }
1004
1017
  }
1005
 
 
1006
 
  /*
1007
 
    We need to set the unused bits to 1. If the number of bits is a multiple
1008
 
    of 8 there are no unused bits.
1009
 
  */
1010
 
 
1011
 
  if (null_count & 7)
1012
 
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1013
 
 
1014
 
  share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1015
 
 
1016
 
  share->last_null_bit_pos= null_bit_pos;
1017
 
 
1018
 
  free(field_offsets);
1019
 
  field_offsets= NULL;
1020
 
  free(field_pack_length);
1021
 
  field_pack_length= NULL;
1022
 
 
1023
 
  /* Fix key stuff */
1024
 
  if (share->key_parts)
 
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
1025
  {
1026
 
    uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1027
 
                                                &share->keynames, 3) - 1); /* @TODO Huh? */
1028
 
 
 
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
1029
    keyinfo= share->key_info;
1030
1030
    key_part= keyinfo->key_part;
1031
1031
 
1032
 
    for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
 
1032
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1033
1033
    {
1034
1034
      uint32_t usable_parts= 0;
 
1035
      keyinfo->name=(char*) share->keynames.type_names[key];
1035
1036
 
1036
1037
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1037
1038
      {
1038
 
        /*
1039
 
          If the UNIQUE key doesn't have NULL columns and is not a part key
1040
 
          declare this as a primary key.
1041
 
        */
1042
 
        primary_key=key;
1043
 
        for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1044
 
        {
1045
 
          uint32_t fieldnr= key_part[i].fieldnr;
1046
 
          if (! fieldnr ||
1047
 
              share->field[fieldnr-1]->null_ptr ||
1048
 
              share->field[fieldnr-1]->key_length() != key_part[i].length)
1049
 
          {
1050
 
            primary_key= MAX_KEY; // Can't be used
1051
 
            break;
1052
 
          }
1053
 
        }
 
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
        }
1054
1056
      }
1055
1057
 
1056
 
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1058
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1057
1059
      {
1058
1060
        Field *field;
1059
 
        if (! key_part->fieldnr)
 
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)
1060
1067
        {
1061
 
          abort(); // goto err;
 
1068
          error= 4;                             // Wrong file
 
1069
          goto err;
1062
1070
        }
1063
1071
        field= key_part->field= share->field[key_part->fieldnr-1];
1064
1072
        key_part->type= field->key_type();
1065
1073
        if (field->null_ptr)
1066
1074
        {
1067
 
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
 
1075
          key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
1068
1076
                                        share->default_values);
1069
1077
          key_part->null_bit= field->null_bit;
1070
1078
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1088
1096
                           (keyinfo->key_parts == 1)) ?
1089
1097
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1090
1098
        if (i == 0)
1091
 
          field->key_start.set(key);
 
1099
          field->key_start.set_bit(key);
1092
1100
        if (field->key_length() == key_part->length &&
1093
1101
            !(field->flags & BLOB_FLAG))
1094
1102
        {
1095
 
          enum ha_key_alg algo= share->key_info[key].algorithm;
1096
 
          if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
 
1103
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1097
1104
          {
1098
 
            share->keys_for_keyread.set(key);
1099
 
            field->part_of_key.set(key);
1100
 
            field->part_of_key_not_clustered.set(key);
 
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);
1101
1108
          }
1102
 
          if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
1103
 
            field->part_of_sortkey.set(key);
 
1109
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
 
1110
            field->part_of_sortkey.set_bit(key);
1104
1111
        }
1105
1112
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1106
1113
            usable_parts == i)
1113
1120
            If this field is part of the primary key and all keys contains
1114
1121
            the primary key, then we can use any key to find this column
1115
1122
          */
1116
 
          if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
 
1123
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1117
1124
          {
1118
1125
            field->part_of_key= share->keys_in_use;
1119
 
            if (field->part_of_sortkey.test(key))
 
1126
            if (field->part_of_sortkey.is_set(key))
1120
1127
              field->part_of_sortkey= share->keys_in_use;
1121
1128
          }
1122
1129
        }
1130
1137
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1131
1138
                    keyinfo->key_parts);
1132
1139
      share->total_key_length+= keyinfo->key_length;
1133
 
 
1134
 
      if (keyinfo->flags & HA_NOSAME)
1135
 
      {
 
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))
1136
1146
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1137
 
      }
1138
1147
    }
1139
1148
    if (primary_key < MAX_KEY &&
1140
 
        (share->keys_in_use.test(primary_key)))
 
1149
        (share->keys_in_use.is_set(primary_key)))
1141
1150
    {
1142
1151
      share->primary_key= primary_key;
1143
1152
      /*
1144
 
        If we are using an integer as the primary key then allow the user to
1145
 
        refer to it as '_rowid'
 
1153
        If we are using an integer as the primary key then allow the user to
 
1154
        refer to it as '_rowid'
1146
1155
      */
1147
1156
      if (share->key_info[primary_key].key_parts == 1)
1148
1157
      {
1149
 
        Field *field= share->key_info[primary_key].key_part[0].field;
1150
 
        if (field && field->result_type() == INT_RESULT)
 
1158
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1159
        if (field && field->result_type() == INT_RESULT)
1151
1160
        {
1152
1161
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1153
 
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1162
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1154
1163
                                      fieldnr);
1155
1164
        }
1156
1165
      }
1160
1169
  }
1161
1170
  else
1162
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
  }
1163
1182
 
1164
1183
  if (share->found_next_number_field)
1165
1184
  {
1166
 
    Field *reg_field= *share->found_next_number_field;
1167
 
    if ((int) (share->next_number_index= (uint32_t)
 
1185
    reg_field= *share->found_next_number_field;
 
1186
    if ((int) (share->next_number_index= (uint)
1168
1187
               find_ref_key(share->key_info, share->keys,
1169
1188
                            share->default_values, reg_field,
1170
1189
                            &share->next_number_key_offset,
1186
1205
    /* Store offsets to blob fields to find them fast */
1187
1206
    if (!(share->blob_field= save=
1188
1207
          (uint*) alloc_root(&share->mem_root,
1189
 
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
 
1208
                             (uint) (share->blob_fields* sizeof(uint)))))
1190
1209
      goto err;
1191
 
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
 
1210
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1192
1211
    {
1193
1212
      if ((*ptr)->flags & BLOB_FLAG)
1194
 
        (*save++)= k;
 
1213
        (*save++)= k;
1195
1214
    }
1196
1215
  }
1197
1216
 
1198
 
  share->db_low_byte_first= true; // @todo Question this.
 
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();
1199
1226
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1200
1227
 
1201
 
  my_bitmap_map *bitmaps;
1202
 
 
1203
1228
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1204
1229
                                             share->column_bitmap_size)))
1205
1230
    goto err;
1206
 
  share->all_set.init(bitmaps, share->fields);
1207
 
  share->all_set.setAll();
 
1231
  bitmap_init(&share->all_set, bitmaps, share->fields, false);
 
1232
  bitmap_set_all(&share->all_set);
1208
1233
 
 
1234
  delete handler_file;
 
1235
  if (buff)
 
1236
    free(buff);
1209
1237
  return (0);
1210
1238
 
1211
 
err:
1212
 
  if (field_offsets)
1213
 
    free(field_offsets);
1214
 
  if (field_pack_length)
1215
 
    free(field_pack_length);
1216
 
 
 
1239
 err:
 
1240
  if (buff)
 
1241
    free(buff);
1217
1242
  share->error= error;
1218
 
  share->open_errno= errno;
1219
 
  share->errarg= 0;
 
1243
  share->open_errno= my_errno;
 
1244
  share->errarg= errarg;
 
1245
  if (disk_buff)
 
1246
    free(disk_buff);
 
1247
  delete handler_file;
1220
1248
  hash_free(&share->name_hash);
1221
 
  share->open_table_error(error, share->open_errno, 0);
1222
 
 
1223
 
  return error;
1224
 
}
1225
 
 
1226
 
/*
1227
 
  Read table definition from a binary / text based .frm cursor
1228
 
 
1229
 
  SYNOPSIS
1230
 
  open_table_def()
1231
 
  session               Thread Cursor
1232
 
  share         Fill this with table definition
1233
 
 
1234
 
  NOTES
1235
 
    This function is called when the table definition is not cached in
1236
 
    table_def_cache
1237
 
    The data is returned in 'share', which is alloced by
1238
 
    alloc_table_share().. The code assumes that share is initialized.
 
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.
1239
1419
 
1240
1420
  RETURN VALUES
1241
 
   0    ok
1242
 
   1    Error (see open_table_error)
1243
 
   2    Error (see open_table_error)
1244
 
   3    Wrong data in .frm cursor
1245
 
   4    Error (see open_table_error)
1246
 
   5    Error (see open_table_error: charset unavailable)
1247
 
   6    Unknown .frm version
 
1421
    true            Failure
 
1422
    false           Success
1248
1423
*/
1249
 
 
1250
 
int open_table_def(Session& session, TableShare *share)
 
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)
1251
1430
{
1252
 
  int error;
1253
 
  bool error_given;
1254
 
 
1255
 
  error= 1;
1256
 
  error_given= 0;
1257
 
 
1258
 
  message::Table table;
1259
 
 
1260
 
  error= plugin::StorageEngine::getTableDefinition(session, share->normalized_path.str,
1261
 
                                                   share->db.str,
1262
 
                                                   share->table_name.str,
1263
 
                                                   false,
1264
 
                                                   &table);
1265
 
 
1266
 
  if (error != EEXIST)
1267
 
  {
1268
 
    if (error > 0)
1269
 
    {
1270
 
      errno= error;
1271
 
      error= 1;
1272
 
    }
1273
 
    else
1274
 
    {
1275
 
      if (not table.IsInitialized())
1276
 
      {
1277
 
        error= 4;
1278
 
      }
1279
 
    }
1280
 
    goto err_not_open;
1281
 
  }
1282
 
 
1283
 
  error= parse_table_proto(session, table, share);
1284
 
 
1285
 
  share->table_category= get_table_category(& share->db);
1286
 
 
1287
 
  if (not error)
1288
 
    session.status_var.opened_shares++;
1289
 
 
1290
 
err_not_open:
1291
 
  if (error && !error_given)
1292
 
  {
1293
 
    share->error= error;
1294
 
    share->open_table_error(error, (share->open_errno= errno), 0);
1295
 
  }
1296
 
 
1297
 
  return(error);
 
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);
1298
1521
}
1299
1522
 
1300
1523
 
1301
1524
/*
1302
 
  Open a table based on a TableShare
 
1525
  Open a table based on a TABLE_SHARE
1303
1526
 
1304
1527
  SYNOPSIS
1305
1528
    open_table_from_share()
1306
 
    session                     Thread Cursor
 
1529
    session                     Thread handler
1307
1530
    share               Table definition
1308
1531
    alias               Alias for table
1309
1532
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1310
1533
                        HA_OPEN_RNDFILE..) can be 0 (example in
1311
1534
                        ha_example_table)
 
1535
    prgflag             READ_ALL etc..
1312
1536
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
1313
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
1314
1541
 
1315
1542
  RETURN VALUES
1316
1543
   0    ok
1317
1544
   1    Error (see open_table_error)
1318
1545
   2    Error (see open_table_error)
1319
 
   3    Wrong data in .frm cursor
 
1546
   3    Wrong data in .frm file
1320
1547
   4    Error (see open_table_error)
1321
1548
   5    Error (see open_table_error: charset unavailable)
1322
1549
   7    Table definition has changed in engine
1323
1550
*/
1324
1551
 
1325
 
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1326
 
                          uint32_t db_stat, uint32_t ha_open_flags,
1327
 
                          Table *outparam)
 
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)
1328
1555
{
1329
1556
  int error;
1330
1557
  uint32_t records, i, bitmap_size;
1331
1558
  bool error_reported= false;
1332
1559
  unsigned char *record, *bitmaps;
1333
 
  Field **field_ptr;
 
1560
  Field **field_ptr, **vfield_ptr;
1334
1561
 
1335
1562
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1336
1563
  assert(session->lex->is_lex_started);
1337
1564
 
1338
1565
  error= 1;
1339
 
  outparam->resetTable(session, share, db_stat);
1340
 
 
1341
 
 
1342
 
  if (not (outparam->alias= strdup(alias)))
1343
 
    goto err;
1344
 
 
1345
 
  /* Allocate Cursor */
1346
 
  if (not (outparam->cursor= share->db_type()->getCursor(*share, &outparam->mem_root)))
1347
 
    goto err;
 
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
  }
1348
1592
 
1349
1593
  error= 4;
1350
 
  records= 0;
1351
 
  if ((db_stat & HA_OPEN_KEYFILE))
 
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))
1352
1598
    records=1;
1353
 
 
1354
 
  records++;
 
1599
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
1600
    records++;
1355
1601
 
1356
1602
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1357
1603
                                   share->rec_buff_length * records)))
1358
 
    goto err;
 
1604
    goto err;                                   /* purecov: inspected */
1359
1605
 
1360
1606
  if (records == 0)
1361
1607
  {
1387
1633
#endif
1388
1634
 
1389
1635
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1390
 
                                          (uint32_t) ((share->fields+1)*
 
1636
                                          (uint) ((share->fields+1)*
1391
1637
                                                  sizeof(Field*)))))
1392
 
    goto err;
 
1638
    goto err;                                   /* purecov: inspected */
1393
1639
 
1394
1640
  outparam->field= field_ptr;
1395
1641
 
1396
1642
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
1397
 
 
1398
 
  outparam->null_flags= (unsigned char*) record+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);
1399
1648
 
1400
1649
  /* Setup copy of fields from share, but use the right alias and record */
1401
 
  for (i= 0 ; i < share->fields; i++, field_ptr++)
 
1650
  for (i=0 ; i < share->fields; i++, field_ptr++)
1402
1651
  {
1403
1652
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1404
1653
      goto err;
1407
1656
 
1408
1657
  if (share->found_next_number_field)
1409
1658
    outparam->found_next_number_field=
1410
 
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
 
1659
      outparam->field[(uint) (share->found_next_number_field - share->field)];
1411
1660
  if (share->timestamp_field)
1412
1661
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1413
1662
 
1458
1707
    }
1459
1708
  }
1460
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
 
1461
1749
  /* Allocate bitmaps */
1462
1750
 
1463
1751
  bitmap_size= share->column_bitmap_size;
1464
1752
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1465
1753
    goto err;
1466
 
  outparam->def_read_set.init((my_bitmap_map*) bitmaps, share->fields);
1467
 
  outparam->def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
1468
 
  outparam->tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
 
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);
1469
1760
  outparam->default_column_bitmaps();
1470
1761
 
1471
1762
  /* The table struct is now initialized;  Open the table */
1472
1763
  error= 2;
1473
 
  if (db_stat)
 
1764
  if (db_stat && open_mode != OTM_ALTER)
1474
1765
  {
1475
1766
    int ha_err;
1476
 
    if ((ha_err= (outparam->cursor->
 
1767
    if ((ha_err= (outparam->file->
1477
1768
                  ha_open(outparam, share->normalized_path.str,
1478
1769
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1479
1770
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1482
1773
                          HA_OPEN_ABORT_IF_LOCKED :
1483
1774
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1484
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
 
1485
1781
      switch (ha_err)
1486
1782
      {
1487
1783
        case HA_ERR_NO_SUCH_TABLE:
1488
1784
          /*
1489
1785
            The table did not exists in storage engine, use same error message
1490
 
            as if the .frm cursor didn't exist
 
1786
            as if the .frm file didn't exist
1491
1787
          */
1492
1788
          error= 1;
1493
 
          errno= ENOENT;
 
1789
          my_errno= ENOENT;
1494
1790
          break;
1495
1791
        case EMFILE:
1496
1792
          /*
1497
1793
            Too many files opened, use same error message as if the .frm
1498
 
            cursor can't open
 
1794
            file can't open
1499
1795
           */
1500
1796
          error= 1;
1501
 
          errno= EMFILE;
 
1797
          my_errno= EMFILE;
1502
1798
          break;
1503
1799
        default:
1504
 
          outparam->print_error(ha_err, MYF(0));
 
1800
          outparam->file->print_error(ha_err, MYF(0));
1505
1801
          error_reported= true;
1506
1802
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1507
1803
            error= 7;
1508
1804
          break;
1509
1805
      }
1510
 
      goto err;
 
1806
      goto err;                                 /* purecov: inspected */
1511
1807
    }
1512
1808
  }
1513
1809
 
1515
1811
  memset(bitmaps, 0, bitmap_size*3);
1516
1812
#endif
1517
1813
 
 
1814
  outparam->no_replicate= outparam->file;
1518
1815
  session->status_var.opened_tables++;
1519
1816
 
1520
1817
  return (0);
1521
1818
 
1522
1819
 err:
1523
 
  if (!error_reported)
1524
 
    share->open_table_error(error, errno, 0);
1525
 
  delete outparam->cursor;
1526
 
  outparam->cursor= 0;                          // For easier error checking
1527
 
  outparam->db_stat= 0;
 
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;
1528
1825
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1529
1826
  free((char*) outparam->alias);
1530
1827
  return (error);
1531
1828
}
1532
1829
 
1533
 
bool Table::fill_item_list(List<Item> *item_list) const
 
1830
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
 
1831
uint32_t  Table::tmpkeyval()
1534
1832
{
1535
 
  /*
1536
 
    All Item_field's created using a direct pointer to a field
1537
 
    are fixed in Item_field constructor.
1538
 
  */
1539
 
  for (Field **ptr= field; *ptr; ptr++)
1540
 
  {
1541
 
    Item_field *item= new Item_field(*ptr);
1542
 
    if (!item || item_list->push_back(item))
1543
 
      return true;
1544
 
  }
1545
 
  return false;
 
1833
  return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
1546
1834
}
1547
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
 
1548
1845
int Table::closefrm(bool free_share)
1549
1846
{
1550
 
  int error= 0;
 
1847
  int error=0;
1551
1848
 
1552
1849
  if (db_stat)
1553
 
    error= cursor->close();
 
1850
    error= file->close();
1554
1851
  free((char*) alias);
1555
1852
  alias= NULL;
1556
1853
  if (field)
1559
1856
      delete *ptr;
1560
1857
    field= 0;
1561
1858
  }
1562
 
  delete cursor;
1563
 
  cursor= 0;                            /* For easier errorchecking */
 
1859
  delete file;
 
1860
  file= 0;                              /* For easier errorchecking */
1564
1861
  if (free_share)
1565
1862
  {
1566
 
    if (s->tmp_table == STANDARD_TABLE)
1567
 
      TableShare::release(s);
 
1863
    if (s->tmp_table == NO_TMP_TABLE)
 
1864
      release_table_share(s, RELEASE_NORMAL);
1568
1865
    else
1569
 
      s->free_table_share();
 
1866
      free_table_share(s);
1570
1867
  }
1571
1868
  free_root(&mem_root, MYF(0));
1572
1869
 
1574
1871
}
1575
1872
 
1576
1873
 
1577
 
void Table::resetTable(Session *session,
1578
 
                       TableShare *share,
1579
 
                       uint32_t db_stat_arg)
1580
 
{
1581
 
  s= share;
1582
 
  field= NULL;
1583
 
 
1584
 
  cursor= NULL;
1585
 
  next= NULL;
1586
 
  prev= NULL;
1587
 
 
1588
 
  read_set= NULL;
1589
 
  write_set= NULL;
1590
 
 
1591
 
  tablenr= 0;
1592
 
  db_stat= db_stat_arg;
1593
 
 
1594
 
  in_use= session;
1595
 
  record[0]= (unsigned char *) NULL;
1596
 
  record[1]= (unsigned char *) NULL;
1597
 
 
1598
 
  insert_values= NULL;
1599
 
  key_info= NULL;
1600
 
  next_number_field= NULL;
1601
 
  found_next_number_field= NULL;
1602
 
  timestamp_field= NULL;
1603
 
 
1604
 
  pos_in_table_list= NULL;
1605
 
  group= NULL;
1606
 
  alias= NULL;
1607
 
  null_flags= NULL;
1608
 
 
1609
 
  lock_position= 0;
1610
 
  lock_data_start= 0;
1611
 
  lock_count= 0;
1612
 
  used_fields= 0;
1613
 
  status= 0;
1614
 
  derived_select_number= 0;
1615
 
  current_lock= F_UNLCK;
1616
 
  copy_blobs= false;
1617
 
 
1618
 
  maybe_null= false;
1619
 
 
1620
 
  null_row= false;
1621
 
 
1622
 
  force_index= false;
1623
 
  distinct= false;
1624
 
  const_table= false;
1625
 
  no_rows= false;
1626
 
  key_read= false;
1627
 
  no_keyread= false;
1628
 
 
1629
 
  open_placeholder= false;
1630
 
  locked_by_name= false;
1631
 
  no_cache= false;
1632
 
 
1633
 
  auto_increment_field_not_null= false;
1634
 
  alias_name_used= false;
1635
 
 
1636
 
  query_id= 0;
1637
 
  quick_condition_rows= 0;
1638
 
 
1639
 
  timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1640
 
  map= 0;
1641
 
 
1642
 
  reginfo.reset();
1643
 
 
1644
 
  covering_keys.reset();
1645
 
 
1646
 
  quick_keys.reset();
1647
 
  merge_keys.reset();
1648
 
 
1649
 
  keys_in_use_for_query.reset();
1650
 
  keys_in_use_for_group_by.reset();
1651
 
  keys_in_use_for_order_by.reset();
1652
 
 
1653
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
1654
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
1655
 
 
1656
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
1657
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1658
 
 
1659
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1660
 
  memset(&sort, 0, sizeof(filesort_info_st));
1661
 
}
1662
 
 
1663
 
 
1664
 
 
1665
1874
/* Deallocate temporary blob storage */
1666
1875
 
1667
1876
void free_blobs(register Table *table)
1674
1883
}
1675
1884
 
1676
1885
 
1677
 
        /* error message when opening a form cursor */
1678
 
 
1679
 
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
 
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)
1680
2031
{
1681
2032
  int err_no;
1682
2033
  char buff[FN_REFLEN];
1683
2034
  myf errortype= ME_ERROR+ME_WAITTANG;
1684
2035
 
1685
 
  switch (pass_error) {
 
2036
  switch (error) {
1686
2037
  case 7:
1687
2038
  case 1:
1688
2039
    if (db_errno == ENOENT)
1689
 
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
 
2040
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1690
2041
    else
1691
2042
    {
1692
 
      sprintf(buff,"%s",normalized_path.str);
 
2043
      sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
1693
2044
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1694
2045
               errortype, buff, db_errno);
1695
2046
    }
1696
2047
    break;
1697
2048
  case 2:
1698
2049
  {
1699
 
    Cursor *cursor= 0;
 
2050
    handler *file= 0;
1700
2051
    const char *datext= "";
1701
2052
 
1702
 
    if (db_type() != NULL)
 
2053
    if (share->db_type() != NULL)
1703
2054
    {
1704
 
      if ((cursor= db_type()->getCursor(*this, current_session->mem_root)))
 
2055
      if ((file= get_new_handler(share, current_session->mem_root,
 
2056
                                 share->db_type())))
1705
2057
      {
1706
 
        if (!(datext= *db_type()->bas_ext()))
 
2058
        if (!(datext= *file->bas_ext()))
1707
2059
          datext= "";
1708
2060
      }
1709
2061
    }
1710
2062
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1711
2063
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1712
 
    sprintf(buff,"%s%s", normalized_path.str,datext);
 
2064
    sprintf(buff,"%s%s", share->normalized_path.str,datext);
1713
2065
    my_error(err_no,errortype, buff, db_errno);
1714
 
    delete cursor;
 
2066
    delete file;
1715
2067
    break;
1716
2068
  }
1717
2069
  case 5:
1718
2070
  {
1719
 
    const char *csname= get_charset_name((uint32_t) pass_errarg);
 
2071
    const char *csname= get_charset_name((uint) errarg);
1720
2072
    char tmp[10];
1721
2073
    if (!csname || csname[0] =='?')
1722
2074
    {
1723
 
      snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
 
2075
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
1724
2076
      csname= tmp;
1725
2077
    }
1726
2078
    my_printf_error(ER_UNKNOWN_COLLATION,
1727
2079
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1728
 
                    MYF(0), csname, table_name.str);
 
2080
                    MYF(0), csname, share->table_name.str);
1729
2081
    break;
1730
2082
  }
1731
2083
  case 6:
1732
 
    sprintf(buff,"%s", normalized_path.str);
 
2084
    sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
1733
2085
    my_printf_error(ER_NOT_FORM_FILE,
1734
2086
                    _("Table '%-.64s' was created with a different version "
1735
2087
                    "of Drizzle and cannot be read"),
1739
2091
    break;
1740
2092
  default:                              /* Better wrong error than none */
1741
2093
  case 4:
1742
 
    sprintf(buff,"%s", normalized_path.str);
 
2094
    sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
1743
2095
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1744
2096
    break;
1745
2097
  }
1747
2099
} /* open_table_error */
1748
2100
 
1749
2101
 
1750
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
 
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)
1751
2143
{
1752
2144
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
1753
2145
  if (!result)
1754
2146
    return 0;
1755
 
  result->count= strings.elements;
1756
 
  result->name= "";
1757
 
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
1758
 
  
 
2147
  result->count=strings.elements;
 
2148
  result->name="";
 
2149
  uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
1759
2150
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1760
2151
    return 0;
1761
 
    
1762
2152
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1763
 
 
1764
2153
  List_iterator<String> it(strings);
1765
2154
  String *tmp;
1766
 
  for (uint32_t i= 0; (tmp= it++); i++)
 
2155
  for (uint32_t i=0; (tmp=it++) ; i++)
1767
2156
  {
1768
2157
    result->type_names[i]= tmp->ptr();
1769
2158
    result->type_lengths[i]= tmp->length();
1770
2159
  }
1771
 
 
1772
 
  result->type_names[result->count]= 0;   // End marker
 
2160
  result->type_names[result->count]= 0;         // End marker
1773
2161
  result->type_lengths[result->count]= 0;
1774
 
 
1775
2162
  return result;
1776
2163
}
1777
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
 
1778
2200
        /* Check that the integer is in the internal */
1779
2201
 
1780
2202
int set_zone(register int nr, int min_zone, int max_zone)
1818
2240
 
1819
2241
  for (; pos != end ; pos++)
1820
2242
  {
 
2243
#if defined(USE_MB)
1821
2244
    uint32_t mblen;
1822
2245
    if (use_mb(default_charset_info) &&
1823
2246
        (mblen= my_ismbchar(default_charset_info, pos, end)))
1824
2247
    {
1825
2248
      res->append(pos, mblen);
1826
2249
      pos+= mblen;
1827
 
      if (pos >= end)
1828
 
        break;
1829
2250
      continue;
1830
2251
    }
 
2252
#endif
1831
2253
 
1832
2254
    switch (*pos) {
1833
2255
    case 0:                             /* Must be escaped for 'mysql' */
1859
2281
}
1860
2282
 
1861
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
 
1862
2400
/*
1863
2401
  Set up column usage bitmaps for a temporary table
1864
2402
 
1871
2409
{
1872
2410
  uint32_t field_count= s->fields;
1873
2411
 
1874
 
  this->def_read_set.init((my_bitmap_map*) bitmaps, field_count);
1875
 
  this->tmp_set.init((my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
 
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);
1876
2414
 
1877
2415
  /* write_set and all_set are copies of read_set */
1878
2416
  def_write_set= def_read_set;
1879
2417
  s->all_set= def_read_set;
1880
 
  this->s->all_set.setAll();
 
2418
  bitmap_set_all(&this->s->all_set);
1881
2419
  default_column_bitmaps();
1882
2420
}
1883
2421
 
1884
2422
 
1885
2423
 
1886
 
void Table::updateCreateInfo(message::Table *table_proto)
 
2424
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
1887
2425
{
1888
 
  message::Table::TableOptions *table_options= table_proto->mutable_options();
1889
 
  table_options->set_block_size(s->block_size);
1890
 
  table_options->set_comment(s->getComment());
 
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;
1891
2437
}
1892
2438
 
1893
2439
int rename_file_ext(const char * from,const char * to,const char * ext)
1898
2444
  from_s.append(ext);
1899
2445
  to_s.append(to);
1900
2446
  to_s.append(ext);
1901
 
  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;
1902
2510
}
1903
2511
 
1904
2512
/*
1934
2542
    check_db_name()
1935
2543
    org_name            Name of database and length
1936
2544
 
 
2545
  NOTES
 
2546
    If lower_case_table_names is set then database is converted to lower case
 
2547
 
1937
2548
  RETURN
1938
2549
    0   ok
1939
2550
    1   error
1944
2555
  char *name= org_name->str;
1945
2556
  uint32_t name_length= org_name->length;
1946
2557
 
1947
 
  if (not plugin::Authorization::isAuthorized(current_session->getSecurityContext(),
1948
 
                                              string(name, name_length)))
1949
 
  {
1950
 
    return 1;
1951
 
  }
1952
 
 
1953
2558
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
1954
2559
    return 1;
1955
2560
 
1956
 
  my_casedn_str(files_charset_info, name);
 
2561
  if (lower_case_table_names && name != any_db)
 
2562
    my_casedn_str(files_charset_info, name);
1957
2563
 
1958
2564
  return check_identifier_name(org_name);
1959
2565
}
1960
2566
 
 
2567
 
1961
2568
/*
1962
2569
  Allow anything as a table name, as long as it doesn't contain an
1963
2570
  ' ' at the end
1964
2571
  returns 1 on error
1965
2572
*/
 
2573
 
 
2574
 
1966
2575
bool check_table_name(const char *name, uint32_t length)
1967
2576
{
1968
2577
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
1986
2595
 
1987
2596
  while (*name)
1988
2597
  {
 
2598
#if defined(USE_MB) && defined(USE_MB_IDENT)
1989
2599
    last_char_is_space= my_isspace(system_charset_info, *name);
1990
2600
    if (use_mb(system_charset_info))
1991
2601
    {
2000
2610
        continue;
2001
2611
      }
2002
2612
    }
 
2613
#else
 
2614
    last_char_is_space= *name==' ';
 
2615
#endif
2003
2616
    /*
2004
2617
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
2005
2618
      It is defined as 0xFF, which is a not valid byte in utf8.
2011
2624
    name_length++;
2012
2625
  }
2013
2626
  /* Error if empty or too long column name */
2014
 
  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 *field= this->field[i];
 
2690
 
 
2691
      if (strncmp(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
                        field->field_name);
 
2703
      }
 
2704
      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, _("Incorrect definition of table %s.%s: "
 
2726
                        "expected column '%s' at position %d to have type "
 
2727
                        "%s, found type %s."), s->db.str, alias,
 
2728
                        table_def->name.str, i, table_def->type.str,
 
2729
                        sql_type.c_ptr_safe());
 
2730
        error= true;
 
2731
      }
 
2732
      else if (table_def->cset.str && !field->has_charset())
 
2733
      {
 
2734
        errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
 
2735
                        "expected the type of column '%s' at position %d "
 
2736
                        "to have character set '%s' but the type has no "
 
2737
                        "character set."), s->db.str, alias,
 
2738
                        table_def->name.str, i, table_def->cset.str);
 
2739
        error= true;
 
2740
      }
 
2741
      else if (table_def->cset.str &&
 
2742
               strcmp(field->charset()->csname, table_def->cset.str))
 
2743
      {
 
2744
        errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
 
2745
                        "expected the type of column '%s' at position %d "
 
2746
                        "to have character set '%s' but found "
 
2747
                        "character set '%s'."), s->db.str, alias,
 
2748
                        table_def->name.str, i, table_def->cset.str,
 
2749
                        field->charset()->csname);
 
2750
        error= true;
 
2751
      }
 
2752
    }
 
2753
    else
 
2754
    {
 
2755
      errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
 
2756
                      "expected column '%s' at position %d to have type %s "
 
2757
                      " but the column is not found."),
 
2758
                      s->db.str, alias,
 
2759
                      table_def->name.str, i, table_def->type.str);
 
2760
      error= true;
 
2761
    }
 
2762
  }
 
2763
  return(error);
 
2764
}
 
2765
 
 
2766
 
 
2767
/*
 
2768
  Create Item_field for each column in the table.
 
2769
 
 
2770
  SYNPOSIS
 
2771
    Table::fill_item_list()
 
2772
      item_list          a pointer to an empty list used to store items
 
2773
 
 
2774
  DESCRIPTION
 
2775
    Create Item_field object for each column in the table and
 
2776
    initialize it with the corresponding Field. New items are
 
2777
    created in the current Session memory root.
 
2778
 
 
2779
  RETURN VALUE
 
2780
    0                    success
 
2781
    1                    out of memory
 
2782
*/
 
2783
 
 
2784
bool Table::fill_item_list(List<Item> *item_list) const
 
2785
{
 
2786
  /*
 
2787
    All Item_field's created using a direct pointer to a field
 
2788
    are fixed in Item_field constructor.
 
2789
  */
 
2790
  for (Field **ptr= field; *ptr; ptr++)
 
2791
  {
 
2792
    Item_field *item= new Item_field(*ptr);
 
2793
    if (!item || item_list->push_back(item))
 
2794
      return true;
 
2795
  }
 
2796
  return false;
 
2797
}
 
2798
 
 
2799
/*
 
2800
  Reset an existing list of Item_field items to point to the
 
2801
  Fields of this table.
 
2802
 
 
2803
  SYNPOSIS
 
2804
    Table::fill_item_list()
 
2805
      item_list          a non-empty list with Item_fields
 
2806
 
 
2807
  DESCRIPTION
 
2808
    This is a counterpart of fill_item_list used to redirect
 
2809
    Item_fields to the fields of a newly created table.
 
2810
    The caller must ensure that number of items in the item_list
 
2811
    is the same as the number of columns in the table.
 
2812
*/
 
2813
 
 
2814
void Table::reset_item_list(List<Item> *item_list) const
 
2815
{
 
2816
  List_iterator_fast<Item> it(*item_list);
 
2817
  for (Field **ptr= field; *ptr; ptr++)
 
2818
  {
 
2819
    Item_field *item_field= (Item_field*) it++;
 
2820
    assert(item_field != 0);
 
2821
    item_field->reset_field(*ptr);
 
2822
  }
 
2823
}
 
2824
 
 
2825
 
 
2826
/*
 
2827
  Find underlying base tables (TableList) which represent given
 
2828
  table_to_find (Table)
 
2829
 
 
2830
  SYNOPSIS
 
2831
    TableList::find_underlying_table()
 
2832
    table_to_find table to find
 
2833
 
 
2834
  RETURN
 
2835
    0  table is not found
 
2836
    found table reference
 
2837
*/
 
2838
 
 
2839
TableList *TableList::find_underlying_table(Table *table_to_find)
 
2840
{
 
2841
  /* is this real table and table which we are looking for? */
 
2842
  if (table == table_to_find && merge_underlying_list == 0)
 
2843
    return this;
 
2844
 
 
2845
  for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
 
2846
  {
 
2847
    TableList *result;
 
2848
    if ((result= tbl->find_underlying_table(table_to_find)))
 
2849
      return result;
 
2850
  }
 
2851
  return 0;
 
2852
}
 
2853
 
 
2854
/*
 
2855
  cleunup items belonged to view fields translation table
 
2856
 
 
2857
  SYNOPSIS
 
2858
    TableList::cleanup_items()
 
2859
*/
 
2860
 
 
2861
void TableList::cleanup_items()
 
2862
{
 
2863
}
 
2864
 
 
2865
 
 
2866
bool TableList::placeholder()
 
2867
{
 
2868
  return derived || schema_table || (create && !table->getDBStat()) || !table;
 
2869
}
 
2870
 
 
2871
 
 
2872
/*
 
2873
  Set insert_values buffer
 
2874
 
 
2875
  SYNOPSIS
 
2876
    set_insert_values()
 
2877
    mem_root   memory pool for allocating
 
2878
 
 
2879
  RETURN
 
2880
    false - OK
 
2881
    TRUE  - out of memory
 
2882
*/
 
2883
 
 
2884
bool TableList::set_insert_values(MEM_ROOT *mem_root)
 
2885
{
 
2886
  if (table)
 
2887
  {
 
2888
    if (!table->insert_values &&
 
2889
        !(table->insert_values= (unsigned char *)alloc_root(mem_root,
 
2890
                                                   table->s->rec_buff_length)))
 
2891
      return true;
 
2892
  }
 
2893
 
 
2894
  return false;
 
2895
}
 
2896
 
 
2897
 
 
2898
/*
 
2899
  Test if this is a leaf with respect to name resolution.
 
2900
 
 
2901
  SYNOPSIS
 
2902
    TableList::is_leaf_for_name_resolution()
 
2903
 
 
2904
  DESCRIPTION
 
2905
    A table reference is a leaf with respect to name resolution if
 
2906
    it is either a leaf node in a nested join tree (table, view,
 
2907
    schema table, subquery), or an inner node that represents a
 
2908
    NATURAL/USING join, or a nested join with materialized join
 
2909
    columns.
 
2910
 
 
2911
  RETURN
 
2912
    TRUE if a leaf, false otherwise.
 
2913
*/
 
2914
bool TableList::is_leaf_for_name_resolution()
 
2915
{
 
2916
  return (is_natural_join || is_join_columns_complete || !nested_join);
 
2917
}
 
2918
 
 
2919
 
 
2920
/*
 
2921
  Retrieve the first (left-most) leaf in a nested join tree with
 
2922
  respect to name resolution.
 
2923
 
 
2924
  SYNOPSIS
 
2925
    TableList::first_leaf_for_name_resolution()
 
2926
 
 
2927
  DESCRIPTION
 
2928
    Given that 'this' is a nested table reference, recursively walk
 
2929
    down the left-most children of 'this' until we reach a leaf
 
2930
    table reference with respect to name resolution.
 
2931
 
 
2932
  IMPLEMENTATION
 
2933
    The left-most child of a nested table reference is the last element
 
2934
    in the list of children because the children are inserted in
 
2935
    reverse order.
 
2936
 
 
2937
  RETURN
 
2938
    If 'this' is a nested table reference - the left-most child of
 
2939
      the tree rooted in 'this',
 
2940
    else return 'this'
 
2941
*/
 
2942
 
 
2943
TableList *TableList::first_leaf_for_name_resolution()
 
2944
{
 
2945
  TableList *cur_table_ref= NULL;
 
2946
  nested_join_st *cur_nested_join;
 
2947
 
 
2948
  if (is_leaf_for_name_resolution())
 
2949
    return this;
 
2950
  assert(nested_join);
 
2951
 
 
2952
  for (cur_nested_join= nested_join;
 
2953
       cur_nested_join;
 
2954
       cur_nested_join= cur_table_ref->nested_join)
 
2955
  {
 
2956
    List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
2957
    cur_table_ref= it++;
 
2958
    /*
 
2959
      If the current nested join is a RIGHT JOIN, the operands in
 
2960
      'join_list' are in reverse order, thus the first operand is
 
2961
      already at the front of the list. Otherwise the first operand
 
2962
      is in the end of the list of join operands.
 
2963
    */
 
2964
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
2965
    {
 
2966
      TableList *next;
 
2967
      while ((next= it++))
 
2968
        cur_table_ref= next;
 
2969
    }
 
2970
    if (cur_table_ref->is_leaf_for_name_resolution())
 
2971
      break;
 
2972
  }
 
2973
  return cur_table_ref;
 
2974
}
 
2975
 
 
2976
 
 
2977
/*
 
2978
  Retrieve the last (right-most) leaf in a nested join tree with
 
2979
  respect to name resolution.
 
2980
 
 
2981
  SYNOPSIS
 
2982
    TableList::last_leaf_for_name_resolution()
 
2983
 
 
2984
  DESCRIPTION
 
2985
    Given that 'this' is a nested table reference, recursively walk
 
2986
    down the right-most children of 'this' until we reach a leaf
 
2987
    table reference with respect to name resolution.
 
2988
 
 
2989
  IMPLEMENTATION
 
2990
    The right-most child of a nested table reference is the first
 
2991
    element in the list of children because the children are inserted
 
2992
    in reverse order.
 
2993
 
 
2994
  RETURN
 
2995
    - If 'this' is a nested table reference - the right-most child of
 
2996
      the tree rooted in 'this',
 
2997
    - else - 'this'
 
2998
*/
 
2999
 
 
3000
TableList *TableList::last_leaf_for_name_resolution()
 
3001
{
 
3002
  TableList *cur_table_ref= this;
 
3003
  nested_join_st *cur_nested_join;
 
3004
 
 
3005
  if (is_leaf_for_name_resolution())
 
3006
    return this;
 
3007
  assert(nested_join);
 
3008
 
 
3009
  for (cur_nested_join= nested_join;
 
3010
       cur_nested_join;
 
3011
       cur_nested_join= cur_table_ref->nested_join)
 
3012
  {
 
3013
    cur_table_ref= cur_nested_join->join_list.head();
 
3014
    /*
 
3015
      If the current nested is a RIGHT JOIN, the operands in
 
3016
      'join_list' are in reverse order, thus the last operand is in the
 
3017
      end of the list.
 
3018
    */
 
3019
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
3020
    {
 
3021
      List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
3022
      TableList *next;
 
3023
      cur_table_ref= it++;
 
3024
      while ((next= it++))
 
3025
        cur_table_ref= next;
 
3026
    }
 
3027
    if (cur_table_ref->is_leaf_for_name_resolution())
 
3028
      break;
 
3029
  }
 
3030
  return cur_table_ref;
2015
3031
}
2016
3032
 
2017
3033
 
2028
3044
    bitmap_clear_all(&table->def_read_set);
2029
3045
    bitmap_clear_all(&table->def_write_set);
2030
3046
  */
2031
 
  def_read_set.clearAll();
2032
 
  def_write_set.clearAll();
 
3047
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
2033
3048
  column_bitmaps_set(&def_read_set, &def_write_set);
2034
3049
}
2035
3050
 
2036
3051
 
2037
3052
/*
2038
 
  Tell Cursor we are going to call position() and rnd_pos() later.
 
3053
  Tell handler we are going to call position() and rnd_pos() later.
2039
3054
 
2040
3055
  NOTES:
2041
3056
  This is needed for handlers that uses the primary key to find the
2046
3061
void Table::prepare_for_position()
2047
3062
{
2048
3063
 
2049
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
 
3064
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
2050
3065
      s->primary_key < MAX_KEY)
2051
3066
  {
2052
 
    mark_columns_used_by_index_no_reset(s->primary_key);
 
3067
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3068
    /* signal change */
 
3069
    file->column_bitmaps_signal();
2053
3070
  }
2054
3071
  return;
2055
3072
}
2067
3084
 
2068
3085
void Table::mark_columns_used_by_index(uint32_t index)
2069
3086
{
2070
 
  MyBitmap *bitmap= &tmp_set;
 
3087
  MY_BITMAP *bitmap= &tmp_set;
2071
3088
 
2072
 
  (void) cursor->extra(HA_EXTRA_KEYREAD);
2073
 
  bitmap->clearAll();
 
3089
  (void) file->extra(HA_EXTRA_KEYREAD);
 
3090
  bitmap_clear_all(bitmap);
2074
3091
  mark_columns_used_by_index_no_reset(index, bitmap);
2075
3092
  column_bitmaps_set(bitmap, bitmap);
2076
3093
  return;
2092
3109
{
2093
3110
 
2094
3111
  key_read= 0;
2095
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3112
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
2096
3113
  default_column_bitmaps();
 
3114
  file->column_bitmaps_signal();
2097
3115
  return;
2098
3116
}
2099
3117
 
2102
3120
  mark columns used by key, but don't reset other fields
2103
3121
*/
2104
3122
 
2105
 
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
2106
 
{
2107
 
    mark_columns_used_by_index_no_reset(index, read_set);
2108
 
}
2109
 
 
2110
3123
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
2111
 
                                                MyBitmap *bitmap)
 
3124
                                                   MY_BITMAP *bitmap)
2112
3125
{
2113
3126
  KEY_PART_INFO *key_part= key_info[index].key_part;
2114
3127
  KEY_PART_INFO *key_part_end= (key_part +
2115
3128
                                key_info[index].key_parts);
2116
3129
  for (;key_part != key_part_end; key_part++)
2117
 
    bitmap->setBit(key_part->fieldnr-1);
 
3130
  {
 
3131
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
 
3132
    if (key_part->field->vcol_info &&
 
3133
        key_part->field->vcol_info->expr_item)
 
3134
      key_part->field->vcol_info->
 
3135
               expr_item->walk(&Item::register_field_in_bitmap,
 
3136
                               1, (unsigned char *) bitmap);
 
3137
  }
2118
3138
}
2119
3139
 
2120
3140
 
2133
3153
    We must set bit in read set as update_auto_increment() is using the
2134
3154
    store() to check overflow of auto_increment values
2135
3155
  */
2136
 
  setReadSet(found_next_number_field->field_index);
2137
 
  setWriteSet(found_next_number_field->field_index);
 
3156
  bitmap_set_bit(read_set, found_next_number_field->field_index);
 
3157
  bitmap_set_bit(write_set, found_next_number_field->field_index);
2138
3158
  if (s->next_number_keypart)
2139
 
    mark_columns_used_by_index_no_reset(s->next_number_index);
 
3159
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
 
3160
  file->column_bitmaps_signal();
2140
3161
}
2141
3162
 
2142
3163
 
2160
3181
 
2161
3182
void Table::mark_columns_needed_for_delete()
2162
3183
{
2163
 
  /*
2164
 
    If the Cursor has no cursor capabilites, or we have row-based
2165
 
    replication active for the current statement, we have to read
2166
 
    either the primary key, the hidden primary key or all columns to
2167
 
    be able to do an delete
2168
 
 
2169
 
  */
2170
 
  if (s->primary_key == MAX_KEY)
2171
 
  {
2172
 
    /* fallback to use all columns in the table to identify row */
2173
 
    use_all_columns();
2174
 
    return;
2175
 
  }
2176
 
  else
2177
 
    mark_columns_used_by_index_no_reset(s->primary_key);
2178
 
 
2179
 
  /* If we the engine wants all predicates we mark all keys */
2180
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
3184
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2181
3185
  {
2182
3186
    Field **reg_field;
2183
3187
    for (reg_field= field ; *reg_field ; reg_field++)
2184
3188
    {
2185
3189
      if ((*reg_field)->flags & PART_KEY_FLAG)
2186
 
        setReadSet((*reg_field)->field_index);
 
3190
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
3191
    }
 
3192
    file->column_bitmaps_signal();
 
3193
  }
 
3194
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE || (drizzle_bin_log.is_open() && in_use))
 
3195
  {
 
3196
    /*
 
3197
      If the handler has no cursor capabilites, or we have row-based
 
3198
      replication active for the current statement, we have to read
 
3199
      either the primary key, the hidden primary key or all columns to
 
3200
      be able to do an delete
 
3201
    */
 
3202
    if (s->primary_key == MAX_KEY)
 
3203
      file->use_hidden_primary_key();
 
3204
    else
 
3205
    {
 
3206
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3207
      file->column_bitmaps_signal();
2187
3208
    }
2188
3209
  }
2189
3210
}
2201
3222
    if neeed, either the primary key column or all columns to be read.
2202
3223
    (see mark_columns_needed_for_delete() for details)
2203
3224
 
2204
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
3225
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
2205
3226
    mark all USED key columns as 'to-be-read'. This allows the engine to
2206
3227
    loop over the given record to find all changed keys and doesn't have to
2207
3228
    retrieve the row again.
2209
3230
 
2210
3231
void Table::mark_columns_needed_for_update()
2211
3232
{
2212
 
  /*
2213
 
    If the Cursor has no cursor capabilites, or we have row-based
2214
 
    logging active for the current statement, we have to read either
2215
 
    the primary key, the hidden primary key or all columns to be
2216
 
    able to do an update
2217
 
  */
2218
 
  if (s->primary_key == MAX_KEY)
2219
 
  {
2220
 
    /* fallback to use all columns in the table to identify row */
2221
 
    use_all_columns();
2222
 
    return;
2223
 
  }
2224
 
  else
2225
 
    mark_columns_used_by_index_no_reset(s->primary_key);
2226
 
 
2227
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
3233
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2228
3234
  {
2229
3235
    /* Mark all used key columns for read */
2230
3236
    Field **reg_field;
2231
3237
    for (reg_field= field ; *reg_field ; reg_field++)
2232
3238
    {
2233
3239
      /* Merge keys is all keys that had a column refered to in the query */
2234
 
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
2235
 
        setReadSet((*reg_field)->field_index);
2236
 
    }
2237
 
  }
2238
 
 
 
3240
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
 
3241
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
3242
    }
 
3243
    file->column_bitmaps_signal();
 
3244
  }
 
3245
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) ||
 
3246
      (drizzle_bin_log.is_open() && in_use))
 
3247
  {
 
3248
    /*
 
3249
      If the handler has no cursor capabilites, or we have row-based
 
3250
      logging active for the current statement, we have to read either
 
3251
      the primary key, the hidden primary key or all columns to be
 
3252
      able to do an update
 
3253
    */
 
3254
    if (s->primary_key == MAX_KEY)
 
3255
      file->use_hidden_primary_key();
 
3256
    else
 
3257
    {
 
3258
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3259
      file->column_bitmaps_signal();
 
3260
    }
 
3261
  }
 
3262
  /* Mark all virtual columns as writable */
 
3263
  mark_virtual_columns();
 
3264
  return;
2239
3265
}
2240
3266
 
2241
3267
 
2242
3268
/*
2243
 
  Mark columns the Cursor needs for doing an insert
 
3269
  Mark columns the handler needs for doing an insert
2244
3270
 
2245
3271
  For now, this is used to mark fields used by the trigger
2246
3272
  as changed.
2250
3276
{
2251
3277
  if (found_next_number_field)
2252
3278
    mark_auto_increment_column();
2253
 
}
2254
 
 
 
3279
  /* Mark all virtual columns as writable */
 
3280
  mark_virtual_columns();
 
3281
}
 
3282
 
 
3283
/*
 
3284
  @brief Update the write and read table bitmap to allow
 
3285
         using procedure save_in_field for all virtual columns
 
3286
         in the table.
 
3287
 
 
3288
  @return       void
 
3289
 
 
3290
  @detail
 
3291
    Each virtual field is set in the write column map.
 
3292
    All fields that the virtual columns are based on are set in the
 
3293
    read bitmap.
 
3294
*/
 
3295
 
 
3296
void Table::mark_virtual_columns(void)
 
3297
{
 
3298
  Field **vfield_ptr, *tmp_vfield;
 
3299
  bool bitmap_updated= false;
 
3300
 
 
3301
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
 
3302
  {
 
3303
    tmp_vfield= *vfield_ptr;
 
3304
    assert(tmp_vfield->vcol_info && tmp_vfield->vcol_info->expr_item);
 
3305
    tmp_vfield->vcol_info->expr_item->walk(&Item::register_field_in_read_map,
 
3306
                                           1, (unsigned char *) 0);
 
3307
    bitmap_set_bit(read_set, tmp_vfield->field_index);
 
3308
    bitmap_set_bit(write_set, tmp_vfield->field_index);
 
3309
    bitmap_updated= true;
 
3310
  }
 
3311
  if (bitmap_updated)
 
3312
    file->column_bitmaps_signal();
 
3313
}
 
3314
 
 
3315
 
 
3316
/*
 
3317
  Cleanup this table for re-execution.
 
3318
 
 
3319
  SYNOPSIS
 
3320
    TableList::reinit_before_use()
 
3321
*/
 
3322
 
 
3323
void TableList::reinit_before_use(Session *session)
 
3324
{
 
3325
  /*
 
3326
    Reset old pointers to TABLEs: they are not valid since the tables
 
3327
    were closed in the end of previous prepare or execute call.
 
3328
  */
 
3329
  table= 0;
 
3330
  /* Reset is_schema_table_processed value(needed for I_S tables */
 
3331
  schema_table_state= NOT_PROCESSED;
 
3332
 
 
3333
  TableList *embedded; /* The table at the current level of nesting. */
 
3334
  TableList *parent_embedding= this; /* The parent nested table reference. */
 
3335
  do
 
3336
  {
 
3337
    embedded= parent_embedding;
 
3338
    if (embedded->prep_on_expr)
 
3339
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
 
3340
    parent_embedding= embedded->embedding;
 
3341
  }
 
3342
  while (parent_embedding &&
 
3343
         parent_embedding->nested_join->join_list.head() == embedded);
 
3344
}
 
3345
 
 
3346
/*
 
3347
  Return subselect that contains the FROM list this table is taken from
 
3348
 
 
3349
  SYNOPSIS
 
3350
    TableList::containing_subselect()
 
3351
 
 
3352
  RETURN
 
3353
    Subselect item for the subquery that contains the FROM list
 
3354
    this table is taken from if there is any
 
3355
    0 - otherwise
 
3356
 
 
3357
*/
 
3358
 
 
3359
Item_subselect *TableList::containing_subselect()
 
3360
{
 
3361
  return (select_lex ? select_lex->master_unit()->item : 0);
 
3362
}
 
3363
 
 
3364
/*
 
3365
  Compiles the tagged hints list and fills up the bitmasks.
 
3366
 
 
3367
  SYNOPSIS
 
3368
    process_index_hints()
 
3369
      table         the Table to operate on.
 
3370
 
 
3371
  DESCRIPTION
 
3372
    The parser collects the index hints for each table in a "tagged list"
 
3373
    (TableList::index_hints). Using the information in this tagged list
 
3374
    this function sets the members Table::keys_in_use_for_query,
 
3375
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
 
3376
    Table::force_index and Table::covering_keys.
 
3377
 
 
3378
    Current implementation of the runtime does not allow mixing FORCE INDEX
 
3379
    and USE INDEX, so this is checked here. Then the FORCE INDEX list
 
3380
    (if non-empty) is appended to the USE INDEX list and a flag is set.
 
3381
 
 
3382
    Multiple hints of the same kind are processed so that each clause
 
3383
    is applied to what is computed in the previous clause.
 
3384
    For example:
 
3385
        USE INDEX (i1) USE INDEX (i2)
 
3386
    is equivalent to
 
3387
        USE INDEX (i1,i2)
 
3388
    and means "consider only i1 and i2".
 
3389
 
 
3390
    Similarly
 
3391
        USE INDEX () USE INDEX (i1)
 
3392
    is equivalent to
 
3393
        USE INDEX (i1)
 
3394
    and means "consider only the index i1"
 
3395
 
 
3396
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
 
3397
    not an error.
 
3398
 
 
3399
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
 
3400
    order:
 
3401
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
 
3402
      2. All IGNORE INDEX
 
3403
 
 
3404
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
 
3405
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
 
3406
 
 
3407
    As an optimization if there is a covering index, and we have
 
3408
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
 
3409
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
 
3410
 
 
3411
  RETURN VALUE
 
3412
    false                no errors found
 
3413
    TRUE                 found and reported an error.
 
3414
*/
 
3415
bool TableList::process_index_hints(Table *tbl)
 
3416
{
 
3417
  /* initialize the result variables */
 
3418
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
 
3419
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
 
3420
 
 
3421
  /* index hint list processing */
 
3422
  if (index_hints)
 
3423
  {
 
3424
    key_map index_join[INDEX_HINT_FORCE + 1];
 
3425
    key_map index_order[INDEX_HINT_FORCE + 1];
 
3426
    key_map index_group[INDEX_HINT_FORCE + 1];
 
3427
    Index_hint *hint;
 
3428
    int type;
 
3429
    bool have_empty_use_join= false, have_empty_use_order= false,
 
3430
         have_empty_use_group= false;
 
3431
    List_iterator <Index_hint> iter(*index_hints);
 
3432
 
 
3433
    /* initialize temporary variables used to collect hints of each kind */
 
3434
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
 
3435
    {
 
3436
      index_join[type].clear_all();
 
3437
      index_order[type].clear_all();
 
3438
      index_group[type].clear_all();
 
3439
    }
 
3440
 
 
3441
    /* iterate over the hints list */
 
3442
    while ((hint= iter++))
 
3443
    {
 
3444
      uint32_t pos;
 
3445
 
 
3446
      /* process empty USE INDEX () */
 
3447
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
 
3448
      {
 
3449
        if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3450
        {
 
3451
          index_join[hint->type].clear_all();
 
3452
          have_empty_use_join= true;
 
3453
        }
 
3454
        if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3455
        {
 
3456
          index_order[hint->type].clear_all();
 
3457
          have_empty_use_order= true;
 
3458
        }
 
3459
        if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3460
        {
 
3461
          index_group[hint->type].clear_all();
 
3462
          have_empty_use_group= true;
 
3463
        }
 
3464
        continue;
 
3465
      }
 
3466
 
 
3467
      /*
 
3468
        Check if an index with the given name exists and get his offset in
 
3469
        the keys bitmask for the table
 
3470
      */
 
3471
      if (tbl->s->keynames.type_names == 0 ||
 
3472
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
 
3473
                          hint->key_name.length, 1)) <= 0)
 
3474
      {
 
3475
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
 
3476
        return 1;
 
3477
      }
 
3478
 
 
3479
      pos--;
 
3480
 
 
3481
      /* add to the appropriate clause mask */
 
3482
      if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3483
        index_join[hint->type].set_bit (pos);
 
3484
      if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3485
        index_order[hint->type].set_bit (pos);
 
3486
      if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3487
        index_group[hint->type].set_bit (pos);
 
3488
    }
 
3489
 
 
3490
    /* cannot mix USE INDEX and FORCE INDEX */
 
3491
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3492
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3493
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
 
3494
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
 
3495
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
 
3496
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
 
3497
    {
 
3498
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
 
3499
               index_hint_type_name[INDEX_HINT_FORCE]);
 
3500
      return 1;
 
3501
    }
 
3502
 
 
3503
    /* process FORCE INDEX as USE INDEX with a flag */
 
3504
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3505
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3506
        !index_group[INDEX_HINT_FORCE].is_clear_all())
 
3507
    {
 
3508
      tbl->force_index= true;
 
3509
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
 
3510
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
 
3511
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
 
3512
    }
 
3513
 
 
3514
    /* apply USE INDEX */
 
3515
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
 
3516
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
 
3517
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
 
3518
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
 
3519
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
 
3520
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
 
3521
 
 
3522
    /* apply IGNORE INDEX */
 
3523
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
 
3524
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
 
3525
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
 
3526
  }
 
3527
 
 
3528
  /* make sure covering_keys don't include indexes disabled with a hint */
 
3529
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
 
3530
  return 0;
 
3531
}
2255
3532
 
2256
3533
 
2257
3534
size_t Table::max_row_length(const unsigned char *data)
2281
3558
/**
2282
3559
  Create field for temporary table from given field.
2283
3560
 
2284
 
  @param session               Thread Cursor
 
3561
  @param session               Thread handler
2285
3562
  @param org_field    field from which new field will be created
2286
3563
  @param name         New field name
2287
3564
  @param table         Temporary table
2340
3617
 
2341
3618
 
2342
3619
/**
 
3620
  Create field for information schema table.
 
3621
 
 
3622
  @param session                Thread handler
 
3623
  @param table          Temporary table
 
3624
  @param item           Item to create a field for
 
3625
 
 
3626
  @retval
 
3627
    0                   on error
 
3628
  @retval
 
3629
    new_created field
 
3630
*/
 
3631
 
 
3632
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
 
3633
{
 
3634
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
3635
  {
 
3636
    Field *field;
 
3637
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
3638
      field= new Field_blob(item->max_length, item->maybe_null,
 
3639
                            item->name, item->collation.collation);
 
3640
    else
 
3641
      field= new Field_varstring(item->max_length, item->maybe_null,
 
3642
                                 item->name,
 
3643
                                 table->s, item->collation.collation);
 
3644
    if (field)
 
3645
      field->init(table);
 
3646
    return field;
 
3647
  }
 
3648
  return item->tmp_table_field_from_field_type(table, 0);
 
3649
}
 
3650
 
 
3651
 
 
3652
/**
2343
3653
  Create a temp table according to a field list.
2344
3654
 
2345
3655
  Given field pointers are changed to point at tmp_table for
2369
3679
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
2370
3680
#define RATIO_TO_PACK_ROWS             2
2371
3681
 
2372
 
static void make_internal_temporary_table_path(Session *session, char *path)
2373
 
{
2374
 
  snprintf(path, FN_REFLEN, "%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
2375
 
           session->thread_id, session->tmp_table++);
2376
 
 
2377
 
  internal::fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
2378
 
}
2379
 
 
2380
3682
Table *
2381
 
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
 
3683
create_tmp_table(Session *session,TMP_TABLE_PARAM *param,List<Item> &fields,
2382
3684
                 order_st *group, bool distinct, bool save_sum_fields,
2383
3685
                 uint64_t select_options, ha_rows rows_limit,
2384
 
                 const char *table_alias)
 
3686
                 char *table_alias)
2385
3687
{
2386
 
  memory::Root *mem_root_save, own_root;
 
3688
  MEM_ROOT *mem_root_save, own_root;
2387
3689
  Table *table;
2388
 
  TableShare *share;
 
3690
  TABLE_SHARE *share;
2389
3691
  uint  i,field_count,null_count,null_pack_length;
2390
3692
  uint32_t  copy_func_count= param->func_count;
2391
3693
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
2392
3694
  uint32_t  blob_count,group_null_items, string_count;
 
3695
  uint32_t  temp_pool_slot=MY_BIT_NONE;
2393
3696
  uint32_t fieldnr= 0;
2394
3697
  ulong reclength, string_total_length;
2395
 
  bool  using_unique_constraint= false;
2396
 
  bool  use_packed_rows= true;
 
3698
  bool  using_unique_constraint= 0;
 
3699
  bool  use_packed_rows= 0;
2397
3700
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
2398
 
  char  *tmpname;
2399
 
  char  path[FN_REFLEN];
 
3701
  char  *tmpname,path[FN_REFLEN];
2400
3702
  unsigned char *pos, *group_buff, *bitmaps;
2401
3703
  unsigned char *null_flags;
2402
3704
  Field **reg_field, **from_field, **default_field;
2403
3705
  uint32_t *blob_field;
2404
 
  CopyField *copy= 0;
 
3706
  Copy_field *copy=0;
2405
3707
  KEY *keyinfo;
2406
3708
  KEY_PART_INFO *key_part_info;
2407
3709
  Item **copy_func;
2408
3710
  MI_COLUMNDEF *recinfo;
2409
3711
  uint32_t total_uneven_bit_length= 0;
2410
3712
  bool force_copy_fields= param->force_copy_fields;
2411
 
  uint64_t max_rows= 0;
2412
3713
 
2413
3714
  status_var_increment(session->status_var.created_tmp_tables);
2414
3715
 
2415
 
  make_internal_temporary_table_path(session, path);
 
3716
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
 
3717
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
 
3718
 
 
3719
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
 
3720
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
 
3721
            (unsigned long)current_pid, temp_pool_slot);
 
3722
  else
 
3723
  {
 
3724
    /* if we run out of slots or we are not using tempool */
 
3725
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
3726
            session->thread_id, session->tmp_table++);
 
3727
  }
 
3728
 
 
3729
  /*
 
3730
    No need to change table name to lower case as we are only creating
 
3731
    MyISAM or HEAP tables here
 
3732
  */
 
3733
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3734
 
2416
3735
 
2417
3736
  if (group)
2418
3737
  {
2419
 
    if (! param->quick_group)
2420
 
      group= 0;                                 // Can't use group key
 
3738
    if (!param->quick_group)
 
3739
      group=0;                                  // Can't use group key
2421
3740
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
2422
3741
    {
2423
3742
      /*
2428
3747
      */
2429
3748
      (*tmp->item)->marker= 4;
2430
3749
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
2431
 
        using_unique_constraint= true;
 
3750
        using_unique_constraint=1;
2432
3751
    }
2433
3752
    if (param->group_length >= MAX_BLOB_WIDTH)
2434
 
      using_unique_constraint= true;
 
3753
      using_unique_constraint=1;
2435
3754
    if (group)
2436
 
      distinct= 0;                              // Can't use distinct
 
3755
      distinct=0;                               // Can't use distinct
2437
3756
  }
2438
3757
 
2439
3758
  field_count=param->field_count+param->func_count+param->sum_func_count;
2443
3762
    When loose index scan is employed as access method, it already
2444
3763
    computes all groups and the result of all aggregate functions. We
2445
3764
    make space for the items of the aggregate function in the list of
2446
 
    functions Tmp_Table_Param::items_to_copy, so that the values of
 
3765
    functions TMP_TABLE_PARAM::items_to_copy, so that the values of
2447
3766
    these items are stored in the temporary table.
2448
3767
  */
2449
3768
  if (param->precomputed_group_by)
2450
3769
    copy_func_count+= param->sum_func_count;
2451
3770
 
2452
 
  memory::init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
3771
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
2453
3772
 
2454
3773
  if (!multi_alloc_root(&own_root,
2455
3774
                        &table, sizeof(*table),
2456
3775
                        &share, sizeof(*share),
2457
3776
                        &reg_field, sizeof(Field*) * (field_count+1),
2458
3777
                        &default_field, sizeof(Field*) * (field_count),
2459
 
                        &blob_field, sizeof(uint32_t)*(field_count+1),
 
3778
                        &blob_field, sizeof(uint)*(field_count+1),
2460
3779
                        &from_field, sizeof(Field*)*field_count,
2461
3780
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
2462
3781
                        &param->keyinfo, sizeof(*param->keyinfo),
2464
3783
                        sizeof(*key_part_info)*(param->group_parts+1),
2465
3784
                        &param->start_recinfo,
2466
3785
                        sizeof(*param->recinfo)*(field_count*2+4),
2467
 
                        &tmpname, (uint32_t) strlen(path)+1,
 
3786
                        &tmpname, (uint) strlen(path)+1,
2468
3787
                        &group_buff, (group && ! using_unique_constraint ?
2469
3788
                                      param->group_length : 0),
2470
3789
                        &bitmaps, bitmap_buffer_size(field_count)*2,
2471
3790
                        NULL))
2472
3791
  {
2473
 
    return NULL;
 
3792
    if (temp_pool_slot != MY_BIT_NONE)
 
3793
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3794
    return(NULL);                               /* purecov: inspected */
2474
3795
  }
2475
 
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
2476
 
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
 
3796
  /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in Session mem_root */
 
3797
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
2477
3798
  {
2478
 
    free_root(&own_root, MYF(0));
2479
 
    return NULL;
 
3799
    if (temp_pool_slot != MY_BIT_NONE)
 
3800
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3801
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
3802
    return(NULL);                               /* purecov: inspected */
2480
3803
  }
2481
3804
  param->items_to_copy= copy_func;
2482
3805
  strcpy(tmpname,path);
2496
3819
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
2497
3820
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
2498
3821
  table->map=1;
 
3822
  table->temp_pool_slot = temp_pool_slot;
2499
3823
  table->copy_blobs= 1;
2500
3824
  table->in_use= session;
2501
 
  table->quick_keys.reset();
2502
 
  table->covering_keys.reset();
2503
 
  table->keys_in_use_for_query.reset();
 
3825
  table->quick_keys.init();
 
3826
  table->covering_keys.init();
 
3827
  table->keys_in_use_for_query.init();
2504
3828
 
2505
3829
  table->setShare(share);
2506
 
  share->init(tmpname, tmpname);
 
3830
  init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
2507
3831
  share->blob_field= blob_field;
2508
3832
  share->blob_ptr_size= portable_sizeof_char_ptr;
2509
3833
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
2510
3834
  share->table_charset= param->table_charset;
2511
3835
  share->primary_key= MAX_KEY;               // Indicate no primary key
2512
 
  share->keys_for_keyread.reset();
2513
 
  share->keys_in_use.reset();
 
3836
  share->keys_for_keyread.init();
 
3837
  share->keys_in_use.init();
2514
3838
 
2515
3839
  /* Calculate which type of fields we will store in the temporary table */
2516
3840
 
2517
3841
  reclength= string_total_length= 0;
2518
3842
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
2519
 
  param->using_indirect_summary_function= 0;
 
3843
  param->using_indirect_summary_function=0;
2520
3844
 
2521
3845
  List_iterator_fast<Item> li(fields);
2522
3846
  Item *item;
2547
3871
    }
2548
3872
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
2549
3873
    {                                           /* Can't calc group yet */
2550
 
      ((Item_sum*) item)->result_field= 0;
2551
 
      for (i= 0 ; i < ((Item_sum*) item)->arg_count ; i++)
 
3874
      ((Item_sum*) item)->result_field=0;
 
3875
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
2552
3876
      {
2553
3877
        Item **argp= ((Item_sum*) item)->args + i;
2554
3878
        Item *arg= *argp;
2558
3882
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
2559
3883
                             tmp_from_field, &default_field[fieldnr],
2560
3884
                             group != 0,not_all_columns,
2561
 
                             false,
 
3885
                             distinct, 0,
2562
3886
                             param->convert_blob_length);
2563
3887
          if (!new_field)
2564
3888
            goto err;                                   // Should be OOM
2603
3927
        We here distinguish between UNION and multi-table-updates by the fact
2604
3928
        that in the later case group is set to the row pointer.
2605
3929
      */
2606
 
      Field *new_field=
 
3930
      Field *new_field= (param->schema_table) ?
 
3931
        create_tmp_field_for_schema(session, item, table) :
2607
3932
        create_tmp_field(session, table, item, type, &copy_func,
2608
3933
                         tmp_from_field, &default_field[fieldnr],
2609
3934
                         group != 0,
2610
3935
                         !force_copy_fields &&
2611
 
                           (not_all_columns || group != 0),
 
3936
                           (not_all_columns || group !=0),
 
3937
                         /*
 
3938
                           If item->marker == 4 then we force create_tmp_field
 
3939
                           to create a 64-bit longs for BIT fields because HEAP
 
3940
                           tables can't index BIT fields directly. We do the same
 
3941
                           for distinct, as we want the distinct index to be
 
3942
                           usable in this case too.
 
3943
                         */
 
3944
                         item->marker == 4 || param->bit_fields_as_long,
2612
3945
                         force_copy_fields,
2613
3946
                         param->convert_blob_length);
2614
3947
 
2652
3985
      null_count= 0;
2653
3986
    }
2654
3987
  }
2655
 
  assert(fieldnr == (uint32_t) (reg_field - table->field));
2656
 
  assert(field_count >= (uint32_t) (reg_field - table->field));
 
3988
  assert(fieldnr == (uint) (reg_field - table->field));
 
3989
  assert(field_count >= (uint) (reg_field - table->field));
2657
3990
  field_count= fieldnr;
2658
3991
  *reg_field= 0;
2659
3992
  *blob_field= 0;                               // End marker
2662
3995
  /* If result table is small; use a heap */
2663
3996
  /* future: storage engine selection can be made dynamic? */
2664
3997
  if (blob_count || using_unique_constraint ||
2665
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
 
3998
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
3999
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
2666
4000
  {
2667
 
    share->storage_engine= myisam_engine;
2668
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
4001
    share->db_plugin= ha_lock_engine(0, myisam_hton);
 
4002
    table->file= get_new_handler(share, &table->mem_root,
 
4003
                                 share->db_type());
2669
4004
    if (group &&
2670
 
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
2671
 
         param->group_length > table->cursor->getEngine()->max_key_length()))
2672
 
      using_unique_constraint= true;
 
4005
        (param->group_parts > table->file->max_key_parts() ||
 
4006
         param->group_length > table->file->max_key_length()))
 
4007
      using_unique_constraint=1;
2673
4008
  }
2674
4009
  else
2675
4010
  {
2676
 
    share->storage_engine= heap_engine;
2677
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
4011
    share->db_plugin= ha_lock_engine(0, heap_hton);
 
4012
    table->file= get_new_handler(share, &table->mem_root,
 
4013
                                 share->db_type());
2678
4014
  }
2679
 
  if (! table->cursor)
 
4015
  if (!table->file)
2680
4016
    goto err;
2681
4017
 
2682
4018
 
2683
 
  if (! using_unique_constraint)
 
4019
  if (!using_unique_constraint)
2684
4020
    reclength+= group_null_items;       // null flag is stored separately
2685
4021
 
2686
4022
  share->blob_fields= blob_count;
2712
4048
    table->record[1]= table->record[0]+alloc_length;
2713
4049
    share->default_values= table->record[1]+alloc_length;
2714
4050
  }
2715
 
  copy_func[0]= 0;                              // End marker
 
4051
  copy_func[0]=0;                               // End marker
2716
4052
  param->func_count= copy_func - param->items_to_copy;
2717
4053
 
2718
4054
  table->setup_tmp_table_column_bitmaps(bitmaps);
2734
4070
  }
2735
4071
  null_count= (blob_count == 0) ? 1 : 0;
2736
4072
  hidden_field_count=param->hidden_field_count;
2737
 
  for (i= 0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
 
4073
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
2738
4074
  {
2739
4075
    Field *field= *reg_field;
2740
4076
    uint32_t length;
2748
4084
          We have to reserve one byte here for NULL bits,
2749
4085
          as this is updated by 'end_update()'
2750
4086
        */
2751
 
        *pos++= '\0';                           // Null is stored here
2752
 
        recinfo->length= 1;
 
4087
        *pos++=0;                               // Null is stored here
 
4088
        recinfo->length=1;
2753
4089
        recinfo->type=FIELD_NORMAL;
2754
4090
        recinfo++;
2755
4091
        memset(recinfo, 0, sizeof(*recinfo));
2778
4114
         inherit the default value that is defined for the field referred
2779
4115
         by the Item_field object from which 'field' has been created.
2780
4116
      */
2781
 
      ptrdiff_t diff;
 
4117
      my_ptrdiff_t diff;
2782
4118
      Field *orig_field= default_field[i];
2783
4119
      /* Get the value from default_values */
2784
 
      diff= (ptrdiff_t) (orig_field->table->s->default_values-
 
4120
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
2785
4121
                            orig_field->table->record[0]);
2786
4122
      orig_field->move_field_offset(diff);      // Points now at default_values
2787
4123
      if (orig_field->is_real_null())
2817
4153
 
2818
4154
  param->copy_field_end=copy;
2819
4155
  param->recinfo=recinfo;
2820
 
  table->storeRecordAsDefault();        // Make empty default record
 
4156
  store_record(table,s->default_values);        // Make empty default record
2821
4157
 
2822
4158
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
2823
 
    max_rows= ~(uint64_t) 0;
 
4159
    share->max_rows= ~(ha_rows) 0;
2824
4160
  else
2825
 
    max_rows= (uint64_t) (((share->db_type() == heap_engine) ?
2826
 
                          min(session->variables.tmp_table_size,
2827
 
                              session->variables.max_heap_table_size) :
2828
 
                          session->variables.tmp_table_size) /
2829
 
                         share->reclength);
2830
 
 
2831
 
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
 
4161
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
 
4162
                                 cmin(session->variables.tmp_table_size,
 
4163
                                     session->variables.max_heap_table_size) :
 
4164
                                 session->variables.tmp_table_size) /
 
4165
                                 share->reclength);
 
4166
  set_if_bigger(share->max_rows,1);             // For dummy start options
2832
4167
  /*
2833
4168
    Push the LIMIT clause to the temporary table creation, so that we
2834
4169
    materialize only up to 'rows_limit' records instead of all result records.
2835
4170
  */
2836
 
  set_if_smaller(max_rows, rows_limit);
2837
 
 
2838
 
  share->setMaxRows(max_rows);
2839
 
 
 
4171
  set_if_smaller(share->max_rows, rows_limit);
2840
4172
  param->end_write_records= rows_limit;
2841
4173
 
2842
4174
  keyinfo= param->keyinfo;
2851
4183
    keyinfo->key_part=key_part_info;
2852
4184
    keyinfo->flags=HA_NOSAME;
2853
4185
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
2854
 
    keyinfo->key_length= 0;
2855
 
    keyinfo->rec_per_key= 0;
 
4186
    keyinfo->key_length=0;
 
4187
    keyinfo->rec_per_key=0;
2856
4188
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
2857
4189
    keyinfo->name= (char*) "group_key";
2858
4190
    order_st *cur_group= group;
2860
4192
    {
2861
4193
      Field *field=(*cur_group->item)->get_tmp_table_field();
2862
4194
      bool maybe_null=(*cur_group->item)->maybe_null;
2863
 
      key_part_info->null_bit= 0;
 
4195
      key_part_info->null_bit=0;
2864
4196
      key_part_info->field=  field;
2865
4197
      key_part_info->offset= field->offset(table->record[0]);
2866
4198
      key_part_info->length= (uint16_t) field->key_length();
2867
4199
      key_part_info->type=   (uint8_t) field->key_type();
2868
 
      key_part_info->key_type= 
 
4200
      key_part_info->key_type =
2869
4201
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2870
4202
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2871
4203
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2872
 
        0 : 1;
 
4204
        0 : FIELDFLAG_BINARY;
2873
4205
      if (!using_unique_constraint)
2874
4206
      {
2875
4207
        cur_group->buff=(char*) group_buff;
2878
4210
                                                     test(maybe_null),
2879
4211
                                                     field->null_ptr,
2880
4212
                                                     field->null_bit)))
2881
 
          goto err;
 
4213
          goto err; /* purecov: inspected */
2882
4214
        if (maybe_null)
2883
4215
        {
2884
4216
          /*
2889
4221
          */
2890
4222
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
2891
4223
          key_part_info->null_bit=field->null_bit;
2892
 
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
 
4224
          key_part_info->null_offset= (uint) (field->null_ptr -
2893
4225
                                              (unsigned char*) table->record[0]);
2894
4226
          cur_group->buff++;                        // Pointer to field data
2895
4227
          group_buff++;                         // Skipp null flag
2935
4267
    keyinfo->key_length=(uint16_t) reclength;
2936
4268
    keyinfo->name= (char*) "distinct_key";
2937
4269
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
2938
 
    keyinfo->rec_per_key= 0;
 
4270
    keyinfo->rec_per_key=0;
2939
4271
 
2940
4272
    /*
2941
4273
      Create an extra field to hold NULL bits so that unique indexes on
2944
4276
    */
2945
4277
    if (null_pack_length && share->uniques)
2946
4278
    {
2947
 
      key_part_info->null_bit= 0;
 
4279
      key_part_info->null_bit=0;
2948
4280
      key_part_info->offset=hidden_null_pack_length;
2949
4281
      key_part_info->length=null_pack_length;
2950
4282
      key_part_info->field= new Field_varstring(table->record[0],
2951
4283
                                                (uint32_t) key_part_info->length,
2952
4284
                                                0,
2953
4285
                                                (unsigned char*) 0,
2954
 
                                                (uint32_t) 0,
 
4286
                                                (uint) 0,
 
4287
                                                Field::NONE,
2955
4288
                                                NULL,
2956
4289
                                                table->s,
2957
4290
                                                &my_charset_bin);
2958
4291
      if (!key_part_info->field)
2959
4292
        goto err;
2960
4293
      key_part_info->field->init(table);
2961
 
      key_part_info->key_type= 1; /* binary comparison */
 
4294
      key_part_info->key_type=FIELDFLAG_BINARY;
2962
4295
      key_part_info->type=    HA_KEYTYPE_BINARY;
2963
4296
      key_part_info++;
2964
4297
    }
2967
4300
         i < field_count;
2968
4301
         i++, reg_field++, key_part_info++)
2969
4302
    {
2970
 
      key_part_info->null_bit= 0;
 
4303
      key_part_info->null_bit=0;
2971
4304
      key_part_info->field=    *reg_field;
2972
4305
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
2973
4306
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
2974
4307
      /* TODO:
2975
4308
        The below method of computing the key format length of the
2976
 
        key part is a copy/paste from optimizer/range.cc, and table.cc.
 
4309
        key part is a copy/paste from opt_range.cc, and table.cc.
2977
4310
        This should be factored out, e.g. as a method of Field.
2978
4311
        In addition it is not clear if any of the Field::*_length
2979
4312
        methods is supposed to compute the same length. If so, it
2992
4325
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2993
4326
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2994
4327
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2995
 
        0 : 1;
 
4328
        0 : FIELDFLAG_BINARY;
2996
4329
    }
2997
4330
  }
2998
4331
 
2999
4332
  if (session->is_fatal_error)                          // If end of memory
3000
 
    goto err;
 
4333
    goto err;                                    /* purecov: inspected */
3001
4334
  share->db_record_offset= 1;
3002
 
  if (share->db_type() == myisam_engine)
 
4335
  if (share->db_type() == myisam_hton)
3003
4336
  {
3004
4337
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
3005
4338
                                       &param->recinfo, select_options))
3014
4347
 
3015
4348
err:
3016
4349
  session->mem_root= mem_root_save;
3017
 
  table->free_tmp_table(session);
3018
 
  return NULL;
 
4350
  table->free_tmp_table(session);                    /* purecov: inspected */
 
4351
  if (temp_pool_slot != MY_BIT_NONE)
 
4352
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
4353
  return(NULL);                         /* purecov: inspected */
3019
4354
}
3020
4355
 
3021
4356
/****************************************************************************/
3024
4359
  Create a reduced Table object with properly set up Field list from a
3025
4360
  list of field definitions.
3026
4361
 
3027
 
    The created table doesn't have a table Cursor associated with
 
4362
    The created table doesn't have a table handler associated with
3028
4363
    it, has no keys, no group/distinct, no copy_funcs array.
3029
4364
    The sole purpose of this Table object is to use the power of Field
3030
4365
    class to read/write data to/from table->record[0]. Then one can store
3039
4374
    0 if out of memory, Table object in case of success
3040
4375
*/
3041
4376
 
3042
 
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
 
4377
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
3043
4378
{
3044
4379
  uint32_t field_count= field_list.elements;
3045
4380
  uint32_t blob_count= 0;
3046
4381
  Field **field;
3047
 
  CreateField *cdef;                           /* column definition */
 
4382
  Create_field *cdef;                           /* column definition */
3048
4383
  uint32_t record_length= 0;
3049
4384
  uint32_t null_count= 0;                 /* number of columns which may be null */
3050
4385
  uint32_t null_pack_length;              /* NULL representation array length */
3051
4386
  uint32_t *blob_field;
3052
4387
  unsigned char *bitmaps;
3053
4388
  Table *table;
3054
 
  TableShare *share;
 
4389
  TABLE_SHARE *share;
3055
4390
 
3056
4391
  if (!multi_alloc_root(session->mem_root,
3057
4392
                        &table, sizeof(*table),
3058
4393
                        &share, sizeof(*share),
3059
4394
                        &field, (field_count + 1) * sizeof(Field*),
3060
 
                        &blob_field, (field_count+1) *sizeof(uint32_t),
 
4395
                        &blob_field, (field_count+1) *sizeof(uint),
3061
4396
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3062
4397
                        NULL))
3063
 
    return NULL;
 
4398
    return 0;
3064
4399
 
3065
4400
  memset(table, 0, sizeof(*table));
3066
4401
  memset(share, 0, sizeof(*share));
3072
4407
  table->setup_tmp_table_column_bitmaps(bitmaps);
3073
4408
 
3074
4409
  /* Create all fields and calculate the total length of record */
3075
 
  List_iterator_fast<CreateField> it(field_list);
 
4410
  List_iterator_fast<Create_field> it(field_list);
3076
4411
  while ((cdef= it++))
3077
4412
  {
3078
 
    *field= make_field(share,
3079
 
                       NULL,
3080
 
                       0,
3081
 
                       cdef->length,
3082
 
                       (cdef->flags & NOT_NULL_FLAG) ? false : true,
3083
 
                       (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
3084
 
                       (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
3085
 
                       cdef->decimals,
3086
 
                       cdef->sql_type,
3087
 
                       cdef->charset,
 
4413
    *field= make_field(share, 0, cdef->length,
 
4414
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
4415
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
4416
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
3088
4417
                       cdef->unireg_check,
3089
 
                       cdef->interval,
3090
 
                       cdef->field_name);
 
4418
                       cdef->interval, cdef->field_name);
3091
4419
    if (!*field)
3092
4420
      goto error;
3093
4421
    (*field)->init(table);
3096
4424
      null_count++;
3097
4425
 
3098
4426
    if ((*field)->flags & BLOB_FLAG)
3099
 
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
 
4427
      share->blob_field[blob_count++]= (uint) (field - table->field);
3100
4428
 
3101
4429
    field++;
3102
4430
  }
3152
4480
  return 0;
3153
4481
}
3154
4482
 
 
4483
 
3155
4484
bool Table::open_tmp_table()
3156
4485
{
3157
4486
  int error;
3158
 
  if ((error=cursor->ha_open(this, s->table_name.str,O_RDWR,
 
4487
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
3159
4488
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3160
4489
  {
3161
 
    print_error(error, MYF(0));
3162
 
    db_stat= 0;
3163
 
    return true;
 
4490
    file->print_error(error,MYF(0)); /* purecov: inspected */
 
4491
    db_stat=0;
 
4492
    return(1);
3164
4493
  }
3165
 
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
3166
 
  return false;
 
4494
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
4495
  return(0);
3167
4496
}
3168
4497
 
3169
4498
 
3204
4533
  int error;
3205
4534
  MI_KEYDEF keydef;
3206
4535
  MI_UNIQUEDEF uniquedef;
3207
 
  TableShare *share= s;
 
4536
  TABLE_SHARE *share= s;
3208
4537
 
3209
4538
  if (share->keys)
3210
4539
  {                                             // Get keys for ni_create
3211
 
    bool using_unique_constraint= false;
 
4540
    bool using_unique_constraint=0;
3212
4541
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3213
4542
                                            sizeof(*seg) * keyinfo->key_parts);
3214
4543
    if (!seg)
3215
4544
      goto err;
3216
4545
 
3217
4546
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
3218
 
    if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
3219
 
        keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
 
4547
    if (keyinfo->key_length >= file->max_key_length() ||
 
4548
        keyinfo->key_parts > file->max_key_parts() ||
3220
4549
        share->uniques)
3221
4550
    {
3222
4551
      /* Can't create a key; Make a unique constraint instead of a key */
3223
4552
      share->keys=    0;
3224
4553
      share->uniques= 1;
3225
 
      using_unique_constraint= true;
 
4554
      using_unique_constraint=1;
3226
4555
      memset(&uniquedef, 0, sizeof(uniquedef));
3227
4556
      uniquedef.keysegs=keyinfo->key_parts;
3228
4557
      uniquedef.seg=seg;
3243
4572
      keydef.keysegs=  keyinfo->key_parts;
3244
4573
      keydef.seg= seg;
3245
4574
    }
3246
 
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
4575
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
3247
4576
    {
3248
 
      Field *key_field=keyinfo->key_part[i].field;
 
4577
      Field *field=keyinfo->key_part[i].field;
3249
4578
      seg->flag=     0;
3250
 
      seg->language= key_field->charset()->number;
 
4579
      seg->language= field->charset()->number;
3251
4580
      seg->length=   keyinfo->key_part[i].length;
3252
4581
      seg->start=    keyinfo->key_part[i].offset;
3253
 
      if (key_field->flags & BLOB_FLAG)
 
4582
      if (field->flags & BLOB_FLAG)
3254
4583
      {
3255
 
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
4584
        seg->type=
 
4585
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
3256
4586
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3257
 
        seg->bit_start= (uint8_t)(key_field->pack_length()
3258
 
                                  - share->blob_ptr_size);
 
4587
        seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
3259
4588
        seg->flag= HA_BLOB_PART;
3260
 
        seg->length= 0;                 // Whole blob in unique constraint
 
4589
        seg->length=0;                  // Whole blob in unique constraint
3261
4590
      }
3262
4591
      else
3263
4592
      {
3264
4593
        seg->type= keyinfo->key_part[i].type;
3265
4594
      }
3266
 
      if (!(key_field->flags & NOT_NULL_FLAG))
 
4595
      if (!(field->flags & NOT_NULL_FLAG))
3267
4596
      {
3268
 
        seg->null_bit= key_field->null_bit;
3269
 
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
 
4597
        seg->null_bit= field->null_bit;
 
4598
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) record[0]);
3270
4599
        /*
3271
4600
          We are using a GROUP BY on something that contains NULL
3272
4601
          In this case we have to tell MyISAM that two NULL should
3273
4602
          on INSERT be regarded at the same value
3274
4603
        */
3275
 
        if (! using_unique_constraint)
 
4604
        if (!using_unique_constraint)
3276
4605
          keydef.flag|= HA_NULL_ARE_EQUAL;
3277
4606
      }
3278
4607
    }
3285
4614
    create_info.data_file_length= ~(uint64_t) 0;
3286
4615
 
3287
4616
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
3288
 
                       (uint32_t) (*recinfo-start_recinfo),
 
4617
                       (uint) (*recinfo-start_recinfo),
3289
4618
                       start_recinfo,
3290
4619
                       share->uniques, &uniquedef,
3291
4620
                       &create_info,
3292
4621
                       HA_CREATE_TMP_TABLE)))
3293
4622
  {
3294
 
    print_error(error, MYF(0));
3295
 
    db_stat= 0;
 
4623
    file->print_error(error,MYF(0));    /* purecov: inspected */
 
4624
    db_stat=0;
3296
4625
    goto err;
3297
4626
  }
3298
4627
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
3305
4634
 
3306
4635
void Table::free_tmp_table(Session *session)
3307
4636
{
3308
 
  memory::Root own_root= mem_root;
 
4637
  MEM_ROOT own_root= mem_root;
3309
4638
  const char *save_proc_info;
3310
4639
 
3311
4640
  save_proc_info=session->get_proc_info();
3312
4641
  session->set_proc_info("removing tmp table");
3313
4642
 
3314
 
  // Release latches since this can take a long time
3315
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
3316
 
 
3317
 
  if (cursor)
 
4643
  if (file)
3318
4644
  {
3319
4645
    if (db_stat)
3320
 
      cursor->closeMarkForDelete(s->table_name.str);
3321
 
 
3322
 
    s->db_type()->doDropTable(*session, s->table_name.str);
3323
 
 
3324
 
    delete cursor;
 
4646
      file->ha_drop_table(s->table_name.str);
 
4647
    else
 
4648
      file->ha_delete_table(s->table_name.str);
 
4649
    delete file;
3325
4650
  }
3326
4651
 
3327
4652
  /* free blobs */
3328
4653
  for (Field **ptr= field ; *ptr ; ptr++)
3329
4654
    (*ptr)->free();
3330
 
  free_io_cache();
 
4655
  free_io_cache(this);
 
4656
 
 
4657
  if (temp_pool_slot != MY_BIT_NONE)
 
4658
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
4659
 
 
4660
  plugin_unlock(0, s->db_plugin);
3331
4661
 
3332
4662
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
3333
4663
  session->set_proc_info(save_proc_info);
 
4664
 
 
4665
  return;
3334
4666
}
3335
4667
 
3336
4668
/**
3344
4676
                             int error, bool ignore_last_dupp_key_error)
3345
4677
{
3346
4678
  Table new_table;
3347
 
  TableShare share;
 
4679
  TABLE_SHARE share;
3348
4680
  const char *save_proc_info;
3349
4681
  int write_err;
3350
4682
 
3351
 
  if (table->s->db_type() != heap_engine ||
 
4683
  if (table->s->db_type() != heap_hton ||
3352
4684
      error != HA_ERR_RECORD_FILE_FULL)
3353
4685
  {
3354
 
    table->print_error(error, MYF(0));
3355
 
    return true;
 
4686
    table->file->print_error(error,MYF(0));
 
4687
    return(1);
3356
4688
  }
3357
 
 
3358
 
  // Release latches since this can take a long time
3359
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
3360
 
 
3361
4689
  new_table= *table;
3362
4690
  share= *table->s;
3363
4691
  new_table.s= &share;
3364
 
  new_table.s->storage_engine= myisam_engine;
3365
 
  if (not (new_table.cursor= new_table.s->db_type()->getCursor(share, &new_table.mem_root)))
3366
 
    return true;                                // End of memory
 
4692
  new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
 
4693
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
4694
                                        new_table.s->db_type())))
 
4695
    return(1);                          // End of memory
3367
4696
 
3368
4697
  save_proc_info=session->get_proc_info();
3369
4698
  session->set_proc_info("converting HEAP to MyISAM");
3374
4703
    goto err2;
3375
4704
  if (new_table.open_tmp_table())
3376
4705
    goto err1;
3377
 
  if (table->cursor->indexes_are_disabled())
3378
 
    new_table.cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL);
3379
 
  table->cursor->ha_index_or_rnd_end();
3380
 
  table->cursor->ha_rnd_init(1);
 
4706
  if (table->file->indexes_are_disabled())
 
4707
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
4708
  table->file->ha_index_or_rnd_end();
 
4709
  table->file->ha_rnd_init(1);
3381
4710
  if (table->no_rows)
3382
4711
  {
3383
 
    new_table.cursor->extra(HA_EXTRA_NO_ROWS);
 
4712
    new_table.file->extra(HA_EXTRA_NO_ROWS);
3384
4713
    new_table.no_rows=1;
3385
4714
  }
3386
4715
 
3387
4716
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3388
 
  new_table.cursor->extra(HA_EXTRA_WRITE_CACHE);
 
4717
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
3389
4718
 
3390
4719
  /*
3391
4720
    copy all old rows from heap table to MyISAM table
3392
4721
    This is the only code that uses record[1] to read/write but this
3393
4722
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3394
4723
  */
3395
 
  while (!table->cursor->rnd_next(new_table.record[1]))
 
4724
  while (!table->file->rnd_next(new_table.record[1]))
3396
4725
  {
3397
 
    write_err= new_table.cursor->ha_write_row(new_table.record[1]);
 
4726
    write_err= new_table.file->ha_write_row(new_table.record[1]);
3398
4727
    if (write_err)
3399
4728
      goto err;
3400
4729
  }
3401
4730
  /* copy row that filled HEAP table */
3402
 
  if ((write_err=new_table.cursor->ha_write_row(table->record[0])))
 
4731
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
3403
4732
  {
3404
 
    if (new_table.cursor->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
4733
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
3405
4734
        !ignore_last_dupp_key_error)
3406
4735
      goto err;
3407
4736
  }
3408
4737
 
3409
4738
  /* remove heap table and change to use myisam table */
3410
 
  (void) table->cursor->ha_rnd_end();
3411
 
  (void) table->cursor->close();                  // This deletes the table !
3412
 
  delete table->cursor;
3413
 
  table->cursor= NULL;
 
4739
  (void) table->file->ha_rnd_end();
 
4740
  (void) table->file->close();                  // This deletes the table !
 
4741
  delete table->file;
 
4742
  table->file=0;
 
4743
  plugin_unlock(0, table->s->db_plugin);
 
4744
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
3414
4745
  new_table.s= table->s;                       // Keep old share
3415
4746
  *table= new_table;
3416
4747
  *table->s= share;
3417
4748
 
3418
 
  table->cursor->change_table_ptr(table, table->s);
 
4749
  table->file->change_table_ptr(table, table->s);
3419
4750
  table->use_all_columns();
3420
4751
  if (save_proc_info)
3421
4752
  {
3424
4755
      "Copying to tmp table on disk" : save_proc_info);
3425
4756
    session->set_proc_info(new_proc_info);
3426
4757
  }
3427
 
  return false;
 
4758
  return(0);
3428
4759
 
3429
4760
 err:
3430
 
  table->print_error(write_err, MYF(0));
3431
 
  (void) table->cursor->ha_rnd_end();
3432
 
  (void) new_table.cursor->close();
 
4761
  table->file->print_error(write_err, MYF(0));
 
4762
  (void) table->file->ha_rnd_end();
 
4763
  (void) new_table.file->close();
3433
4764
 err1:
3434
 
  new_table.s->db_type()->doDropTable(*session, new_table.s->table_name.str);
 
4765
  new_table.file->ha_delete_table(new_table.s->table_name.str);
3435
4766
 err2:
3436
 
  delete new_table.cursor;
 
4767
  delete new_table.file;
3437
4768
  session->set_proc_info(save_proc_info);
3438
4769
  table->mem_root= new_table.mem_root;
3439
 
  return true;
 
4770
  return(1);
3440
4771
}
3441
4772
 
3442
 
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
4773
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
3443
4774
{
3444
 
  my_bitmap_map *old= bitmap->getBitmap();
3445
 
  bitmap->setBitmap(s->all_set.getBitmap());
 
4775
  my_bitmap_map *old= bitmap->bitmap;
 
4776
  bitmap->bitmap= s->all_set.bitmap;
3446
4777
  return old;
3447
4778
}
3448
4779
 
3449
4780
void Table::restore_column_map(my_bitmap_map *old)
3450
4781
{
3451
 
  read_set->setBitmap(old);
 
4782
  read_set->bitmap= old;
3452
4783
}
3453
4784
 
3454
4785
uint32_t Table::find_shortest_key(const key_map *usable_keys)
3455
4786
{
3456
4787
  uint32_t min_length= UINT32_MAX;
3457
4788
  uint32_t best= MAX_KEY;
3458
 
  if (usable_keys->any())
 
4789
  if (!usable_keys->is_clear_all())
3459
4790
  {
3460
 
    for (uint32_t nr= 0; nr < s->keys ; nr++)
 
4791
    for (uint32_t nr=0; nr < s->keys ; nr++)
3461
4792
    {
3462
 
      if (usable_keys->test(nr))
 
4793
      if (usable_keys->is_set(nr))
3463
4794
      {
3464
4795
        if (key_info[nr].key_length < min_length)
3465
4796
        {
3495
4826
bool Table::compare_record()
3496
4827
{
3497
4828
  if (s->blob_fields + s->varchar_fields == 0)
3498
 
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
3499
 
  
 
4829
    return cmp_record(this, record[1]);
3500
4830
  /* Compare null bits */
3501
 
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
3502
 
    return true; /* Diff in NULL value */
3503
 
 
 
4831
  if (memcmp(null_flags,
 
4832
             null_flags + s->rec_buff_length,
 
4833
             s->null_bytes))
 
4834
    return true;                                // Diff in NULL value
3504
4835
  /* Compare updated fields */
3505
4836
  for (Field **ptr= field ; *ptr ; ptr++)
3506
4837
  {
3507
 
    if (isWriteSet((*ptr)->field_index) &&
 
4838
    if (bitmap_is_set(write_set, (*ptr)->field_index) &&
3508
4839
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
3509
4840
      return true;
3510
4841
  }
3511
4842
  return false;
3512
4843
}
3513
4844
 
3514
 
/*
3515
 
 * Store a record from previous record into next
3516
 
 *
3517
 
 */
3518
 
void Table::storeRecord()
3519
 
{
3520
 
  memcpy(record[1], record[0], (size_t) s->reclength);
3521
 
}
3522
 
 
3523
 
/*
3524
 
 * Store a record as an insert
3525
 
 *
3526
 
 */
3527
 
void Table::storeRecordAsInsert()
3528
 
{
3529
 
  memcpy(insert_values, record[0], (size_t) s->reclength);
3530
 
}
3531
 
 
3532
 
/*
3533
 
 * Store a record with default values
3534
 
 *
3535
 
 */
3536
 
void Table::storeRecordAsDefault()
3537
 
{
3538
 
  memcpy(s->default_values, record[0], (size_t) s->reclength);
3539
 
}
3540
 
 
3541
 
/*
3542
 
 * Restore a record from previous record into next
3543
 
 *
3544
 
 */
3545
 
void Table::restoreRecord()
3546
 
{
3547
 
  memcpy(record[0], record[1], (size_t) s->reclength);
3548
 
}
3549
 
 
3550
 
/*
3551
 
 * Restore a record with default values
3552
 
 *
3553
 
 */
3554
 
void Table::restoreRecordAsDefault()
3555
 
{
3556
 
  memcpy(record[0], s->default_values, (size_t) s->reclength);
3557
 
}
3558
 
 
3559
 
/*
3560
 
 * Empty a record
3561
 
 *
3562
 
 */
3563
 
void Table::emptyRecord()
3564
 
{
3565
 
  restoreRecordAsDefault();
3566
 
  memset(null_flags, 255, s->null_bytes);
3567
 
}
3568
 
 
3569
 
Table::Table()
3570
 
  : s(NULL),
3571
 
    field(NULL),
3572
 
    cursor(NULL),
3573
 
    next(NULL),
3574
 
    prev(NULL),
3575
 
    read_set(NULL),
3576
 
    write_set(NULL),
3577
 
    tablenr(0),
3578
 
    db_stat(0),
3579
 
    in_use(NULL),
3580
 
    insert_values(NULL),
3581
 
    key_info(NULL),
3582
 
    next_number_field(NULL),
3583
 
    found_next_number_field(NULL),
3584
 
    timestamp_field(NULL),
3585
 
    pos_in_table_list(NULL),
3586
 
    group(NULL),
3587
 
    alias(NULL),
3588
 
    null_flags(NULL),
3589
 
    lock_position(0),
3590
 
    lock_data_start(0),
3591
 
    lock_count(0),
3592
 
    used_fields(0),
3593
 
    status(0),
3594
 
    derived_select_number(0),
3595
 
    current_lock(F_UNLCK),
3596
 
    copy_blobs(false),
3597
 
    maybe_null(false),
3598
 
    null_row(false),
3599
 
    force_index(false),
3600
 
    distinct(false),
3601
 
    const_table(false),
3602
 
    no_rows(false),
3603
 
    key_read(false),
3604
 
    no_keyread(false),
3605
 
    open_placeholder(false),
3606
 
    locked_by_name(false),
3607
 
    no_cache(false),
3608
 
    auto_increment_field_not_null(false),
3609
 
    alias_name_used(false),
3610
 
    query_id(0),
3611
 
    quick_condition_rows(0),
3612
 
    timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
3613
 
    map(0)
3614
 
{
3615
 
  record[0]= (unsigned char *) 0;
3616
 
  record[1]= (unsigned char *) 0;
3617
 
 
3618
 
  covering_keys.reset();
3619
 
 
3620
 
  quick_keys.reset();
3621
 
  merge_keys.reset();
3622
 
 
3623
 
  keys_in_use_for_query.reset();
3624
 
  keys_in_use_for_group_by.reset();
3625
 
  keys_in_use_for_order_by.reset();
3626
 
 
3627
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
3628
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
3629
 
 
3630
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
3631
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
3632
 
 
3633
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
3634
 
  memset(&sort, 0, sizeof(filesort_info_st));
3635
 
}
 
4845
 
 
4846
 
 
4847
 
3636
4848
 
3637
4849
/*****************************************************************************
3638
4850
  The different ways to read a record
3639
4851
  Returns -1 if row was not found, 0 if row was found and 1 on errors
3640
4852
*****************************************************************************/
3641
4853
 
3642
 
/** Help function when we get some an error from the table Cursor. */
 
4854
/** Help function when we get some an error from the table handler. */
3643
4855
 
3644
4856
int Table::report_error(int error)
3645
4857
{
3655
4867
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
3656
4868
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
3657
4869
                    error, s->path.str);
3658
 
  print_error(error, MYF(0));
 
4870
  file->print_error(error,MYF(0));
3659
4871
 
3660
4872
  return 1;
3661
4873
}
3662
4874
 
3663
4875
 
3664
 
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
3665
 
{
3666
 
  used_fields= 0;
3667
 
  const_table= 0;
3668
 
  null_row= 0;
3669
 
  status= STATUS_NO_RECORD;
3670
 
  maybe_null= table_list->outer_join;
 
4876
/*
 
4877
  Calculate data for each virtual field marked for write in the
 
4878
  corresponding column map.
 
4879
 
 
4880
  SYNOPSIS
 
4881
    update_virtual_fields_marked_for_write()
 
4882
    table                  The Table object
 
4883
    ignore_stored          Indication whether physically stored virtual
 
4884
                           fields do not need updating.
 
4885
                           This value is false when during INSERT and UPDATE
 
4886
                           and true in all other cases.
 
4887
 
 
4888
  RETURN
 
4889
    0  - Success
 
4890
    >0 - Error occurred during the generation/calculation of a virtual field value
 
4891
 
 
4892
*/
 
4893
 
 
4894
int update_virtual_fields_marked_for_write(Table *table,
 
4895
                                           bool ignore_stored)
 
4896
{
 
4897
  Field **vfield_ptr, *vfield;
 
4898
  int error= 0;
 
4899
  if ((not table) or (not table->vfield))
 
4900
    return(0);
 
4901
 
 
4902
  /* Iterate over virtual fields in the table */
 
4903
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
 
4904
  {
 
4905
    vfield= (*vfield_ptr);
 
4906
    assert(vfield->vcol_info && vfield->vcol_info->expr_item);
 
4907
    /*
 
4908
      Only update those fields that are marked in the write_set bitmap
 
4909
      and not _already_ physically stored in the database.
 
4910
    */
 
4911
    if (bitmap_is_set(table->write_set, vfield->field_index) &&
 
4912
        (not (ignore_stored && vfield->is_stored))
 
4913
       )
 
4914
    {
 
4915
      /* Generate the actual value of the virtual fields */
 
4916
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
 
4917
    }
 
4918
  }
 
4919
  return(0);
 
4920
}
 
4921
 
 
4922
 
 
4923
void setup_table_map(Table *table, TableList *table_list, uint32_t tablenr)
 
4924
{
 
4925
  table->used_fields= 0;
 
4926
  table->const_table= 0;
 
4927
  table->null_row= 0;
 
4928
  table->status= STATUS_NO_RECORD;
 
4929
  table->maybe_null= table_list->outer_join;
3671
4930
  TableList *embedding= table_list->embedding;
3672
 
  while (!maybe_null && embedding)
 
4931
  while (!table->maybe_null && embedding)
3673
4932
  {
3674
 
    maybe_null= embedding->outer_join;
 
4933
    table->maybe_null= embedding->outer_join;
3675
4934
    embedding= embedding->embedding;
3676
4935
  }
3677
 
  tablenr= table_number;
3678
 
  map= (table_map) 1 << table_number;
3679
 
  force_index= table_list->force_index;
3680
 
  covering_keys= s->keys_for_keyread;
3681
 
  merge_keys.reset();
3682
 
}
3683
 
 
3684
 
 
3685
 
/*
3686
 
  Used by ALTER Table when the table is a temporary one. It changes something
3687
 
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old
3688
 
  name).
3689
 
  Prepares a table cache key, which is the concatenation of db, table_name and
3690
 
  session->slave_proxy_id, separated by '\0'.
3691
 
*/
3692
 
 
3693
 
bool Table::rename_temporary_table(const char *db, const char *table_name)
3694
 
{
3695
 
  char *key;
3696
 
  uint32_t key_length;
3697
 
  TableShare *share= s;
3698
 
 
3699
 
  if (!(key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
3700
 
    return true;
3701
 
 
3702
 
  key_length= TableShare::createKey(key, db, table_name);
3703
 
  share->set_table_cache_key(key, key_length);
3704
 
 
3705
 
  return false;
3706
 
}
3707
 
 
3708
 
} /* namespace drizzled */
 
4936
  table->tablenr= tablenr;
 
4937
  table->map= (table_map) 1 << tablenr;
 
4938
  table->force_index= table_list->force_index;
 
4939
  table->covering_keys= table->s->keys_for_keyread;
 
4940
  table->merge_keys.clear_all();
 
4941
}
 
4942
 
 
4943
 
 
4944
/*****************************************************************************
 
4945
** Instansiate templates
 
4946
*****************************************************************************/
 
4947
 
 
4948
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
4949
template class List<String>;
 
4950
template class List_iterator<String>;
 
4951
#endif