~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-01-24 09:43:35 UTC
  • Revision ID: brian@gir-3.local-20090124094335-6qdtvc35gl5fvivz
Adding in an example singe thread scheduler

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