~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Monty Taylor
  • Date: 2009-04-14 19:16:51 UTC
  • mto: (997.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 994.
  • Revision ID: mordred@inaugust.com-20090414191651-ltbww6hpqks8k7qk
Clarified instructions in README.

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/sj_tmp_table.h>
33
24
#include <drizzled/nested_join.h>
 
25
#include <drizzled/data_home.h>
34
26
#include <drizzled/sql_parse.h>
35
27
#include <drizzled/item/sum.h>
 
28
#include <drizzled/virtual_column_info.h>
36
29
#include <drizzled/table_list.h>
37
30
#include <drizzled/session.h>
38
31
#include <drizzled/sql_base.h>
39
 
#include <drizzled/sql_select.h>
40
32
#include <drizzled/field/blob.h>
41
33
#include <drizzled/field/varstring.h>
42
34
#include <drizzled/field/double.h>
 
35
#include <string>
 
36
#include <bitset>
 
37
 
43
38
#include <drizzled/unireg.h>
44
39
#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
40
 
50
41
#include <drizzled/item/string.h>
51
42
#include <drizzled/item/int.h>
52
43
#include <drizzled/item/decimal.h>
53
44
#include <drizzled/item/float.h>
54
45
#include <drizzled/item/null.h>
55
 
#include <drizzled/temporal.h>
56
46
 
57
 
#include "drizzled/table_proto.h"
58
47
 
59
48
using namespace std;
60
49
 
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,
 
50
/* Keyword for parsing virtual column functions */
 
51
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
 
52
 
 
53
/* Functions defined in this file */
 
54
 
 
55
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
71
56
                      myf errortype, int errarg);
 
57
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
 
58
                              uint32_t types, char **names);
72
59
 
73
60
/*************************************************************************/
74
61
 
80
67
  return (unsigned char*) (*buff)->field_name;
81
68
}
82
69
 
83
 
/*
84
 
  Allocate a setup TableShare structure
 
70
 
 
71
/*
 
72
  Returns pointer to '.frm' extension of the file name.
 
73
 
 
74
  SYNOPSIS
 
75
    fn_rext()
 
76
    name       file name
 
77
 
 
78
  DESCRIPTION
 
79
    Checks file name part starting with the rightmost '.' character,
 
80
    and returns it if it is equal to '.frm'.
 
81
 
 
82
  TODO
 
83
    It is a good idea to get rid of this function modifying the code
 
84
    to garantee that the functions presently calling fn_rext() always
 
85
    get arguments in the same format: either with '.frm' or without '.frm'.
 
86
 
 
87
  RETURN VALUES
 
88
    Pointer to the '.frm' extension. If there is no extension,
 
89
    or extension is not '.frm', pointer at the end of file name.
 
90
*/
 
91
 
 
92
char *fn_rext(char *name)
 
93
{
 
94
  char *res= strrchr(name, '.');
 
95
  if (res && !strcmp(res, ".dfe"))
 
96
    return res;
 
97
  return name + strlen(name);
 
98
}
 
99
 
 
100
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
 
101
{
 
102
  assert(db != NULL);
 
103
  assert(name != NULL);
 
104
 
 
105
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
 
106
      (my_strcasecmp(system_charset_info,
 
107
                    INFORMATION_SCHEMA_NAME.c_str(),
 
108
                    db->str) == 0))
 
109
  {
 
110
    return TABLE_CATEGORY_INFORMATION;
 
111
  }
 
112
 
 
113
  return TABLE_CATEGORY_USER;
 
114
}
 
115
 
 
116
 
 
117
/*
 
118
  Allocate a setup TABLE_SHARE structure
85
119
 
86
120
  SYNOPSIS
87
121
    alloc_table_share()
94
128
    #  Share
95
129
*/
96
130
 
97
 
TableShare *alloc_table_share(TableList *table_list, char *key,
 
131
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
98
132
                               uint32_t key_length)
99
133
{
100
 
  memory::Root mem_root;
101
 
  TableShare *share;
 
134
  MEM_ROOT mem_root;
 
135
  TABLE_SHARE *share;
102
136
  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);
 
137
  char path[FN_REFLEN];
 
138
  uint32_t path_length;
 
139
 
 
140
  path_length= build_table_filename(path, sizeof(path) - 1,
 
141
                                    table_list->db,
 
142
                                    table_list->table_name, "", 0);
 
143
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
108
144
  if (multi_alloc_root(&mem_root,
109
145
                       &share, sizeof(*share),
110
146
                       &key_buff, key_length,
111
 
                       &path_buff, path.length() + 1,
 
147
                       &path_buff, path_length + 1,
112
148
                       NULL))
113
149
  {
114
150
    memset(share, 0, sizeof(*share));
115
151
 
116
152
    share->set_table_cache_key(key_buff, key, key_length);
117
153
 
118
 
    share->path.str= path_buff,
119
 
    share->path.length= path.length();
120
 
    strcpy(share->path.str, path.c_str());
 
154
    share->path.str= path_buff;
 
155
    share->path.length= path_length;
 
156
    strcpy(share->path.str, path);
121
157
    share->normalized_path.str=    share->path.str;
122
 
    share->normalized_path.length= path.length();
 
158
    share->normalized_path.length= path_length;
123
159
 
124
160
    share->version=       refresh_version;
125
161
 
 
162
    /*
 
163
      This constant is used to mark that no table map version has been
 
164
      assigned.  No arithmetic is done on the value: it will be
 
165
      overwritten with a value taken from DRIZZLE_BIN_LOG.
 
166
    */
 
167
    share->table_map_version= UINT64_MAX;
 
168
 
 
169
    /*
 
170
      Since alloc_table_share() can be called without any locking (for
 
171
      example, ha_create_table... functions), we do not assign a table
 
172
      map id here.  Instead we assign a value that is not used
 
173
      elsewhere, and then assign a table map id inside open_table()
 
174
      under the protection of the LOCK_open mutex.
 
175
    */
 
176
    share->table_map_id= UINT32_MAX;
 
177
    share->cached_row_logging_check= -1;
 
178
 
126
179
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
127
180
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
128
181
    pthread_cond_init(&share->cond, NULL);
131
184
}
132
185
 
133
186
 
134
 
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
 
187
/*
 
188
  Initialize share for temporary tables
 
189
 
 
190
  SYNOPSIS
 
191
    init_tmp_table_share()
 
192
    session         thread handle
 
193
    share       Share to fill
 
194
    key         Table_cache_key, as generated from create_table_def_key.
 
195
                must start with db name.
 
196
    key_length  Length of key
 
197
    table_name  Table name
 
198
    path        Path to file (possible in lower case) without .frm
 
199
 
 
200
  NOTES
 
201
    This is different from alloc_table_share() because temporary tables
 
202
    don't have to be shared between threads or put into the table def
 
203
    cache, so we can do some things notable simpler and faster
 
204
 
 
205
    If table is not put in session->temporary_tables (happens only when
 
206
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
 
207
    use key_length= 0 as neither table_cache_key or key_length will be used).
 
208
*/
 
209
 
 
210
void init_tmp_table_share(Session *session, TABLE_SHARE *share, const char *key,
 
211
                          uint32_t key_length, const char *table_name,
 
212
                          const char *path)
 
213
{
 
214
 
 
215
  memset(share, 0, sizeof(*share));
 
216
  init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
217
  share->table_category=         TABLE_CATEGORY_TEMPORARY;
 
218
  share->tmp_table=              INTERNAL_TMP_TABLE;
 
219
  share->db.str=                 (char*) key;
 
220
  share->db.length=              strlen(key);
 
221
  share->table_cache_key.str=    (char*) key;
 
222
  share->table_cache_key.length= key_length;
 
223
  share->table_name.str=         (char*) table_name;
 
224
  share->table_name.length=      strlen(table_name);
 
225
  share->path.str=               (char*) path;
 
226
  share->normalized_path.str=    (char*) path;
 
227
  share->path.length= share->normalized_path.length= strlen(path);
 
228
 
 
229
  /*
 
230
    Temporary tables are not replicated, but we set up these fields
 
231
    anyway to be able to catch errors.
 
232
   */
 
233
  share->table_map_version= ~(uint64_t)0;
 
234
  share->cached_row_logging_check= -1;
 
235
 
 
236
  /*
 
237
    table_map_id is also used for MERGE tables to suppress repeated
 
238
    compatibility checks.
 
239
  */
 
240
  share->table_map_id= (ulong) session->query_id;
 
241
 
 
242
  return;
 
243
}
 
244
 
 
245
 
 
246
/*
 
247
  Free table share and memory used by it
 
248
 
 
249
  SYNOPSIS
 
250
    free_table_share()
 
251
    share               Table share
 
252
 
 
253
  NOTES
 
254
    share->mutex must be locked when we come here if it's not a temp table
 
255
*/
 
256
 
 
257
void free_table_share(TABLE_SHARE *share)
 
258
{
 
259
  MEM_ROOT mem_root;
 
260
  assert(share->ref_count == 0);
 
261
 
 
262
  /*
 
263
    If someone is waiting for this to be deleted, inform it about this.
 
264
    Don't do a delete until we know that no one is refering to this anymore.
 
265
  */
 
266
  if (share->tmp_table == NO_TMP_TABLE)
 
267
  {
 
268
    /* share->mutex is locked in release_table_share() */
 
269
    while (share->waiting_on_cond)
 
270
    {
 
271
      pthread_cond_broadcast(&share->cond);
 
272
      pthread_cond_wait(&share->cond, &share->mutex);
 
273
    }
 
274
    /* No thread refers to this anymore */
 
275
    pthread_mutex_unlock(&share->mutex);
 
276
    pthread_mutex_destroy(&share->mutex);
 
277
    pthread_cond_destroy(&share->cond);
 
278
  }
 
279
  hash_free(&share->name_hash);
 
280
 
 
281
  share->storage_engine= NULL;
 
282
 
 
283
  /* We must copy mem_root from share because share is allocated through it */
 
284
  memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
 
285
  free_root(&mem_root, MYF(0));                 // Free's share
 
286
  return;
 
287
}
 
288
 
 
289
enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
135
290
{
136
291
  enum_field_types field_type;
137
292
 
138
293
  switch(proto_field_type)
139
294
  {
140
 
  case message::Table::Field::INTEGER:
 
295
  case drizzled::message::Table::Field::TINYINT:
 
296
    field_type= DRIZZLE_TYPE_TINY;
 
297
    break;
 
298
  case drizzled::message::Table::Field::INTEGER:
141
299
    field_type= DRIZZLE_TYPE_LONG;
142
300
    break;
143
 
  case message::Table::Field::DOUBLE:
 
301
  case drizzled::message::Table::Field::DOUBLE:
144
302
    field_type= DRIZZLE_TYPE_DOUBLE;
145
303
    break;
146
 
  case message::Table::Field::TIMESTAMP:
 
304
  case drizzled::message::Table::Field::TIMESTAMP:
147
305
    field_type= DRIZZLE_TYPE_TIMESTAMP;
148
306
    break;
149
 
  case message::Table::Field::BIGINT:
 
307
  case drizzled::message::Table::Field::BIGINT:
150
308
    field_type= DRIZZLE_TYPE_LONGLONG;
151
309
    break;
152
 
  case message::Table::Field::DATETIME:
 
310
  case drizzled::message::Table::Field::DATETIME:
153
311
    field_type= DRIZZLE_TYPE_DATETIME;
154
312
    break;
155
 
  case message::Table::Field::DATE:
 
313
  case drizzled::message::Table::Field::DATE:
156
314
    field_type= DRIZZLE_TYPE_DATE;
157
315
    break;
158
 
  case message::Table::Field::VARCHAR:
 
316
  case drizzled::message::Table::Field::VARCHAR:
159
317
    field_type= DRIZZLE_TYPE_VARCHAR;
160
318
    break;
161
 
  case message::Table::Field::DECIMAL:
162
 
    field_type= DRIZZLE_TYPE_DECIMAL;
 
319
  case drizzled::message::Table::Field::DECIMAL:
 
320
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
163
321
    break;
164
 
  case message::Table::Field::ENUM:
 
322
  case drizzled::message::Table::Field::ENUM:
165
323
    field_type= DRIZZLE_TYPE_ENUM;
166
324
    break;
167
 
  case message::Table::Field::BLOB:
 
325
  case drizzled::message::Table::Field::BLOB:
168
326
    field_type= DRIZZLE_TYPE_BLOB;
169
327
    break;
 
328
  case drizzled::message::Table::Field::VIRTUAL:
 
329
    field_type= DRIZZLE_TYPE_VIRTUAL;
 
330
    break;
170
331
  default:
171
 
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
 
332
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
172
333
    assert(1);
173
334
  }
174
335
 
175
336
  return field_type;
176
337
}
177
338
 
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)
 
339
Item * default_value_item(enum_field_types field_type,
 
340
                          const CHARSET_INFO *charset,
 
341
                          bool default_null, const string *default_value,
 
342
                          const string *default_bin_value)
182
343
{
183
344
  Item *default_item= NULL;
184
345
  int error= 0;
185
346
 
186
 
  if (default_null)
 
347
  if(default_null)
187
348
  {
188
349
    return new Item_null();
189
350
  }
190
351
 
191
352
  switch(field_type)
192
353
  {
 
354
  case DRIZZLE_TYPE_TINY:
193
355
  case DRIZZLE_TYPE_LONG:
194
356
  case DRIZZLE_TYPE_LONGLONG:
195
357
    default_item= new Item_int(default_value->c_str(),
196
 
                               (int64_t) internal::my_strtoll10(default_value->c_str(),
197
 
                                                                NULL,
198
 
                                                                &error),
 
358
                               (int64_t) my_strtoll10(default_value->c_str(),
 
359
                                                      NULL,
 
360
                                                      &error),
199
361
                               default_value->length());
200
362
    break;
201
363
  case DRIZZLE_TYPE_DOUBLE:
207
369
  case DRIZZLE_TYPE_TIMESTAMP:
208
370
  case DRIZZLE_TYPE_DATETIME:
209
371
  case DRIZZLE_TYPE_DATE:
210
 
    if (default_value->compare("NOW()") == 0)
 
372
    if(default_value->compare("NOW()")==0)
211
373
      break;
212
374
  case DRIZZLE_TYPE_ENUM:
213
375
    default_item= new Item_string(default_value->c_str(),
216
378
    break;
217
379
  case DRIZZLE_TYPE_VARCHAR:
218
380
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
219
 
    if (charset==&my_charset_bin)
 
381
    if(charset==&my_charset_bin)
220
382
    {
221
383
      default_item= new Item_string(default_bin_value->c_str(),
222
384
                                    default_bin_value->length(),
229
391
                                    system_charset_info);
230
392
    }
231
393
    break;
232
 
  case DRIZZLE_TYPE_DECIMAL:
 
394
  case DRIZZLE_TYPE_VIRTUAL:
 
395
    break;
 
396
  case DRIZZLE_TYPE_NEWDECIMAL:
233
397
    default_item= new Item_decimal(default_value->c_str(),
234
398
                                   default_value->length(),
235
399
                                   system_charset_info);
239
403
  return default_item;
240
404
}
241
405
 
242
 
int parse_table_proto(Session& session,
243
 
                      message::Table &table,
244
 
                      TableShare *share)
 
406
int parse_table_proto(Session *session, drizzled::message::Table &table, TABLE_SHARE *share)
245
407
{
246
408
  int error= 0;
 
409
  handler *handler_file= NULL;
247
410
 
248
 
  if (! table.IsInitialized())
249
411
  {
250
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
251
 
    return ER_CORRUPT_TABLE_DEFINITION;
 
412
    LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
 
413
                              strlen(table.engine().name().c_str()) };
 
414
    share->storage_engine= ha_resolve_by_name(session, &engine_name);
252
415
  }
253
416
 
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())
 
417
  share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
 
418
 
 
419
  drizzled::message::Table::TableOptions table_options;
 
420
 
 
421
  if(table.has_options())
262
422
    table_options= table.options();
263
423
 
264
 
  uint32_t db_create_options= 0;
 
424
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
265
425
 
266
 
  if (table_options.has_pack_keys())
 
426
  if(table_options.has_pack_keys())
267
427
  {
268
 
    if (table_options.pack_keys())
 
428
    if(table_options.pack_keys())
269
429
      db_create_options|= HA_OPTION_PACK_KEYS;
270
430
    else
271
431
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
272
432
  }
273
433
 
274
 
  if (table_options.pack_record())
 
434
  if(table_options.pack_record())
275
435
    db_create_options|= HA_OPTION_PACK_RECORD;
276
436
 
 
437
  if(table_options.has_checksum())
 
438
  {
 
439
    if(table_options.checksum())
 
440
      db_create_options|= HA_OPTION_CHECKSUM;
 
441
    else
 
442
      db_create_options|= HA_OPTION_NO_CHECKSUM;
 
443
  }
 
444
 
 
445
  if(table_options.has_delay_key_write())
 
446
  {
 
447
    if(table_options.delay_key_write())
 
448
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
 
449
    else
 
450
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
 
451
  }
 
452
 
277
453
  /* db_create_options was stored as 2 bytes in FRM
278
454
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
279
455
   */
280
456
  share->db_create_options= (db_create_options & 0x0000FFFF);
281
457
  share->db_options_in_use= share->db_create_options;
282
458
 
 
459
 
 
460
  share->avg_row_length= table_options.has_avg_row_length() ?
 
461
    table_options.avg_row_length() : 0;
 
462
 
 
463
  share->page_checksum= table_options.has_page_checksum() ?
 
464
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
465
    : HA_CHOICE_UNDEF;
 
466
 
283
467
  share->row_type= table_options.has_row_type() ?
284
468
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
285
469
 
308
492
 
309
493
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
310
494
 
 
495
  share->db_low_byte_first= true;
 
496
 
 
497
  share->max_rows= table_options.has_max_rows() ?
 
498
    table_options.max_rows() : 0;
 
499
 
 
500
  share->min_rows= table_options.has_min_rows() ?
 
501
    table_options.min_rows() : 0;
 
502
 
311
503
  share->keys= table.indexes_size();
312
504
 
313
505
  share->key_parts= 0;
314
 
  for (int indx= 0; indx < table.indexes_size(); indx++)
 
506
  for(int indx= 0; indx < table.indexes_size(); indx++)
315
507
    share->key_parts+= table.indexes(indx).index_part_size();
316
508
 
317
509
  share->key_info= (KEY*) alloc_root(&share->mem_root,
340
532
  share->keynames.type_lengths[share->keynames.count]= 0;
341
533
 
342
534
  KEY* keyinfo= share->key_info;
343
 
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
535
  for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
344
536
  {
345
 
    message::Table::Index indx= table.indexes(keynr);
 
537
    drizzled::message::Table::Index indx= table.indexes(keynr);
346
538
 
347
539
    keyinfo->table= 0;
348
540
    keyinfo->flags= 0;
349
541
 
350
 
    if (indx.is_unique())
 
542
    if(indx.is_unique())
351
543
      keyinfo->flags|= HA_NOSAME;
352
544
 
353
 
    if (indx.has_options())
 
545
    if(indx.has_options())
354
546
    {
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())
 
547
      drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
 
548
      if(indx_options.pack_key())
 
549
        keyinfo->flags|= HA_PACK_KEY;
 
550
 
 
551
      if(indx_options.var_length_key())
 
552
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
553
 
 
554
      if(indx_options.null_part_key())
 
555
        keyinfo->flags|= HA_NULL_PART_KEY;
 
556
 
 
557
      if(indx_options.binary_pack_key())
 
558
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
559
 
 
560
      if(indx_options.has_partial_segments())
 
561
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
562
 
 
563
      if(indx_options.auto_generated_key())
 
564
        keyinfo->flags|= HA_GENERATED_KEY;
 
565
 
 
566
      if(indx_options.has_key_block_size())
375
567
      {
376
 
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
377
 
        keyinfo->block_size= indx_options.key_block_size();
 
568
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
569
        keyinfo->block_size= indx_options.key_block_size();
378
570
      }
379
571
      else
380
572
      {
381
 
        keyinfo->block_size= 0;
 
573
        keyinfo->block_size= 0;
382
574
      }
 
575
 
383
576
    }
384
577
 
385
 
    switch (indx.type())
 
578
    switch(indx.type())
386
579
    {
387
 
    case message::Table::Index::UNKNOWN_INDEX:
 
580
    case drizzled::message::Table::Index::UNKNOWN_INDEX:
388
581
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
389
582
      break;
390
 
    case message::Table::Index::BTREE:
 
583
    case drizzled::message::Table::Index::BTREE:
391
584
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
392
585
      break;
393
 
    case message::Table::Index::HASH:
 
586
    case drizzled::message::Table::Index::RTREE:
 
587
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
588
      break;
 
589
    case drizzled::message::Table::Index::HASH:
394
590
      keyinfo->algorithm= HA_KEY_ALG_HASH;
395
591
      break;
 
592
    case drizzled::message::Table::Index::FULLTEXT:
 
593
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
396
594
 
397
595
    default:
398
596
      /* TODO: suitable warning ? */
407
605
    keyinfo->key_part= key_part;
408
606
    keyinfo->rec_per_key= rec_per_key;
409
607
 
410
 
    for (unsigned int partnr= 0;
411
 
         partnr < keyinfo->key_parts;
412
 
         partnr++, key_part++)
 
608
    for(unsigned int partnr= 0;
 
609
        partnr < keyinfo->key_parts;
 
610
        partnr++, key_part++)
413
611
    {
414
 
      message::Table::Index::IndexPart part;
 
612
      drizzled::message::Table::Index::IndexPart part;
415
613
      part= indx.index_part(partnr);
416
614
 
417
 
      *rec_per_key++= 0;
 
615
      *rec_per_key++=0;
418
616
 
419
617
      key_part->field= NULL;
420
618
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
423
621
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
424
622
      /* key_part->type ???? */
425
623
      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;
 
624
      if(part.has_in_reverse_order())
 
625
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
428
626
 
429
627
      key_part->length= part.compare_length();
430
628
 
432
630
 
433
631
      /* key_part->offset is set later */
434
632
      key_part->key_type= part.key_type();
 
633
 
435
634
    }
436
635
 
437
 
    if (! indx.has_comment())
 
636
    if(!indx.has_comment())
438
637
    {
439
638
      keyinfo->comment.length= 0;
440
639
      keyinfo->comment.str= NULL;
456
655
    share->keynames.type_lengths[keynr]= indx.name().length();
457
656
  }
458
657
 
459
 
  share->keys_for_keyread.reset();
460
 
  set_prefix(share->keys_in_use, share->keys);
 
658
  share->keys_for_keyread.init(0);
 
659
  share->keys_in_use.init(share->keys);
 
660
 
 
661
  if(table_options.has_connect_string())
 
662
  {
 
663
    size_t len= table_options.connect_string().length();
 
664
    const char* str= table_options.connect_string().c_str();
 
665
 
 
666
    share->connect_string.length= len;
 
667
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
668
  }
 
669
 
 
670
  if(table_options.has_comment())
 
671
  {
 
672
    size_t len= table_options.comment().length();
 
673
    const char* str= table_options.comment().c_str();
 
674
 
 
675
    share->comment.length= len;
 
676
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
677
  }
 
678
 
 
679
  share->key_block_size= table_options.has_key_block_size() ?
 
680
    table_options.key_block_size() : 0;
461
681
 
462
682
  share->fields= table.field_size();
 
683
  share->vfields= 0;
 
684
  share->stored_fields= share->fields;
463
685
 
464
686
  share->field= (Field**) alloc_root(&share->mem_root,
465
687
                                     ((share->fields+1) * sizeof(Field*)));
478
700
 
479
701
  uint32_t stored_columns_reclength= 0;
480
702
 
481
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
703
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
482
704
  {
483
 
    message::Table::Field pfield= table.field(fieldnr);
484
 
    if (pfield.constraints().is_nullable())
 
705
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
706
    if(pfield.has_constraints() && pfield.constraints().is_nullable())
485
707
      null_fields++;
486
708
 
 
709
    bool field_is_stored= true;
 
710
 
487
711
    enum_field_types drizzle_field_type=
488
712
      proto_field_type_to_drizzle_type(pfield.type());
489
713
 
 
714
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
715
    {
 
716
      drizzled::message::Table::Field::VirtualFieldOptions field_options=
 
717
        pfield.virtual_options();
 
718
 
 
719
      drizzle_field_type=proto_field_type_to_drizzle_type(field_options.type());
 
720
 
 
721
      field_is_stored= field_options.physically_stored();
 
722
    }
 
723
 
490
724
    field_offsets[fieldnr]= stored_columns_reclength;
491
725
 
492
726
    /* the below switch is very similar to
493
 
       CreateField::create_length_to_internal_length in field.cc
 
727
       Create_field::create_length_to_internal_length in field.cc
494
728
       (which should one day be replace by just this code)
495
729
    */
496
730
    switch(drizzle_field_type)
498
732
    case DRIZZLE_TYPE_BLOB:
499
733
    case DRIZZLE_TYPE_VARCHAR:
500
734
      {
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);
 
735
        drizzled::message::Table::Field::StringFieldOptions field_options=
 
736
          pfield.string_options();
 
737
 
 
738
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
739
                                            field_options.collation_id() : 0);
 
740
 
 
741
        if (!cs)
 
742
          cs= default_charset_info;
 
743
 
 
744
        field_pack_length[fieldnr]=
 
745
          calc_pack_length(drizzle_field_type,
 
746
                           field_options.length() * cs->mbmaxlen);
 
747
 
511
748
      }
512
749
      break;
513
750
    case DRIZZLE_TYPE_ENUM:
514
751
      {
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();
 
752
        drizzled::message::Table::Field::SetFieldOptions field_options=
 
753
          pfield.set_options();
 
754
 
 
755
        field_pack_length[fieldnr]=
 
756
          get_enum_pack_length(field_options.field_value_size());
 
757
 
 
758
        interval_count++;
 
759
        interval_parts+= field_options.field_value_size();
522
760
      }
523
761
      break;
524
 
    case DRIZZLE_TYPE_DECIMAL:
 
762
    case DRIZZLE_TYPE_NEWDECIMAL:
525
763
      {
526
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
764
        drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
527
765
 
528
 
        field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
 
766
        field_pack_length[fieldnr]=
 
767
          my_decimal_get_binary_size(fo.precision(), fo.scale());
529
768
      }
530
769
      break;
531
770
    default:
534
773
    }
535
774
 
536
775
    share->reclength+= field_pack_length[fieldnr];
537
 
    stored_columns_reclength+= field_pack_length[fieldnr];
 
776
 
 
777
    if(field_is_stored)
 
778
      stored_columns_reclength+= field_pack_length[fieldnr];
538
779
  }
539
780
 
540
781
  /* data_offset added to stored_rec_length later */
541
782
  share->stored_rec_length= stored_columns_reclength;
542
783
 
 
784
  /* fix up offsets for non-stored fields (at end of record) */
 
785
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
786
  {
 
787
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
788
 
 
789
    bool field_is_stored= true;
 
790
 
 
791
    enum_field_types drizzle_field_type=
 
792
      proto_field_type_to_drizzle_type(pfield.type());
 
793
 
 
794
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
795
    {
 
796
      drizzled::message::Table::Field::VirtualFieldOptions field_options=
 
797
        pfield.virtual_options();
 
798
 
 
799
      field_is_stored= field_options.physically_stored();
 
800
    }
 
801
 
 
802
    if(!field_is_stored)
 
803
    {
 
804
      field_offsets[fieldnr]= stored_columns_reclength;
 
805
      stored_columns_reclength+= field_pack_length[fieldnr];
 
806
    }
 
807
  }
543
808
  share->null_fields= null_fields;
544
809
 
545
810
  ulong null_bits= null_fields;
546
 
  if (! table_options.pack_record())
 
811
  if(!table_options.pack_record())
547
812
    null_bits++;
548
813
  ulong data_offset= (null_bits + 7)/8;
549
814
 
558
823
 
559
824
  unsigned char* record= NULL;
560
825
 
561
 
  if (! (record= (unsigned char *) alloc_root(&share->mem_root,
562
 
                                              rec_buff_length)))
 
826
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
 
827
                                     rec_buff_length)))
563
828
    abort();
564
829
 
565
830
  memset(record, 0, rec_buff_length);
566
831
 
567
832
  int null_count= 0;
568
833
 
569
 
  if (! table_options.pack_record())
 
834
  if(!table_options.pack_record())
570
835
  {
571
836
    null_count++; // one bit for delete mark.
572
837
    *record|= 1;
574
839
 
575
840
  share->default_values= record;
576
841
 
577
 
  if (interval_count)
 
842
  if(interval_count)
578
843
  {
579
 
    share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
580
 
                                           interval_count*sizeof(TYPELIB));
 
844
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
845
                                           interval_count*sizeof(TYPELIB));
581
846
  }
582
847
  else
583
848
    share->intervals= NULL;
584
849
 
585
 
  share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
586
 
                                                          (share->fields + 1) * sizeof(char*));
 
850
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
851
                                  (share->fields+1)*sizeof(char*));
587
852
 
588
 
  share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
589
 
                                                             (share->fields + 1) * sizeof(unsigned int));
 
853
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
854
                                  (share->fields+1)*sizeof(unsigned int));
590
855
 
591
856
  share->fieldnames.type_names[share->fields]= NULL;
592
857
  share->fieldnames.type_lengths[share->fields]= 0;
599
864
 
600
865
  uint32_t interval_nr= 0;
601
866
 
602
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
867
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
603
868
  {
604
 
    message::Table::Field pfield= table.field(fieldnr);
 
869
    drizzled::message::Table::Field pfield= table.field(fieldnr);
605
870
 
606
871
    /* field names */
607
872
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
608
 
                                                        pfield.name().c_str(),
609
 
                                                        pfield.name().length());
 
873
                                                        pfield.name().c_str(),
 
874
                                                        pfield.name().length());
610
875
 
611
876
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
612
877
 
613
878
    /* enum typelibs */
614
 
    if (pfield.type() != message::Table::Field::ENUM)
 
879
    if(pfield.type() != drizzled::message::Table::Field::ENUM)
615
880
      continue;
616
881
 
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)
 
882
    drizzled::message::Table::Field::SetFieldOptions field_options=
 
883
      pfield.set_options();
 
884
 
 
885
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
886
                                             field_options.collation_id() : 0);
 
887
 
 
888
    if (!charset)
623
889
      charset= default_charset_info;
624
890
 
625
891
    TYPELIB *t= &(share->intervals[interval_nr]);
626
892
 
627
893
    t->type_names= (const char**)alloc_root(&share->mem_root,
628
 
                                            (field_options.field_value_size() + 1) * sizeof(char*));
 
894
                           (field_options.field_value_size()+1)*sizeof(char*));
629
895
 
630
896
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
631
 
                                                (field_options.field_value_size() + 1) * sizeof(unsigned int));
 
897
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
632
898
 
633
899
    t->type_names[field_options.field_value_size()]= NULL;
634
900
    t->type_lengths[field_options.field_value_size()]= 0;
636
902
    t->count= field_options.field_value_size();
637
903
    t->name= NULL;
638
904
 
639
 
    for (int n= 0; n < field_options.field_value_size(); n++)
 
905
    for(int n=0; n < field_options.field_value_size(); n++)
640
906
    {
641
907
      t->type_names[n]= strmake_root(&share->mem_root,
642
 
                                     field_options.field_value(n).c_str(),
643
 
                                     field_options.field_value(n).length());
 
908
                                     field_options.field_value(n).c_str(),
 
909
                                     field_options.field_value(n).length());
644
910
 
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.
 
911
      /* Go ask the charset what the length is as for "" length=1
 
912
         and there's stripping spaces or some other crack going on.
648
913
       */
649
914
      uint32_t lengthsp;
650
 
      lengthsp= charset->cset->lengthsp(charset,
651
 
                                        t->type_names[n],
652
 
                                        field_options.field_value(n).length());
 
915
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
916
                                        field_options.field_value(n).length());
653
917
      t->type_lengths[n]= lengthsp;
654
918
    }
655
919
    interval_nr++;
661
925
 
662
926
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
663
927
 
664
 
  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);
 
928
  if(use_hash)
 
929
    use_hash= !hash_init(&share->name_hash,
 
930
                         system_charset_info,
 
931
                         share->fields, 0, 0,
 
932
                         (hash_get_key) get_field_name, 0, 0);
673
933
 
674
934
  unsigned char* null_pos= record;;
675
935
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
676
936
 
677
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
937
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
678
938
  {
679
 
    message::Table::Field pfield= table.field(fieldnr);
 
939
    drizzled::message::Table::Field pfield= table.field(fieldnr);
680
940
 
681
941
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
682
942
 
683
 
    switch (pfield.format())
 
943
    switch(pfield.format())
684
944
    {
685
 
    case message::Table::Field::DefaultFormat:
 
945
    case drizzled::message::Table::Field::DefaultFormat:
686
946
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
687
947
      break;
688
 
    case message::Table::Field::FixedFormat:
 
948
    case drizzled::message::Table::Field::FixedFormat:
689
949
      column_format= COLUMN_FORMAT_TYPE_FIXED;
690
950
      break;
691
 
    case message::Table::Field::DynamicFormat:
 
951
    case drizzled::message::Table::Field::DynamicFormat:
692
952
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
693
953
      break;
694
954
    default:
697
957
 
698
958
    Field::utype unireg_type= Field::NONE;
699
959
 
700
 
    if (pfield.has_numeric_options() &&
701
 
        pfield.numeric_options().is_autoincrement())
 
960
    if(pfield.has_numeric_options()
 
961
       && pfield.numeric_options().is_autoincrement())
702
962
    {
703
963
      unireg_type= Field::NEXT_NUMBER;
704
964
    }
705
965
 
706
 
    if (pfield.has_options() &&
707
 
        pfield.options().has_default_value() &&
708
 
        pfield.options().default_value().compare("NOW()") == 0)
 
966
    if(pfield.has_options()
 
967
       && pfield.options().has_default_value()
 
968
       && pfield.options().default_value().compare("NOW()")==0)
709
969
    {
710
 
      if (pfield.options().has_update_value() &&
711
 
          pfield.options().update_value().compare("NOW()") == 0)
 
970
      if(pfield.options().has_update_value()
 
971
         && pfield.options().update_value().compare("NOW()")==0)
712
972
      {
713
 
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
973
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
714
974
      }
715
 
      else if (! pfield.options().has_update_value())
 
975
      else if (!pfield.options().has_update_value())
716
976
      {
717
 
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
977
        unireg_type= Field::TIMESTAMP_DN_FIELD;
718
978
      }
719
979
      else
720
 
        assert(1); // Invalid update value.
 
980
        assert(1); // Invalid update value.
721
981
    }
722
 
    else if (pfield.has_options() &&
723
 
             pfield.options().has_update_value() &&
724
 
             pfield.options().update_value().compare("NOW()") == 0)
 
982
    else if (pfield.has_options()
 
983
             && pfield.options().has_update_value()
 
984
             && pfield.options().update_value().compare("NOW()")==0)
725
985
    {
726
986
      unireg_type= Field::TIMESTAMP_UN_FIELD;
727
987
    }
728
988
 
729
989
    LEX_STRING comment;
730
 
    if (!pfield.has_comment())
 
990
    if(!pfield.has_comment())
731
991
    {
732
992
      comment.str= (char*)"";
733
993
      comment.length= 0;
742
1002
    }
743
1003
 
744
1004
    enum_field_types field_type;
 
1005
    virtual_column_info *vcol_info= NULL;
 
1006
    bool field_is_stored= true;
 
1007
 
745
1008
 
746
1009
    field_type= proto_field_type_to_drizzle_type(pfield.type());
747
1010
 
 
1011
    if(field_type==DRIZZLE_TYPE_VIRTUAL)
 
1012
    {
 
1013
      drizzled::message::Table::Field::VirtualFieldOptions field_options=
 
1014
        pfield.virtual_options();
 
1015
 
 
1016
      vcol_info= new virtual_column_info();
 
1017
      field_type= proto_field_type_to_drizzle_type(field_options.type());
 
1018
      field_is_stored= field_options.physically_stored();
 
1019
 
 
1020
      size_t len= field_options.expression().length();
 
1021
      const char* str= field_options.expression().c_str();
 
1022
 
 
1023
      vcol_info->expr_str.str= strmake_root(&share->mem_root, str, len);
 
1024
      vcol_info->expr_str.length= len;
 
1025
 
 
1026
      share->vfields++;
 
1027
    }
 
1028
 
748
1029
    const CHARSET_INFO *charset= &my_charset_bin;
749
1030
 
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
 
      {
781
 
        /*
782
 
          We don't write the default to table proto so
783
 
          if no decimals specified for DOUBLE, we use the default.
784
 
        */
785
 
        decimals= NOT_FIXED_DEC;
786
 
      }
787
 
      else
788
 
      {
789
 
        if (fo.scale() > DECIMAL_MAX_SCALE)
790
 
        {
791
 
          error= 4;
792
 
          goto err;
793
 
        }
794
 
        decimals= static_cast<uint8_t>(fo.scale());
795
 
      }
 
1031
    if(field_type==DRIZZLE_TYPE_BLOB
 
1032
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
1033
    {
 
1034
      drizzled::message::Table::Field::StringFieldOptions field_options=
 
1035
        pfield.string_options();
 
1036
 
 
1037
      charset= get_charset(field_options.has_collation_id()?
 
1038
                           field_options.collation_id() : 0);
 
1039
 
 
1040
      if (!charset)
 
1041
        charset= default_charset_info;
 
1042
 
 
1043
    }
 
1044
 
 
1045
    if(field_type==DRIZZLE_TYPE_ENUM)
 
1046
    {
 
1047
      drizzled::message::Table::Field::SetFieldOptions field_options=
 
1048
        pfield.set_options();
 
1049
 
 
1050
      charset= get_charset(field_options.has_collation_id()?
 
1051
                           field_options.collation_id() : 0);
 
1052
 
 
1053
      if (!charset)
 
1054
        charset= default_charset_info;
 
1055
 
796
1056
    }
797
1057
 
798
1058
    Item *default_value= NULL;
799
1059
 
800
 
    if (pfield.options().has_default_value() ||
801
 
        pfield.options().has_default_null()  ||
802
 
        pfield.options().has_default_bin_value())
 
1060
    if(pfield.options().has_default_value()
 
1061
       || pfield.options().has_default_null()
 
1062
       || pfield.options().has_default_bin_value())
803
1063
    {
804
1064
      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());
 
1065
                                        charset,
 
1066
                                        pfield.options().default_null(),
 
1067
                                        &pfield.options().default_value(),
 
1068
                                        &pfield.options().default_bin_value());
809
1069
    }
810
1070
 
 
1071
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
811
1072
 
812
1073
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
813
1074
    memset(&temp_table, 0, sizeof(temp_table));
814
1075
    temp_table.s= share;
815
 
    temp_table.in_use= &session;
816
 
    temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
 
1076
    temp_table.in_use= session;
 
1077
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
817
1078
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
818
1079
 
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())
841
 
      {
842
 
        field_length= DBL_DIG+7;
843
 
      }
844
 
      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]);
 
1080
    Field* f= make_field(share, &share->mem_root,
 
1081
                         record+field_offsets[fieldnr]+data_offset,
 
1082
                         pfield.options().length(),
 
1083
                         null_pos,
 
1084
                         null_bit_pos,
 
1085
                         pack_flag,
 
1086
                         field_type,
 
1087
                         charset,
 
1088
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
1089
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
1090
                         share->intervals+(interval_nr++)
 
1091
                         : (TYPELIB*) 0),
 
1092
                        share->fieldnames.type_names[fieldnr]);
919
1093
 
920
1094
    share->field[fieldnr]= f;
921
1095
 
922
1096
    f->init(&temp_table); /* blob default values need table obj */
923
1097
 
924
 
    if (! (f->flags & NOT_NULL_FLAG))
 
1098
    if(!(f->flags & NOT_NULL_FLAG))
925
1099
    {
926
1100
      *f->null_ptr|= f->null_bit;
927
 
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
928
 
        null_pos++;
 
1101
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
 
1102
        null_pos++;
929
1103
      null_count++;
930
1104
    }
931
1105
 
932
 
    if (default_value)
 
1106
    if(default_value)
933
1107
    {
934
 
      enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
935
 
      session.count_cuted_fields= CHECK_FIELD_WARN;
 
1108
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
1109
      session->count_cuted_fields= CHECK_FIELD_WARN;
936
1110
      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? */
 
1111
      session->count_cuted_fields= old_count_cuted_fields;
 
1112
      if (res != 0 && res != 3)
939
1113
      {
940
1114
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
941
1115
        error= 1;
942
 
        goto err;
 
1116
        goto err;
943
1117
      }
944
1118
    }
945
 
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
946
 
             (f->flags & NOT_NULL_FLAG))
 
1119
    else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
 
1120
            (f->flags & NOT_NULL_FLAG))
947
1121
    {
948
1122
      f->set_notnull();
949
1123
      f->store((int64_t) 1, true);
957
1131
 
958
1132
    f->field_index= fieldnr;
959
1133
    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
 
    {
 
1134
    f->vcol_info= vcol_info;
 
1135
    f->is_stored= field_is_stored;
 
1136
    if(!default_value
 
1137
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
1138
       && (f->flags & NOT_NULL_FLAG)
 
1139
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
965
1140
      f->flags|= NO_DEFAULT_VALUE_FLAG;
966
 
    }
967
1141
 
968
 
    if (f->unireg_check == Field::NEXT_NUMBER)
 
1142
    if(f->unireg_check == Field::NEXT_NUMBER)
969
1143
      share->found_next_number_field= &(share->field[fieldnr]);
970
1144
 
971
 
    if (share->timestamp_field == f)
 
1145
    if(share->timestamp_field == f)
972
1146
      share->timestamp_field_offset= fieldnr;
973
1147
 
974
1148
    if (use_hash) /* supposedly this never fails... but comments lie */
975
1149
      (void) my_hash_insert(&share->name_hash,
976
1150
                            (unsigned char*)&(share->field[fieldnr]));
977
1151
 
 
1152
    if(!f->is_stored)
 
1153
    {
 
1154
      share->stored_fields--;
 
1155
    }
978
1156
  }
979
1157
 
980
1158
  keyinfo= share->key_info;
981
 
  for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
 
1159
  for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
982
1160
  {
983
1161
    key_part= keyinfo->key_part;
984
1162
 
985
 
    for (unsigned int partnr= 0;
986
 
         partnr < keyinfo->key_parts;
987
 
         partnr++, key_part++)
 
1163
    for(unsigned int partnr= 0;
 
1164
        partnr < keyinfo->key_parts;
 
1165
        partnr++, key_part++)
988
1166
    {
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
 
       */
 
1167
      /* Fix up key_part->offset by adding data_offset.
 
1168
         We really should compute offset as well.
 
1169
         But at least this way we are a little better. */
994
1170
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
995
1171
    }
996
1172
  }
1003
1179
  if (null_count & 7)
1004
1180
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1005
1181
 
1006
 
  share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
 
1182
  share->null_bytes= (null_pos - (unsigned char*) record +
 
1183
                      (null_bit_pos + 7) / 8);
1007
1184
 
1008
1185
  share->last_null_bit_pos= null_bit_pos;
1009
1186
 
1010
1187
  free(field_offsets);
1011
 
  field_offsets= NULL;
1012
1188
  free(field_pack_length);
1013
 
  field_pack_length= NULL;
 
1189
 
 
1190
  if(!(handler_file= get_new_handler(share, session->mem_root,
 
1191
                                     share->db_type())))
 
1192
    abort(); // FIXME
1014
1193
 
1015
1194
  /* Fix key stuff */
1016
1195
  if (share->key_parts)
1017
1196
  {
1018
 
    uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1019
 
                                                &share->keynames, 3) - 1); /* @TODO Huh? */
 
1197
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
 
1198
                                       &share->keynames, 3) - 1);
 
1199
 
 
1200
    int64_t ha_option= handler_file->ha_table_flags();
1020
1201
 
1021
1202
    keyinfo= share->key_info;
1022
1203
    key_part= keyinfo->key_part;
1023
1204
 
1024
 
    for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
 
1205
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1025
1206
    {
1026
1207
      uint32_t usable_parts= 0;
1027
1208
 
1028
1209
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1029
1210
      {
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
 
        }
 
1211
        /*
 
1212
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
1213
          declare this as a primary key.
 
1214
        */
 
1215
        primary_key=key;
 
1216
        for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
 
1217
        {
 
1218
          uint32_t fieldnr= key_part[i].fieldnr;
 
1219
          if (!fieldnr ||
 
1220
              share->field[fieldnr-1]->null_ptr ||
 
1221
              share->field[fieldnr-1]->key_length() !=
 
1222
              key_part[i].length)
 
1223
          {
 
1224
            primary_key=MAX_KEY;                // Can't be used
 
1225
            break;
 
1226
          }
 
1227
        }
1046
1228
      }
1047
1229
 
1048
 
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1230
      for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1049
1231
      {
1050
1232
        Field *field;
1051
 
        if (! key_part->fieldnr)
 
1233
        if (!key_part->fieldnr)
1052
1234
        {
1053
 
          abort(); // goto err;
 
1235
//          error= 4;                             // Wrong file
 
1236
          abort(); // goto err;
1054
1237
        }
1055
1238
        field= key_part->field= share->field[key_part->fieldnr-1];
1056
1239
        key_part->type= field->key_type();
1080
1263
                           (keyinfo->key_parts == 1)) ?
1081
1264
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1082
1265
        if (i == 0)
1083
 
          field->key_start.set(key);
 
1266
          field->key_start.set_bit(key);
1084
1267
        if (field->key_length() == key_part->length &&
1085
1268
            !(field->flags & BLOB_FLAG))
1086
1269
        {
1087
 
          enum ha_key_alg algo= share->key_info[key].algorithm;
1088
 
          if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
 
1270
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1089
1271
          {
1090
 
            share->keys_for_keyread.set(key);
1091
 
            field->part_of_key.set(key);
1092
 
            field->part_of_key_not_clustered.set(key);
 
1272
            share->keys_for_keyread.set_bit(key);
 
1273
            field->part_of_key.set_bit(key);
 
1274
            field->part_of_key_not_clustered.set_bit(key);
1093
1275
          }
1094
 
          if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
1095
 
            field->part_of_sortkey.set(key);
 
1276
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
 
1277
            field->part_of_sortkey.set_bit(key);
1096
1278
        }
1097
1279
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1098
1280
            usable_parts == i)
1105
1287
            If this field is part of the primary key and all keys contains
1106
1288
            the primary key, then we can use any key to find this column
1107
1289
          */
1108
 
          if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
 
1290
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1109
1291
          {
1110
1292
            field->part_of_key= share->keys_in_use;
1111
 
            if (field->part_of_sortkey.test(key))
 
1293
            if (field->part_of_sortkey.is_set(key))
1112
1294
              field->part_of_sortkey= share->keys_in_use;
1113
1295
          }
1114
1296
        }
1122
1304
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1123
1305
                    keyinfo->key_parts);
1124
1306
      share->total_key_length+= keyinfo->key_length;
1125
 
 
1126
 
      if (keyinfo->flags & HA_NOSAME)
1127
 
      {
 
1307
      /*
 
1308
        MERGE tables do not have unique indexes. But every key could be
 
1309
        an unique index on the underlying MyISAM table. (Bug #10400)
 
1310
      */
 
1311
      if ((keyinfo->flags & HA_NOSAME) ||
 
1312
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1128
1313
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1129
 
      }
1130
1314
    }
1131
1315
    if (primary_key < MAX_KEY &&
1132
 
        (share->keys_in_use.test(primary_key)))
 
1316
        (share->keys_in_use.is_set(primary_key)))
1133
1317
    {
1134
1318
      share->primary_key= primary_key;
1135
1319
      /*
1136
 
        If we are using an integer as the primary key then allow the user to
1137
 
        refer to it as '_rowid'
 
1320
        If we are using an integer as the primary key then allow the user to
 
1321
        refer to it as '_rowid'
1138
1322
      */
1139
1323
      if (share->key_info[primary_key].key_parts == 1)
1140
1324
      {
1141
 
        Field *field= share->key_info[primary_key].key_part[0].field;
1142
 
        if (field && field->result_type() == INT_RESULT)
 
1325
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1326
        if (field && field->result_type() == INT_RESULT)
1143
1327
        {
1144
1328
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1145
 
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1329
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1146
1330
                                      fieldnr);
1147
1331
        }
1148
1332
      }
 
1333
 
1149
1334
    }
1150
1335
    else
1151
1336
      share->primary_key = MAX_KEY; // we do not have a primary key
1180
1365
          (uint*) alloc_root(&share->mem_root,
1181
1366
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1182
1367
      goto err;
1183
 
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
 
1368
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1184
1369
    {
1185
1370
      if ((*ptr)->flags & BLOB_FLAG)
1186
 
        (*save++)= k;
 
1371
        (*save++)= k;
1187
1372
    }
1188
1373
  }
1189
1374
 
1190
 
  share->db_low_byte_first= true; // @todo Question this.
 
1375
  share->db_low_byte_first= handler_file->low_byte_first();
1191
1376
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1192
1377
 
1193
1378
  my_bitmap_map *bitmaps;
1195
1380
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1196
1381
                                             share->column_bitmap_size)))
1197
1382
    goto err;
1198
 
  share->all_set.init(bitmaps, share->fields);
1199
 
  share->all_set.setAll();
 
1383
  share->all_set.set();
1200
1384
 
 
1385
  if(handler_file)
 
1386
    delete handler_file;
1201
1387
  return (0);
1202
1388
 
1203
1389
err:
1204
 
  if (field_offsets)
1205
 
    free(field_offsets);
1206
 
  if (field_pack_length)
1207
 
    free(field_pack_length);
1208
 
 
1209
1390
  share->error= error;
1210
 
  share->open_errno= errno;
 
1391
  share->open_errno= my_errno;
1211
1392
  share->errarg= 0;
1212
1393
  hash_free(&share->name_hash);
1213
 
  share->open_table_error(error, share->open_errno, 0);
1214
 
 
 
1394
  if(handler_file)
 
1395
    delete handler_file;
 
1396
  open_table_error(share, error, share->open_errno, 0);
1215
1397
  return error;
1216
1398
}
1217
1399
 
1218
1400
/*
1219
 
  Read table definition from a binary / text based .frm cursor
 
1401
  Read table definition from a binary / text based .frm file
1220
1402
 
1221
1403
  SYNOPSIS
1222
1404
  open_table_def()
1223
 
  session               Thread Cursor
 
1405
  session               Thread handler
1224
1406
  share         Fill this with table definition
 
1407
  db_flags      Bit mask of the following flags: OPEN_VIEW
1225
1408
 
1226
1409
  NOTES
1227
1410
    This function is called when the table definition is not cached in
1233
1416
   0    ok
1234
1417
   1    Error (see open_table_error)
1235
1418
   2    Error (see open_table_error)
1236
 
   3    Wrong data in .frm cursor
 
1419
   3    Wrong data in .frm file
1237
1420
   4    Error (see open_table_error)
1238
1421
   5    Error (see open_table_error: charset unavailable)
1239
1422
   6    Unknown .frm version
1240
1423
*/
1241
1424
 
1242
 
int open_table_def(Session& session, TableIdentifier &identifier, TableShare *share)
 
1425
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
1243
1426
{
1244
1427
  int error;
1245
1428
  bool error_given;
 
1429
  string proto_path("");
1246
1430
 
1247
1431
  error= 1;
1248
1432
  error_given= 0;
1249
1433
 
1250
 
  message::Table table;
1251
 
 
1252
 
  error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1253
 
 
1254
 
  if (error != EEXIST)
 
1434
  proto_path.reserve(FN_REFLEN);
 
1435
  proto_path.append(share->normalized_path.str);
 
1436
 
 
1437
  proto_path.append(".dfe");
 
1438
 
 
1439
  drizzled::message::Table table;
 
1440
 
 
1441
  if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
1255
1442
  {
1256
 
    if (error > 0)
 
1443
    if(error>0)
1257
1444
    {
1258
 
      errno= error;
 
1445
      my_errno= error;
1259
1446
      error= 1;
1260
1447
    }
1261
1448
    else
1262
1449
    {
1263
 
      if (not table.IsInitialized())
 
1450
      if(!table.IsInitialized())
1264
1451
      {
1265
1452
        error= 4;
1266
1453
      }
1270
1457
 
1271
1458
  error= parse_table_proto(session, table, share);
1272
1459
 
1273
 
  share->table_category= TABLE_CATEGORY_USER;
 
1460
  share->table_category= get_table_category(& share->db, & share->table_name);
 
1461
 
 
1462
  if (!error)
 
1463
    session->status_var.opened_shares++;
1274
1464
 
1275
1465
err_not_open:
1276
1466
  if (error && !error_given)
1277
1467
  {
1278
1468
    share->error= error;
1279
 
    share->open_table_error(error, (share->open_errno= errno), 0);
 
1469
    open_table_error(share, error, (share->open_errno= my_errno), 0);
1280
1470
  }
1281
1471
 
1282
1472
  return(error);
1283
1473
}
1284
1474
 
1285
 
 
1286
 
/*
1287
 
  Open a table based on a TableShare
 
1475
/*
 
1476
  Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
 
1477
  This routine is used for error handling purposes.
 
1478
 
 
1479
  SYNOPSIS
 
1480
    clear_field_flag()
 
1481
    table                Table object for which virtual columns are set-up
 
1482
 
 
1483
  RETURN VALUE
 
1484
    NONE
 
1485
*/
 
1486
static void clear_field_flag(Table *table)
 
1487
{
 
1488
  Field **ptr;
 
1489
 
 
1490
  for (ptr= table->field; *ptr; ptr++)
 
1491
    (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
 
1492
}
 
1493
 
 
1494
/*
 
1495
  The function uses the feature in fix_fields where the flag
 
1496
  GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
 
1497
  This field must always be reset before returning from the function
 
1498
  since it is used for other purposes as well.
 
1499
 
 
1500
  SYNOPSIS
 
1501
    fix_fields_vcol_func()
 
1502
    session                  The thread object
 
1503
    func_item            The item tree reference of the virtual columnfunction
 
1504
    table                The table object
 
1505
    field_name           The name of the processed field
 
1506
 
 
1507
  RETURN VALUE
 
1508
    true                 An error occurred, something was wrong with the
 
1509
                         function.
 
1510
    false                Ok, a partition field array was created
 
1511
*/
 
1512
 
 
1513
bool fix_fields_vcol_func(Session *session,
 
1514
                          Item* func_expr,
 
1515
                          Table *table,
 
1516
                          const char *field_name)
 
1517
{
 
1518
  uint32_t dir_length, home_dir_length;
 
1519
  bool result= true;
 
1520
  TableList tables;
 
1521
  TableList *save_table_list, *save_first_table, *save_last_table;
 
1522
  int error;
 
1523
  Name_resolution_context *context;
 
1524
  const char *save_where;
 
1525
  char* db_name;
 
1526
  char db_name_string[FN_REFLEN];
 
1527
  bool save_use_only_table_context;
 
1528
  Field **ptr, *field;
 
1529
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
 
1530
  assert(func_expr);
 
1531
 
 
1532
  /*
 
1533
    Set-up the TABLE_LIST object to be a list with a single table
 
1534
    Set the object to zero to create NULL pointers and set alias
 
1535
    and real name to table name and get database name from file name.
 
1536
  */
 
1537
 
 
1538
  bzero((void*)&tables, sizeof(TableList));
 
1539
  tables.alias= tables.table_name= (char*) table->s->table_name.str;
 
1540
  tables.table= table;
 
1541
  tables.next_local= NULL;
 
1542
  tables.next_name_resolution_table= NULL;
 
1543
  memcpy(db_name_string,
 
1544
         table->s->normalized_path.str,
 
1545
         table->s->normalized_path.length);
 
1546
  db_name_string[table->s->normalized_path.length]= '\0';
 
1547
  dir_length= dirname_length(db_name_string);
 
1548
  db_name_string[dir_length - 1]= 0;
 
1549
  home_dir_length= dirname_length(db_name_string);
 
1550
  db_name= &db_name_string[home_dir_length];
 
1551
  tables.db= db_name;
 
1552
 
 
1553
  session->mark_used_columns= MARK_COLUMNS_NONE;
 
1554
 
 
1555
  context= session->lex->current_context();
 
1556
  table->map= 1; //To ensure correct calculation of const item
 
1557
  table->get_fields_in_item_tree= true;
 
1558
  save_table_list= context->table_list;
 
1559
  save_first_table= context->first_name_resolution_table;
 
1560
  save_last_table= context->last_name_resolution_table;
 
1561
  context->table_list= &tables;
 
1562
  context->first_name_resolution_table= &tables;
 
1563
  context->last_name_resolution_table= NULL;
 
1564
  func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
 
1565
  save_where= session->where;
 
1566
  session->where= "virtual column function";
 
1567
 
 
1568
  /* Save the context before fixing the fields*/
 
1569
  save_use_only_table_context= session->lex->use_only_table_context;
 
1570
  session->lex->use_only_table_context= true;
 
1571
  /* Fix fields referenced to by the virtual column function */
 
1572
  error= func_expr->fix_fields(session, (Item**)0);
 
1573
  /* Restore the original context*/
 
1574
  session->lex->use_only_table_context= save_use_only_table_context;
 
1575
  context->table_list= save_table_list;
 
1576
  context->first_name_resolution_table= save_first_table;
 
1577
  context->last_name_resolution_table= save_last_table;
 
1578
 
 
1579
  if (unlikely(error))
 
1580
  {
 
1581
    clear_field_flag(table);
 
1582
    goto end;
 
1583
  }
 
1584
  session->where= save_where;
 
1585
  /*
 
1586
    Walk through the Item tree checking if all items are valid
 
1587
   to be part of the virtual column
 
1588
 */
 
1589
  error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
 
1590
  if (error)
 
1591
  {
 
1592
    my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
 
1593
    clear_field_flag(table);
 
1594
    goto end;
 
1595
  }
 
1596
  if (unlikely(func_expr->const_item()))
 
1597
  {
 
1598
    my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
 
1599
    clear_field_flag(table);
 
1600
    goto end;
 
1601
  }
 
1602
  /* Ensure that this virtual column is not based on another virtual field. */
 
1603
  ptr= table->field;
 
1604
  while ((field= *(ptr++)))
 
1605
  {
 
1606
    if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
 
1607
        (field->vcol_info))
 
1608
    {
 
1609
      my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
 
1610
      clear_field_flag(table);
 
1611
      goto end;
 
1612
    }
 
1613
  }
 
1614
  /*
 
1615
    Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
 
1616
    when calling fix_fields.
 
1617
  */
 
1618
  clear_field_flag(table);
 
1619
  result= false;
 
1620
 
 
1621
end:
 
1622
  table->get_fields_in_item_tree= false;
 
1623
  session->mark_used_columns= save_mark_used_columns;
 
1624
  table->map= 0; //Restore old value
 
1625
  return(result);
 
1626
}
 
1627
 
 
1628
/*
 
1629
  Unpack the definition of a virtual column
 
1630
 
 
1631
  SYNOPSIS
 
1632
    unpack_vcol_info_from_frm()
 
1633
    session                  Thread handler
 
1634
    table                Table with the checked field
 
1635
    field                Pointer to Field object
 
1636
    open_mode            Open table mode needed to determine
 
1637
                         which errors need to be generated in a failure
 
1638
    error_reported       updated flag for the caller that no other error
 
1639
                         messages are to be generated.
 
1640
 
 
1641
  RETURN VALUES
 
1642
    true            Failure
 
1643
    false           Success
 
1644
*/
 
1645
bool unpack_vcol_info_from_frm(Session *session,
 
1646
                               Table *table,
 
1647
                               Field *field,
 
1648
                               LEX_STRING *vcol_expr,
 
1649
                               open_table_mode open_mode,
 
1650
                               bool *error_reported)
 
1651
{
 
1652
  assert(vcol_expr);
 
1653
 
 
1654
  /*
 
1655
    Step 1: Construct a statement for the parser.
 
1656
    The parsed string needs to take the following format:
 
1657
    "PARSE_VCOL_EXPR (<expr_string_from_frm>)"
 
1658
  */
 
1659
  char *vcol_expr_str;
 
1660
  int str_len= 0;
 
1661
 
 
1662
  if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
 
1663
                                          vcol_expr->length +
 
1664
                                            parse_vcol_keyword.length + 3)))
 
1665
  {
 
1666
    return(true);
 
1667
  }
 
1668
  memcpy(vcol_expr_str,
 
1669
         (char*) parse_vcol_keyword.str,
 
1670
         parse_vcol_keyword.length);
 
1671
  str_len= parse_vcol_keyword.length;
 
1672
  memcpy(vcol_expr_str + str_len, "(", 1);
 
1673
  str_len++;
 
1674
  memcpy(vcol_expr_str + str_len,
 
1675
         (char*) vcol_expr->str,
 
1676
         vcol_expr->length);
 
1677
  str_len+= vcol_expr->length;
 
1678
  memcpy(vcol_expr_str + str_len, ")", 1);
 
1679
  str_len++;
 
1680
  memcpy(vcol_expr_str + str_len, "\0", 1);
 
1681
  str_len++;
 
1682
  Lex_input_stream lip(session, vcol_expr_str, str_len);
 
1683
 
 
1684
  /*
 
1685
    Step 2: Setup session for parsing.
 
1686
    1) make Item objects be created in the memory allocated for the Table
 
1687
       object (not TABLE_SHARE)
 
1688
    2) ensure that created Item's are not put on to session->free_list
 
1689
       (which is associated with the parsed statement and hence cleared after
 
1690
       the parsing)
 
1691
    3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
 
1692
       to be parsed as a SQL command.
 
1693
  */
 
1694
  MEM_ROOT **root_ptr, *old_root;
 
1695
  Item *backup_free_list= session->free_list;
 
1696
  root_ptr= current_mem_root_ptr();
 
1697
  old_root= *root_ptr;
 
1698
  *root_ptr= &table->mem_root;
 
1699
  session->free_list= NULL;
 
1700
  session->lex->parse_vcol_expr= true;
 
1701
 
 
1702
  /*
 
1703
    Step 3: Use the parser to build an Item object from.
 
1704
  */
 
1705
  if (parse_sql(session, &lip))
 
1706
  {
 
1707
    goto parse_err;
 
1708
  }
 
1709
  /* From now on use vcol_info generated by the parser. */
 
1710
  field->vcol_info= session->lex->vcol_info;
 
1711
 
 
1712
  /* Validate the Item tree. */
 
1713
  if (fix_fields_vcol_func(session,
 
1714
                           field->vcol_info->expr_item,
 
1715
                           table,
 
1716
                           field->field_name))
 
1717
  {
 
1718
    if (open_mode == OTM_CREATE)
 
1719
    {
 
1720
      /*
 
1721
        During CREATE/ALTER TABLE it is ok to receive errors here.
 
1722
        It is not ok if it happens during the opening of an frm
 
1723
        file as part of a normal query.
 
1724
      */
 
1725
      *error_reported= true;
 
1726
    }
 
1727
    field->vcol_info= NULL;
 
1728
    goto parse_err;
 
1729
  }
 
1730
  field->vcol_info->item_free_list= session->free_list;
 
1731
  session->free_list= backup_free_list;
 
1732
  *root_ptr= old_root;
 
1733
 
 
1734
  return(false);
 
1735
 
 
1736
parse_err:
 
1737
  session->lex->parse_vcol_expr= false;
 
1738
  session->free_items();
 
1739
  *root_ptr= old_root;
 
1740
  session->free_list= backup_free_list;
 
1741
  return(true);
 
1742
}
 
1743
 
 
1744
 
 
1745
/*
 
1746
  Open a table based on a TABLE_SHARE
1288
1747
 
1289
1748
  SYNOPSIS
1290
1749
    open_table_from_share()
1291
 
    session                     Thread Cursor
 
1750
    session                     Thread handler
1292
1751
    share               Table definition
1293
1752
    alias               Alias for table
1294
1753
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1295
1754
                        HA_OPEN_RNDFILE..) can be 0 (example in
1296
1755
                        ha_example_table)
 
1756
    prgflag             READ_ALL etc..
1297
1757
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
1298
1758
    outparam            result table
 
1759
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
 
1760
                        if OTM_CREATE some errors are ignore
 
1761
                        if OTM_ALTER HA_OPEN is not called
1299
1762
 
1300
1763
  RETURN VALUES
1301
1764
   0    ok
1302
1765
   1    Error (see open_table_error)
1303
1766
   2    Error (see open_table_error)
1304
 
   3    Wrong data in .frm cursor
 
1767
   3    Wrong data in .frm file
1305
1768
   4    Error (see open_table_error)
1306
1769
   5    Error (see open_table_error: charset unavailable)
1307
1770
   7    Table definition has changed in engine
1308
1771
*/
1309
1772
 
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)
 
1773
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
 
1774
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
 
1775
                          Table *outparam, open_table_mode open_mode)
1313
1776
{
1314
1777
  int error;
1315
 
  uint32_t records, i, bitmap_size;
 
1778
  uint32_t records, i;
1316
1779
  bool error_reported= false;
1317
 
  unsigned char *record, *bitmaps;
1318
 
  Field **field_ptr;
 
1780
  unsigned char *record;
 
1781
  Field **field_ptr, **vfield_ptr;
1319
1782
 
1320
1783
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1321
1784
  assert(session->lex->is_lex_started);
1322
1785
 
1323
1786
  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;
 
1787
  memset(outparam, 0, sizeof(*outparam));
 
1788
  outparam->in_use= session;
 
1789
  outparam->s= share;
 
1790
  outparam->db_stat= db_stat;
 
1791
  outparam->write_row_record= NULL;
 
1792
 
 
1793
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
1794
 
 
1795
  if (!(outparam->alias= strdup(alias)))
 
1796
    goto err;
 
1797
  outparam->quick_keys.init();
 
1798
  outparam->covering_keys.init();
 
1799
  outparam->keys_in_use_for_query.init();
 
1800
 
 
1801
  /* Allocate handler */
 
1802
  outparam->file= 0;
 
1803
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
 
1804
  {
 
1805
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
 
1806
                                          share->db_type())))
 
1807
      goto err;
 
1808
  }
 
1809
  else
 
1810
  {
 
1811
    assert(!db_stat);
 
1812
  }
1333
1813
 
1334
1814
  error= 4;
1335
 
  records= 0;
1336
 
  if ((db_stat & HA_OPEN_KEYFILE))
 
1815
  outparam->reginfo.lock_type= TL_UNLOCK;
 
1816
  outparam->current_lock= F_UNLCK;
 
1817
  records=0;
 
1818
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1337
1819
    records=1;
1338
 
 
1339
 
  records++;
 
1820
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
1821
    records++;
1340
1822
 
1341
1823
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1342
1824
                                   share->rec_buff_length * records)))
1343
 
    goto err;
 
1825
    goto err;                                   /* purecov: inspected */
1344
1826
 
1345
1827
  if (records == 0)
1346
1828
  {
1374
1856
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1375
1857
                                          (uint32_t) ((share->fields+1)*
1376
1858
                                                  sizeof(Field*)))))
1377
 
    goto err;
 
1859
    goto err;                                   /* purecov: inspected */
1378
1860
 
1379
1861
  outparam->field= field_ptr;
1380
1862
 
1383
1865
  outparam->null_flags= (unsigned char*) record+1;
1384
1866
 
1385
1867
  /* Setup copy of fields from share, but use the right alias and record */
1386
 
  for (i= 0 ; i < share->fields; i++, field_ptr++)
 
1868
  for (i=0 ; i < share->fields; i++, field_ptr++)
1387
1869
  {
1388
1870
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1389
1871
      goto err;
1443
1925
    }
1444
1926
  }
1445
1927
 
 
1928
  /*
 
1929
    Process virtual columns, if any.
 
1930
  */
 
1931
  if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1932
                                              (uint32_t) ((share->vfields+1)*
 
1933
                                                      sizeof(Field*)))))
 
1934
    goto err;
 
1935
 
 
1936
  outparam->vfield= vfield_ptr;
 
1937
 
 
1938
  for (field_ptr= outparam->field; *field_ptr; field_ptr++)
 
1939
  {
 
1940
    if ((*field_ptr)->vcol_info)
 
1941
    {
 
1942
      if (unpack_vcol_info_from_frm(session,
 
1943
                                    outparam,
 
1944
                                    *field_ptr,
 
1945
                                    &(*field_ptr)->vcol_info->expr_str,
 
1946
                                    open_mode,
 
1947
                                    &error_reported))
 
1948
      {
 
1949
        error= 4; // in case no error is reported
 
1950
        goto err;
 
1951
      }
 
1952
      *(vfield_ptr++)= *field_ptr;
 
1953
    }
 
1954
  }
 
1955
  *vfield_ptr= NULL;                              // End marker
 
1956
  /* Check virtual columns against table's storage engine. */
 
1957
  if ((share->vfields && outparam->file) &&
 
1958
        (not outparam->file->check_if_supported_virtual_columns()))
 
1959
  {
 
1960
    my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
1961
             MYF(0),
 
1962
             "Specified storage engine");
 
1963
    error_reported= true;
 
1964
    goto err;
 
1965
  }
 
1966
 
1446
1967
  /* Allocate bitmaps */
1447
 
 
1448
 
  bitmap_size= share->column_bitmap_size;
1449
 
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1450
 
    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);
1454
1968
  outparam->default_column_bitmaps();
1455
1969
 
1456
1970
  /* The table struct is now initialized;  Open the table */
1457
1971
  error= 2;
1458
 
  if (db_stat)
 
1972
  if (db_stat && open_mode != OTM_ALTER)
1459
1973
  {
1460
1974
    int ha_err;
1461
 
    if ((ha_err= (outparam->cursor->
 
1975
    if ((ha_err= (outparam->file->
1462
1976
                  ha_open(outparam, share->normalized_path.str,
1463
1977
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1464
1978
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1467
1981
                          HA_OPEN_ABORT_IF_LOCKED :
1468
1982
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1469
1983
    {
 
1984
      /* Set a flag if the table is crashed and it can be auto. repaired */
 
1985
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
 
1986
                       outparam->file->auto_repair() &&
 
1987
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
 
1988
 
1470
1989
      switch (ha_err)
1471
1990
      {
1472
1991
        case HA_ERR_NO_SUCH_TABLE:
1473
1992
          /*
1474
1993
            The table did not exists in storage engine, use same error message
1475
 
            as if the .frm cursor didn't exist
 
1994
            as if the .frm file didn't exist
1476
1995
          */
1477
1996
          error= 1;
1478
 
          errno= ENOENT;
 
1997
          my_errno= ENOENT;
1479
1998
          break;
1480
1999
        case EMFILE:
1481
2000
          /*
1482
2001
            Too many files opened, use same error message as if the .frm
1483
 
            cursor can't open
 
2002
            file can't open
1484
2003
           */
1485
2004
          error= 1;
1486
 
          errno= EMFILE;
 
2005
          my_errno= EMFILE;
1487
2006
          break;
1488
2007
        default:
1489
 
          outparam->print_error(ha_err, MYF(0));
 
2008
          outparam->file->print_error(ha_err, MYF(0));
1490
2009
          error_reported= true;
1491
2010
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1492
2011
            error= 7;
1493
2012
          break;
1494
2013
      }
1495
 
      goto err;
 
2014
      goto err;                                 /* purecov: inspected */
1496
2015
    }
1497
2016
  }
1498
2017
 
1500
2019
  memset(bitmaps, 0, bitmap_size*3);
1501
2020
#endif
1502
2021
 
1503
 
  return 0;
 
2022
  outparam->no_replicate= outparam->file;
 
2023
  session->status_var.opened_tables++;
 
2024
 
 
2025
  return (0);
1504
2026
 
1505
2027
 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;
 
2028
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
 
2029
    open_table_error(share, error, my_errno, 0);
 
2030
  delete outparam->file;
 
2031
  outparam->file= 0;                            // For easier error checking
 
2032
  outparam->db_stat=0;
1511
2033
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1512
2034
  free((char*) outparam->alias);
1513
2035
  return (error);
1514
2036
}
1515
2037
 
1516
 
bool Table::fill_item_list(List<Item> *item_list) const
 
2038
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
 
2039
uint32_t  Table::tmpkeyval()
1517
2040
{
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;
 
2041
  return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
1529
2042
}
1530
2043
 
 
2044
/*
 
2045
  Free information allocated by openfrm
 
2046
 
 
2047
  SYNOPSIS
 
2048
    closefrm()
 
2049
    table               Table object to free
 
2050
    free_share          Is 1 if we also want to free table_share
 
2051
*/
 
2052
 
1531
2053
int Table::closefrm(bool free_share)
1532
2054
{
1533
 
  int error= 0;
 
2055
  int error=0;
1534
2056
 
1535
2057
  if (db_stat)
1536
 
    error= cursor->close();
 
2058
    error= file->close();
1537
2059
  free((char*) alias);
1538
2060
  alias= NULL;
1539
2061
  if (field)
1542
2064
      delete *ptr;
1543
2065
    field= 0;
1544
2066
  }
1545
 
  delete cursor;
1546
 
  cursor= 0;                            /* For easier errorchecking */
 
2067
  delete file;
 
2068
  file= 0;                              /* For easier errorchecking */
1547
2069
  if (free_share)
1548
2070
  {
1549
 
    if (s->tmp_table == message::Table::STANDARD)
1550
 
      TableShare::release(s);
 
2071
    if (s->tmp_table == NO_TMP_TABLE)
 
2072
      release_table_share(s, RELEASE_NORMAL);
1551
2073
    else
1552
 
      s->free_table_share();
 
2074
      free_table_share(s);
1553
2075
  }
1554
2076
  free_root(&mem_root, MYF(0));
1555
2077
 
1557
2079
}
1558
2080
 
1559
2081
 
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
2082
/* Deallocate temporary blob storage */
1649
2083
 
1650
2084
void free_blobs(register Table *table)
1657
2091
}
1658
2092
 
1659
2093
 
1660
 
        /* error message when opening a form cursor */
1661
 
 
1662
 
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
 
2094
        /* Find where a form starts */
 
2095
        /* if formname is NULL then only formnames is read */
 
2096
 
 
2097
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
 
2098
{
 
2099
  uint32_t a_length,names,length;
 
2100
  unsigned char *pos,*buf;
 
2101
  ulong ret_value=0;
 
2102
 
 
2103
  names=uint2korr(head+8);
 
2104
  a_length=(names+2)*sizeof(char *);            /* Room for two extra */
 
2105
 
 
2106
  if (!save_names)
 
2107
    a_length=0;
 
2108
  else
 
2109
    save_names->type_names=0;                   /* Clear if error */
 
2110
 
 
2111
  if (names)
 
2112
  {
 
2113
    length=uint2korr(head+4);
 
2114
    lseek(file,64,SEEK_SET);
 
2115
    if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
 
2116
        my_read(file, buf+a_length, (size_t) (length+names*4),
 
2117
                MYF(MY_NABP)))
 
2118
    {                                           /* purecov: inspected */
 
2119
      if (buf)
 
2120
        free(buf);
 
2121
      return(0L);                               /* purecov: inspected */
 
2122
    }
 
2123
    pos= buf+a_length+length;
 
2124
    ret_value=uint4korr(pos);
 
2125
  }
 
2126
  if (! save_names)
 
2127
  {
 
2128
    if (names)
 
2129
      free((unsigned char*) buf);
 
2130
  }
 
2131
  else if (!names)
 
2132
    memset(save_names, 0, sizeof(save_names));
 
2133
  else
 
2134
  {
 
2135
    char *str;
 
2136
    str=(char *) (buf+a_length);
 
2137
    fix_type_pointers((const char ***) &buf,save_names,1,&str);
 
2138
  }
 
2139
  return(ret_value);
 
2140
}
 
2141
 
 
2142
 
 
2143
/*
 
2144
  Read string from a file with malloc
 
2145
 
 
2146
  NOTES:
 
2147
    We add an \0 at end of the read string to make reading of C strings easier
 
2148
*/
 
2149
 
 
2150
int read_string(File file, unsigned char**to, size_t length)
 
2151
{
 
2152
 
 
2153
  if (*to)
 
2154
    free(*to);
 
2155
  if (!(*to= (unsigned char*) malloc(length+1)) ||
 
2156
      my_read(file, *to, length,MYF(MY_NABP)))
 
2157
  {
 
2158
    if (*to)
 
2159
      free(*to);
 
2160
    *to= NULL;
 
2161
    return(1);                           /* purecov: inspected */
 
2162
  }
 
2163
  *((char*) *to+length)= '\0';
 
2164
  return (0);
 
2165
} /* read_string */
 
2166
 
 
2167
 
 
2168
        /* Add a new form to a form file */
 
2169
 
 
2170
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
 
2171
                     const char *newname)
 
2172
{
 
2173
  uint32_t i,bufflength,maxlength,n_length,length,names;
 
2174
  off_t endpos,newpos;
 
2175
  unsigned char buff[IO_SIZE];
 
2176
  unsigned char *pos;
 
2177
 
 
2178
  length=(uint32_t) strlen(newname)+1;
 
2179
  n_length=uint2korr(fileinfo+4);
 
2180
  maxlength=uint2korr(fileinfo+6);
 
2181
  names=uint2korr(fileinfo+8);
 
2182
  newpos=uint4korr(fileinfo+10);
 
2183
 
 
2184
  if (64+length+n_length+(names+1)*4 > maxlength)
 
2185
  {                                             /* Expand file */
 
2186
    newpos+=IO_SIZE;
 
2187
    int4store(fileinfo+10,newpos);
 
2188
    endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
 
2189
    bufflength= (uint32_t) (endpos & (IO_SIZE-1));      /* IO_SIZE is a power of 2 */
 
2190
 
 
2191
    while (endpos > maxlength)
 
2192
    {
 
2193
      lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
 
2194
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
 
2195
        return(0L);
 
2196
      lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
 
2197
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
 
2198
        return(0);
 
2199
      endpos-=bufflength; bufflength=IO_SIZE;
 
2200
    }
 
2201
    memset(buff, 0, IO_SIZE);                   /* Null new block */
 
2202
    lseek(file,(ulong) maxlength,SEEK_SET);
 
2203
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
 
2204
      return(0L);
 
2205
    maxlength+=IO_SIZE;                         /* Fix old ref */
 
2206
    int2store(fileinfo+6,maxlength);
 
2207
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
 
2208
         pos+=4)
 
2209
    {
 
2210
      endpos=uint4korr(pos)+IO_SIZE;
 
2211
      int4store(pos,endpos);
 
2212
    }
 
2213
  }
 
2214
 
 
2215
  if (n_length == 1 )
 
2216
  {                                             /* First name */
 
2217
    length++;
 
2218
    sprintf((char*)buff,"/%s/",newname);
 
2219
  }
 
2220
  else
 
2221
    sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
 
2222
  lseek(file, 63 + n_length,SEEK_SET);
 
2223
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
 
2224
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
 
2225
                         names*4, MYF(MY_NABP+MY_WME))) ||
 
2226
      my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
 
2227
    return(0L); /* purecov: inspected */
 
2228
 
 
2229
  int2store(fileinfo+8,names+1);
 
2230
  int2store(fileinfo+4,n_length+length);
 
2231
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
 
2232
  return(newpos);
 
2233
} /* make_new_entry */
 
2234
 
 
2235
 
 
2236
        /* error message when opening a form file */
 
2237
 
 
2238
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
1663
2239
{
1664
2240
  int err_no;
1665
2241
  char buff[FN_REFLEN];
1666
2242
  myf errortype= ME_ERROR+ME_WAITTANG;
1667
2243
 
1668
 
  switch (pass_error) {
 
2244
  switch (error) {
1669
2245
  case 7:
1670
2246
  case 1:
1671
2247
    if (db_errno == ENOENT)
1672
 
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
 
2248
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1673
2249
    else
1674
2250
    {
1675
 
      snprintf(buff, sizeof(buff), "%s",normalized_path.str);
 
2251
      sprintf(buff,"%s",share->normalized_path.str);
1676
2252
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1677
2253
               errortype, buff, db_errno);
1678
2254
    }
1679
2255
    break;
1680
2256
  case 2:
1681
2257
  {
1682
 
    Cursor *cursor= 0;
 
2258
    handler *file= 0;
1683
2259
    const char *datext= "";
1684
2260
 
1685
 
    if (db_type() != NULL)
 
2261
    if (share->db_type() != NULL)
1686
2262
    {
1687
 
      if ((cursor= db_type()->getCursor(*this, current_session->mem_root)))
 
2263
      if ((file= get_new_handler(share, current_session->mem_root,
 
2264
                                 share->db_type())))
1688
2265
      {
1689
 
        if (!(datext= *db_type()->bas_ext()))
 
2266
        if (!(datext= *file->bas_ext()))
1690
2267
          datext= "";
1691
2268
      }
1692
2269
    }
1693
2270
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1694
2271
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1695
 
    snprintf(buff, sizeof(buff), "%s%s", normalized_path.str,datext);
 
2272
    sprintf(buff,"%s%s", share->normalized_path.str,datext);
1696
2273
    my_error(err_no,errortype, buff, db_errno);
1697
 
    delete cursor;
 
2274
    delete file;
1698
2275
    break;
1699
2276
  }
1700
2277
  case 5:
1701
2278
  {
1702
 
    const char *csname= get_charset_name((uint32_t) pass_errarg);
 
2279
    const char *csname= get_charset_name((uint32_t) errarg);
1703
2280
    char tmp[10];
1704
2281
    if (!csname || csname[0] =='?')
1705
2282
    {
1706
 
      snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
 
2283
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
1707
2284
      csname= tmp;
1708
2285
    }
1709
2286
    my_printf_error(ER_UNKNOWN_COLLATION,
1710
2287
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1711
 
                    MYF(0), csname, table_name.str);
 
2288
                    MYF(0), csname, share->table_name.str);
1712
2289
    break;
1713
2290
  }
1714
2291
  case 6:
1715
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
 
2292
    sprintf(buff,"%s",share->normalized_path.str);
1716
2293
    my_printf_error(ER_NOT_FORM_FILE,
1717
2294
                    _("Table '%-.64s' was created with a different version "
1718
2295
                    "of Drizzle and cannot be read"),
1722
2299
    break;
1723
2300
  default:                              /* Better wrong error than none */
1724
2301
  case 4:
1725
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
 
2302
    sprintf(buff,"%s",share->normalized_path.str);
1726
2303
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1727
2304
    break;
1728
2305
  }
1730
2307
} /* open_table_error */
1731
2308
 
1732
2309
 
1733
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
 
2310
        /*
 
2311
        ** fix a str_type to a array type
 
2312
        ** typeparts separated with some char. differents types are separated
 
2313
        ** with a '\0'
 
2314
        */
 
2315
 
 
2316
static void
 
2317
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
 
2318
                  char **names)
 
2319
{
 
2320
  char *type_name, *ptr;
 
2321
  char chr;
 
2322
 
 
2323
  ptr= *names;
 
2324
  while (types--)
 
2325
  {
 
2326
    point_to_type->name=0;
 
2327
    point_to_type->type_names= *array;
 
2328
 
 
2329
    if ((chr= *ptr))                    /* Test if empty type */
 
2330
    {
 
2331
      while ((type_name=strchr(ptr+1,chr)) != NULL)
 
2332
      {
 
2333
        *((*array)++) = ptr+1;
 
2334
        *type_name= '\0';               /* End string */
 
2335
        ptr=type_name;
 
2336
      }
 
2337
      ptr+=2;                           /* Skip end mark and last 0 */
 
2338
    }
 
2339
    else
 
2340
      ptr++;
 
2341
    point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
 
2342
    point_to_type++;
 
2343
    *((*array)++)= NULL;                /* End of type */
 
2344
  }
 
2345
  *names=ptr;                           /* Update end */
 
2346
  return;
 
2347
} /* fix_type_pointers */
 
2348
 
 
2349
 
 
2350
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1734
2351
{
1735
2352
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
1736
2353
  if (!result)
1737
2354
    return 0;
1738
 
  result->count= strings.elements;
1739
 
  result->name= "";
 
2355
  result->count=strings.elements;
 
2356
  result->name="";
1740
2357
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
1741
 
  
1742
2358
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1743
2359
    return 0;
1744
 
    
1745
2360
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1746
 
 
1747
2361
  List_iterator<String> it(strings);
1748
2362
  String *tmp;
1749
 
  for (uint32_t i= 0; (tmp= it++); i++)
 
2363
  for (uint32_t i=0; (tmp=it++) ; i++)
1750
2364
  {
1751
2365
    result->type_names[i]= tmp->ptr();
1752
2366
    result->type_lengths[i]= tmp->length();
1753
2367
  }
1754
 
 
1755
 
  result->type_names[result->count]= 0;   // End marker
 
2368
  result->type_names[result->count]= 0;         // End marker
1756
2369
  result->type_lengths[result->count]= 0;
1757
 
 
1758
2370
  return result;
1759
2371
}
1760
2372
 
1801
2413
 
1802
2414
  for (; pos != end ; pos++)
1803
2415
  {
 
2416
#if defined(USE_MB)
1804
2417
    uint32_t mblen;
1805
2418
    if (use_mb(default_charset_info) &&
1806
2419
        (mblen= my_ismbchar(default_charset_info, pos, end)))
1811
2424
        break;
1812
2425
      continue;
1813
2426
    }
 
2427
#endif
1814
2428
 
1815
2429
    switch (*pos) {
1816
2430
    case 0:                             /* Must be escaped for 'mysql' */
1850
2464
    a tmp_set bitmap to be used by things like filesort.
1851
2465
*/
1852
2466
 
1853
 
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
2467
void Table::setup_tmp_table_column_bitmaps()
1854
2468
{
1855
 
  uint32_t field_count= s->fields;
1856
 
 
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);
1859
 
 
1860
2469
  /* write_set and all_set are copies of read_set */
1861
2470
  def_write_set= def_read_set;
1862
2471
  s->all_set= def_read_set;
1863
 
  this->s->all_set.setAll();
 
2472
  this->s->all_set.set();
1864
2473
  default_column_bitmaps();
 
2474
  read_set->set();
1865
2475
}
1866
2476
 
1867
2477
 
1868
2478
 
1869
 
void Table::updateCreateInfo(message::Table *table_proto)
 
2479
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
1870
2480
{
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());
 
2481
  create_info->max_rows= s->max_rows;
 
2482
  create_info->min_rows= s->min_rows;
 
2483
  create_info->table_options= s->db_create_options;
 
2484
  create_info->avg_row_length= s->avg_row_length;
 
2485
  create_info->block_size= s->block_size;
 
2486
  create_info->row_type= s->row_type;
 
2487
  create_info->default_table_charset= s->table_charset;
 
2488
  create_info->table_charset= 0;
 
2489
  create_info->comment= s->comment;
 
2490
 
 
2491
  return;
1874
2492
}
1875
2493
 
1876
2494
int rename_file_ext(const char * from,const char * to,const char * ext)
1881
2499
  from_s.append(ext);
1882
2500
  to_s.append(to);
1883
2501
  to_s.append(ext);
1884
 
  return (internal::my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
2502
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
2503
}
 
2504
 
 
2505
 
 
2506
/*
 
2507
  Allocate string field in MEM_ROOT and return it as String
 
2508
 
 
2509
  SYNOPSIS
 
2510
    get_field()
 
2511
    mem         MEM_ROOT for allocating
 
2512
    field       Field for retrieving of string
 
2513
    res         result String
 
2514
 
 
2515
  RETURN VALUES
 
2516
    1   string is empty
 
2517
    0   all ok
 
2518
*/
 
2519
 
 
2520
bool get_field(MEM_ROOT *mem, Field *field, String *res)
 
2521
{
 
2522
  char buff[MAX_FIELD_WIDTH], *to;
 
2523
  String str(buff,sizeof(buff),&my_charset_bin);
 
2524
  uint32_t length;
 
2525
 
 
2526
  field->val_str(&str);
 
2527
  if (!(length= str.length()))
 
2528
  {
 
2529
    res->length(0);
 
2530
    return 1;
 
2531
  }
 
2532
  if (!(to= strmake_root(mem, str.ptr(), length)))
 
2533
    length= 0;                                  // Safety fix
 
2534
  res->set(to, length, ((Field_str*)field)->charset());
 
2535
  return 0;
 
2536
}
 
2537
 
 
2538
 
 
2539
/*
 
2540
  Allocate string field in MEM_ROOT and return it as NULL-terminated string
 
2541
 
 
2542
  SYNOPSIS
 
2543
    get_field()
 
2544
    mem         MEM_ROOT for allocating
 
2545
    field       Field for retrieving of string
 
2546
 
 
2547
  RETURN VALUES
 
2548
    NULL  string is empty
 
2549
    #      pointer to NULL-terminated string value of field
 
2550
*/
 
2551
 
 
2552
char *get_field(MEM_ROOT *mem, Field *field)
 
2553
{
 
2554
  char buff[MAX_FIELD_WIDTH], *to;
 
2555
  String str(buff,sizeof(buff),&my_charset_bin);
 
2556
  uint32_t length;
 
2557
 
 
2558
  field->val_str(&str);
 
2559
  length= str.length();
 
2560
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
 
2561
    return NULL;
 
2562
  memcpy(to,str.ptr(),(uint32_t) length);
 
2563
  to[length]=0;
 
2564
  return to;
1885
2565
}
1886
2566
 
1887
2567
/*
1917
2597
    check_db_name()
1918
2598
    org_name            Name of database and length
1919
2599
 
 
2600
  NOTES
 
2601
    If lower_case_table_names is set then database is converted to lower case
 
2602
 
1920
2603
  RETURN
1921
 
    false error
1922
 
    true ok
 
2604
    0   ok
 
2605
    1   error
1923
2606
*/
1924
2607
 
1925
 
bool check_db_name(SchemaIdentifier &schema_identifier)
 
2608
bool check_db_name(LEX_STRING *org_name)
1926
2609
{
1927
 
  if (not plugin::Authorization::isAuthorized(current_session->getSecurityContext(), schema_identifier))
1928
 
  {
1929
 
    return false;
1930
 
  }
1931
 
 
1932
 
  return schema_identifier.isValid();
 
2610
  char *name= org_name->str;
 
2611
  uint32_t name_length= org_name->length;
 
2612
 
 
2613
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
 
2614
    return 1;
 
2615
 
 
2616
  if (lower_case_table_names && name != any_db)
 
2617
    my_casedn_str(files_charset_info, name);
 
2618
 
 
2619
  return check_identifier_name(org_name);
1933
2620
}
1934
2621
 
 
2622
 
1935
2623
/*
1936
2624
  Allow anything as a table name, as long as it doesn't contain an
1937
2625
  ' ' at the end
1938
2626
  returns 1 on error
1939
2627
*/
 
2628
 
 
2629
 
1940
2630
bool check_table_name(const char *name, uint32_t length)
1941
2631
{
1942
2632
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
1960
2650
 
1961
2651
  while (*name)
1962
2652
  {
 
2653
#if defined(USE_MB) && defined(USE_MB_IDENT)
1963
2654
    last_char_is_space= my_isspace(system_charset_info, *name);
1964
2655
    if (use_mb(system_charset_info))
1965
2656
    {
1974
2665
        continue;
1975
2666
      }
1976
2667
    }
 
2668
#else
 
2669
    last_char_is_space= *name==' ';
 
2670
#endif
1977
2671
    /*
1978
2672
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
1979
2673
      It is defined as 0xFF, which is a not valid byte in utf8.
1989
2683
}
1990
2684
 
1991
2685
 
 
2686
/**
 
2687
  Checks whether a table is intact. Should be done *just* after the table has
 
2688
  been opened.
 
2689
 
 
2690
  @param[in] table             The table to check
 
2691
  @param[in] table_f_count     Expected number of columns in the table
 
2692
  @param[in] table_def         Expected structure of the table (column name
 
2693
                               and type)
 
2694
 
 
2695
  @retval  false  OK
 
2696
  @retval  TRUE   There was an error. An error message is output
 
2697
                  to the error log.  We do not push an error
 
2698
                  message into the error stack because this
 
2699
                  function is currently only called at start up,
 
2700
                  and such errors never reach the user.
 
2701
*/
 
2702
 
 
2703
bool
 
2704
Table::table_check_intact(const uint32_t table_f_count,
 
2705
                          const TABLE_FIELD_W_TYPE *table_def)
 
2706
{
 
2707
  uint32_t i;
 
2708
  bool error= false;
 
2709
  bool fields_diff_count;
 
2710
 
 
2711
  fields_diff_count= (s->fields != table_f_count);
 
2712
  if (fields_diff_count)
 
2713
  {
 
2714
 
 
2715
    /* previous MySQL version */
 
2716
    if (DRIZZLE_VERSION_ID > s->mysql_version)
 
2717
    {
 
2718
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
 
2719
                      alias, table_f_count, s->fields,
 
2720
                      s->mysql_version, DRIZZLE_VERSION_ID);
 
2721
      return(true);
 
2722
    }
 
2723
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
 
2724
    {
 
2725
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
 
2726
                      table_f_count, s->fields);
 
2727
      return(true);
 
2728
    }
 
2729
    /*
 
2730
      Something has definitely changed, but we're running an older
 
2731
      version of MySQL with new system tables.
 
2732
      Let's check column definitions. If a column was added at
 
2733
      the end of the table, then we don't care much since such change
 
2734
      is backward compatible.
 
2735
    */
 
2736
  }
 
2737
  char buffer[STRING_BUFFER_USUAL_SIZE];
 
2738
  for (i=0 ; i < table_f_count; i++, table_def++)
 
2739
  {
 
2740
    String sql_type(buffer, sizeof(buffer), system_charset_info);
 
2741
    sql_type.length(0);
 
2742
    if (i < s->fields)
 
2743
    {
 
2744
      Field *cur_field= this->field[i];
 
2745
 
 
2746
      if (strncmp(cur_field->field_name, table_def->name.str,
 
2747
                  table_def->name.length))
 
2748
      {
 
2749
        /*
 
2750
          Name changes are not fatal, we use ordinal numbers to access columns.
 
2751
          Still this can be a sign of a tampered table, output an error
 
2752
          to the error log.
 
2753
        */
 
2754
        errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
 
2755
                        "expected column '%s' at position %d, found '%s'."),
 
2756
                        s->db.str, alias, table_def->name.str, i,
 
2757
                        cur_field->field_name);
 
2758
      }
 
2759
      cur_field->sql_type(sql_type);
 
2760
      /*
 
2761
        Generally, if column types don't match, then something is
 
2762
        wrong.
 
2763
 
 
2764
        However, we only compare column definitions up to the
 
2765
        length of the original definition, since we consider the
 
2766
        following definitions compatible:
 
2767
 
 
2768
        1. DATETIME and DATETIM
 
2769
        2. INT(11) and INT(11
 
2770
        3. SET('one', 'two') and SET('one', 'two', 'more')
 
2771
 
 
2772
        For SETs or ENUMs, if the same prefix is there it's OK to
 
2773
        add more elements - they will get higher ordinal numbers and
 
2774
        the new table definition is backward compatible with the
 
2775
        original one.
 
2776
       */
 
2777
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
 
2778
                  table_def->type.length - 1))
 
2779
      {
 
2780
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2781
                      _("Incorrect definition of table %s.%s: "
 
2782
                        "expected column '%s' at position %d to have type "
 
2783
                        "%s, found type %s."),
 
2784
                      s->db.str, alias,
 
2785
                      table_def->name.str, i, table_def->type.str,
 
2786
                      sql_type.c_ptr_safe());
 
2787
        error= true;
 
2788
      }
 
2789
      else if (table_def->cset.str && !cur_field->has_charset())
 
2790
      {
 
2791
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2792
                      _("Incorrect definition of table %s.%s: "
 
2793
                        "expected the type of column '%s' at position %d "
 
2794
                        "to have character set '%s' but the type has no "
 
2795
                        "character set."),
 
2796
                      s->db.str, alias,
 
2797
                      table_def->name.str, i, table_def->cset.str);
 
2798
        error= true;
 
2799
      }
 
2800
      else if (table_def->cset.str &&
 
2801
               strcmp(cur_field->charset()->csname, table_def->cset.str))
 
2802
      {
 
2803
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2804
                      _("Incorrect definition of table %s.%s: "
 
2805
                        "expected the type of column '%s' at position %d "
 
2806
                        "to have character set '%s' but found "
 
2807
                        "character set '%s'."),
 
2808
                      s->db.str, alias,
 
2809
                      table_def->name.str, i, table_def->cset.str,
 
2810
                      cur_field->charset()->csname);
 
2811
        error= true;
 
2812
      }
 
2813
    }
 
2814
    else
 
2815
    {
 
2816
      errmsg_printf(ERRMSG_LVL_ERROR,
 
2817
                    _("Incorrect definition of table %s.%s: "
 
2818
                      "expected column '%s' at position %d to have type %s "
 
2819
                      " but the column is not found."),
 
2820
                    s->db.str, alias,
 
2821
                    table_def->name.str, i, table_def->type.str);
 
2822
      error= true;
 
2823
    }
 
2824
  }
 
2825
  return(error);
 
2826
}
 
2827
 
 
2828
 
 
2829
/*
 
2830
  Create Item_field for each column in the table.
 
2831
 
 
2832
  SYNPOSIS
 
2833
    Table::fill_item_list()
 
2834
      item_list          a pointer to an empty list used to store items
 
2835
 
 
2836
  DESCRIPTION
 
2837
    Create Item_field object for each column in the table and
 
2838
    initialize it with the corresponding Field. New items are
 
2839
    created in the current Session memory root.
 
2840
 
 
2841
  RETURN VALUE
 
2842
    0                    success
 
2843
    1                    out of memory
 
2844
*/
 
2845
 
 
2846
bool Table::fill_item_list(List<Item> *item_list) const
 
2847
{
 
2848
  /*
 
2849
    All Item_field's created using a direct pointer to a field
 
2850
    are fixed in Item_field constructor.
 
2851
  */
 
2852
  for (Field **ptr= field; *ptr; ptr++)
 
2853
  {
 
2854
    Item_field *item= new Item_field(*ptr);
 
2855
    if (!item || item_list->push_back(item))
 
2856
      return true;
 
2857
  }
 
2858
  return false;
 
2859
}
 
2860
 
 
2861
/*
 
2862
  Reset an existing list of Item_field items to point to the
 
2863
  Fields of this table.
 
2864
 
 
2865
  SYNPOSIS
 
2866
    Table::fill_item_list()
 
2867
      item_list          a non-empty list with Item_fields
 
2868
 
 
2869
  DESCRIPTION
 
2870
    This is a counterpart of fill_item_list used to redirect
 
2871
    Item_fields to the fields of a newly created table.
 
2872
    The caller must ensure that number of items in the item_list
 
2873
    is the same as the number of columns in the table.
 
2874
*/
 
2875
 
 
2876
void Table::reset_item_list(List<Item> *item_list) const
 
2877
{
 
2878
  List_iterator_fast<Item> it(*item_list);
 
2879
  for (Field **ptr= field; *ptr; ptr++)
 
2880
  {
 
2881
    Item_field *item_field= (Item_field*) it++;
 
2882
    assert(item_field != 0);
 
2883
    item_field->reset_field(*ptr);
 
2884
  }
 
2885
}
 
2886
 
 
2887
 
 
2888
/*
 
2889
  Find underlying base tables (TableList) which represent given
 
2890
  table_to_find (Table)
 
2891
 
 
2892
  SYNOPSIS
 
2893
    TableList::find_underlying_table()
 
2894
    table_to_find table to find
 
2895
 
 
2896
  RETURN
 
2897
    0  table is not found
 
2898
    found table reference
 
2899
*/
 
2900
 
 
2901
TableList *TableList::find_underlying_table(Table *table_to_find)
 
2902
{
 
2903
  /* is this real table and table which we are looking for? */
 
2904
  if (table == table_to_find && merge_underlying_list == 0)
 
2905
    return this;
 
2906
 
 
2907
  for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
 
2908
  {
 
2909
    TableList *result;
 
2910
    if ((result= tbl->find_underlying_table(table_to_find)))
 
2911
      return result;
 
2912
  }
 
2913
  return 0;
 
2914
}
 
2915
 
 
2916
/*
 
2917
  cleunup items belonged to view fields translation table
 
2918
 
 
2919
  SYNOPSIS
 
2920
    TableList::cleanup_items()
 
2921
*/
 
2922
 
 
2923
void TableList::cleanup_items()
 
2924
{
 
2925
}
 
2926
 
 
2927
 
 
2928
bool TableList::placeholder()
 
2929
{
 
2930
  return derived || schema_table || (create && !table->getDBStat()) || !table;
 
2931
}
 
2932
 
 
2933
 
 
2934
/*
 
2935
  Set insert_values buffer
 
2936
 
 
2937
  SYNOPSIS
 
2938
    set_insert_values()
 
2939
    mem_root   memory pool for allocating
 
2940
 
 
2941
  RETURN
 
2942
    false - OK
 
2943
    TRUE  - out of memory
 
2944
*/
 
2945
 
 
2946
bool TableList::set_insert_values(MEM_ROOT *mem_root)
 
2947
{
 
2948
  if (table)
 
2949
  {
 
2950
    if (!table->insert_values &&
 
2951
        !(table->insert_values= (unsigned char *)alloc_root(mem_root,
 
2952
                                                   table->s->rec_buff_length)))
 
2953
      return true;
 
2954
  }
 
2955
 
 
2956
  return false;
 
2957
}
 
2958
 
 
2959
 
 
2960
/*
 
2961
  Test if this is a leaf with respect to name resolution.
 
2962
 
 
2963
  SYNOPSIS
 
2964
    TableList::is_leaf_for_name_resolution()
 
2965
 
 
2966
  DESCRIPTION
 
2967
    A table reference is a leaf with respect to name resolution if
 
2968
    it is either a leaf node in a nested join tree (table, view,
 
2969
    schema table, subquery), or an inner node that represents a
 
2970
    NATURAL/USING join, or a nested join with materialized join
 
2971
    columns.
 
2972
 
 
2973
  RETURN
 
2974
    TRUE if a leaf, false otherwise.
 
2975
*/
 
2976
bool TableList::is_leaf_for_name_resolution()
 
2977
{
 
2978
  return (is_natural_join || is_join_columns_complete || !nested_join);
 
2979
}
 
2980
 
 
2981
 
 
2982
/*
 
2983
  Retrieve the first (left-most) leaf in a nested join tree with
 
2984
  respect to name resolution.
 
2985
 
 
2986
  SYNOPSIS
 
2987
    TableList::first_leaf_for_name_resolution()
 
2988
 
 
2989
  DESCRIPTION
 
2990
    Given that 'this' is a nested table reference, recursively walk
 
2991
    down the left-most children of 'this' until we reach a leaf
 
2992
    table reference with respect to name resolution.
 
2993
 
 
2994
  IMPLEMENTATION
 
2995
    The left-most child of a nested table reference is the last element
 
2996
    in the list of children because the children are inserted in
 
2997
    reverse order.
 
2998
 
 
2999
  RETURN
 
3000
    If 'this' is a nested table reference - the left-most child of
 
3001
      the tree rooted in 'this',
 
3002
    else return 'this'
 
3003
*/
 
3004
 
 
3005
TableList *TableList::first_leaf_for_name_resolution()
 
3006
{
 
3007
  TableList *cur_table_ref= NULL;
 
3008
  nested_join_st *cur_nested_join;
 
3009
 
 
3010
  if (is_leaf_for_name_resolution())
 
3011
    return this;
 
3012
  assert(nested_join);
 
3013
 
 
3014
  for (cur_nested_join= nested_join;
 
3015
       cur_nested_join;
 
3016
       cur_nested_join= cur_table_ref->nested_join)
 
3017
  {
 
3018
    List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
3019
    cur_table_ref= it++;
 
3020
    /*
 
3021
      If the current nested join is a RIGHT JOIN, the operands in
 
3022
      'join_list' are in reverse order, thus the first operand is
 
3023
      already at the front of the list. Otherwise the first operand
 
3024
      is in the end of the list of join operands.
 
3025
    */
 
3026
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
3027
    {
 
3028
      TableList *next;
 
3029
      while ((next= it++))
 
3030
        cur_table_ref= next;
 
3031
    }
 
3032
    if (cur_table_ref->is_leaf_for_name_resolution())
 
3033
      break;
 
3034
  }
 
3035
  return cur_table_ref;
 
3036
}
 
3037
 
 
3038
 
 
3039
/*
 
3040
  Retrieve the last (right-most) leaf in a nested join tree with
 
3041
  respect to name resolution.
 
3042
 
 
3043
  SYNOPSIS
 
3044
    TableList::last_leaf_for_name_resolution()
 
3045
 
 
3046
  DESCRIPTION
 
3047
    Given that 'this' is a nested table reference, recursively walk
 
3048
    down the right-most children of 'this' until we reach a leaf
 
3049
    table reference with respect to name resolution.
 
3050
 
 
3051
  IMPLEMENTATION
 
3052
    The right-most child of a nested table reference is the first
 
3053
    element in the list of children because the children are inserted
 
3054
    in reverse order.
 
3055
 
 
3056
  RETURN
 
3057
    - If 'this' is a nested table reference - the right-most child of
 
3058
      the tree rooted in 'this',
 
3059
    - else - 'this'
 
3060
*/
 
3061
 
 
3062
TableList *TableList::last_leaf_for_name_resolution()
 
3063
{
 
3064
  TableList *cur_table_ref= this;
 
3065
  nested_join_st *cur_nested_join;
 
3066
 
 
3067
  if (is_leaf_for_name_resolution())
 
3068
    return this;
 
3069
  assert(nested_join);
 
3070
 
 
3071
  for (cur_nested_join= nested_join;
 
3072
       cur_nested_join;
 
3073
       cur_nested_join= cur_table_ref->nested_join)
 
3074
  {
 
3075
    cur_table_ref= cur_nested_join->join_list.head();
 
3076
    /*
 
3077
      If the current nested is a RIGHT JOIN, the operands in
 
3078
      'join_list' are in reverse order, thus the last operand is in the
 
3079
      end of the list.
 
3080
    */
 
3081
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
3082
    {
 
3083
      List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
3084
      TableList *next;
 
3085
      cur_table_ref= it++;
 
3086
      while ((next= it++))
 
3087
        cur_table_ref= next;
 
3088
    }
 
3089
    if (cur_table_ref->is_leaf_for_name_resolution())
 
3090
      break;
 
3091
  }
 
3092
  return cur_table_ref;
 
3093
}
 
3094
 
 
3095
 
1992
3096
/*****************************************************************************
1993
3097
  Functions to handle column usage bitmaps (read_set, write_set etc...)
1994
3098
*****************************************************************************/
1998
3102
void Table::clear_column_bitmaps()
1999
3103
{
2000
3104
  /*
2001
 
    Reset column read/write usage. It's identical to:
2002
 
    bitmap_clear_all(&table->def_read_set);
2003
 
    bitmap_clear_all(&table->def_write_set);
 
3105
    Reset column read/write usage.
2004
3106
  */
2005
 
  def_read_set.clearAll();
2006
 
  def_write_set.clearAll();
 
3107
  def_read_set.reset();
 
3108
  def_write_set.reset(); /* TODO: is this needed here? */
2007
3109
  column_bitmaps_set(&def_read_set, &def_write_set);
2008
3110
}
2009
3111
 
2010
3112
 
2011
3113
/*
2012
 
  Tell Cursor we are going to call position() and rnd_pos() later.
 
3114
  Tell handler we are going to call position() and rnd_pos() later.
2013
3115
 
2014
3116
  NOTES:
2015
3117
  This is needed for handlers that uses the primary key to find the
2020
3122
void Table::prepare_for_position()
2021
3123
{
2022
3124
 
2023
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
 
3125
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
2024
3126
      s->primary_key < MAX_KEY)
2025
3127
  {
2026
 
    mark_columns_used_by_index_no_reset(s->primary_key);
 
3128
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3129
    /* signal change */
 
3130
    file->column_bitmaps_signal();
2027
3131
  }
2028
3132
  return;
2029
3133
}
2041
3145
 
2042
3146
void Table::mark_columns_used_by_index(uint32_t index)
2043
3147
{
2044
 
  MyBitmap *bitmap= &tmp_set;
 
3148
  bitset<MAX_FIELDS> *bitmap= &tmp_set;
2045
3149
 
2046
 
  (void) cursor->extra(HA_EXTRA_KEYREAD);
2047
 
  bitmap->clearAll();
 
3150
  (void) file->extra(HA_EXTRA_KEYREAD);
 
3151
  bitmap->reset();
2048
3152
  mark_columns_used_by_index_no_reset(index, bitmap);
2049
3153
  column_bitmaps_set(bitmap, bitmap);
2050
3154
  return;
2066
3170
{
2067
3171
 
2068
3172
  key_read= 0;
2069
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3173
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
2070
3174
  default_column_bitmaps();
 
3175
  file->column_bitmaps_signal();
2071
3176
  return;
2072
3177
}
2073
3178
 
2076
3181
  mark columns used by key, but don't reset other fields
2077
3182
*/
2078
3183
 
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
3184
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
2085
 
                                                MyBitmap *bitmap)
 
3185
                                                bitset<MAX_FIELDS> *bitmap)
2086
3186
{
2087
3187
  KEY_PART_INFO *key_part= key_info[index].key_part;
2088
3188
  KEY_PART_INFO *key_part_end= (key_part +
2089
3189
                                key_info[index].key_parts);
2090
3190
  for (;key_part != key_part_end; key_part++)
2091
 
    bitmap->setBit(key_part->fieldnr-1);
 
3191
  {
 
3192
    bitmap->set(key_part->fieldnr-1);
 
3193
    if (key_part->field->vcol_info &&
 
3194
        key_part->field->vcol_info->expr_item)
 
3195
      key_part->field->vcol_info->
 
3196
               expr_item->walk(&Item::register_field_in_bitmap,
 
3197
                               1, (unsigned char *) bitmap);
 
3198
  }
2092
3199
}
2093
3200
 
2094
3201
 
2107
3214
    We must set bit in read set as update_auto_increment() is using the
2108
3215
    store() to check overflow of auto_increment values
2109
3216
  */
2110
 
  setReadSet(found_next_number_field->field_index);
2111
 
  setWriteSet(found_next_number_field->field_index);
 
3217
  read_set->set(found_next_number_field->field_index);
 
3218
  write_set->set(found_next_number_field->field_index);
2112
3219
  if (s->next_number_keypart)
2113
 
    mark_columns_used_by_index_no_reset(s->next_number_index);
 
3220
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
 
3221
  file->column_bitmaps_signal();
2114
3222
}
2115
3223
 
2116
3224
 
2134
3242
 
2135
3243
void Table::mark_columns_needed_for_delete()
2136
3244
{
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))
 
3245
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2155
3246
  {
2156
3247
    Field **reg_field;
2157
3248
    for (reg_field= field ; *reg_field ; reg_field++)
2158
3249
    {
2159
3250
      if ((*reg_field)->flags & PART_KEY_FLAG)
2160
 
        setReadSet((*reg_field)->field_index);
 
3251
        read_set->set((*reg_field)->field_index);
 
3252
    }
 
3253
    file->column_bitmaps_signal();
 
3254
  }
 
3255
 
 
3256
  {
 
3257
    /*
 
3258
      If the handler has no cursor capabilites, or we have row-based
 
3259
      replication active for the current statement, we have to read
 
3260
      either the primary key, the hidden primary key or all columns to
 
3261
      be able to do an delete
 
3262
    */
 
3263
    if (s->primary_key == MAX_KEY)
 
3264
      file->use_hidden_primary_key();
 
3265
    else
 
3266
    {
 
3267
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3268
      file->column_bitmaps_signal();
2161
3269
    }
2162
3270
  }
2163
3271
}
2175
3283
    if neeed, either the primary key column or all columns to be read.
2176
3284
    (see mark_columns_needed_for_delete() for details)
2177
3285
 
2178
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
3286
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
2179
3287
    mark all USED key columns as 'to-be-read'. This allows the engine to
2180
3288
    loop over the given record to find all changed keys and doesn't have to
2181
3289
    retrieve the row again.
2183
3291
 
2184
3292
void Table::mark_columns_needed_for_update()
2185
3293
{
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))
 
3294
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2202
3295
  {
2203
3296
    /* Mark all used key columns for read */
2204
3297
    Field **reg_field;
2205
3298
    for (reg_field= field ; *reg_field ; reg_field++)
2206
3299
    {
2207
3300
      /* 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);
 
3301
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
 
3302
        read_set->set((*reg_field)->field_index);
2210
3303
    }
 
3304
    file->column_bitmaps_signal();
2211
3305
  }
2212
3306
 
 
3307
  {
 
3308
    /*
 
3309
      If the handler has no cursor capabilites, or we have row-based
 
3310
      logging active for the current statement, we have to read either
 
3311
      the primary key, the hidden primary key or all columns to be
 
3312
      able to do an update
 
3313
    */
 
3314
    if (s->primary_key == MAX_KEY)
 
3315
      file->use_hidden_primary_key();
 
3316
    else
 
3317
    {
 
3318
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3319
      file->column_bitmaps_signal();
 
3320
    }
 
3321
  }
 
3322
  /* Mark all virtual columns as writable */
 
3323
  mark_virtual_columns();
 
3324
  return;
2213
3325
}
2214
3326
 
2215
3327
 
2216
3328
/*
2217
 
  Mark columns the Cursor needs for doing an insert
 
3329
  Mark columns the handler needs for doing an insert
2218
3330
 
2219
3331
  For now, this is used to mark fields used by the trigger
2220
3332
  as changed.
2224
3336
{
2225
3337
  if (found_next_number_field)
2226
3338
    mark_auto_increment_column();
2227
 
}
2228
 
 
 
3339
  /* Mark all virtual columns as writable */
 
3340
  mark_virtual_columns();
 
3341
}
 
3342
 
 
3343
/*
 
3344
  @brief Update the write and read table bitmap to allow
 
3345
         using procedure save_in_field for all virtual columns
 
3346
         in the table.
 
3347
 
 
3348
  @return       void
 
3349
 
 
3350
  @detail
 
3351
    Each virtual field is set in the write column map.
 
3352
    All fields that the virtual columns are based on are set in the
 
3353
    read bitmap.
 
3354
*/
 
3355
 
 
3356
void Table::mark_virtual_columns(void)
 
3357
{
 
3358
  Field **vfield_ptr, *tmp_vfield;
 
3359
  bool bitmap_updated= false;
 
3360
 
 
3361
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
 
3362
  {
 
3363
    tmp_vfield= *vfield_ptr;
 
3364
    assert(tmp_vfield->vcol_info && tmp_vfield->vcol_info->expr_item);
 
3365
    tmp_vfield->vcol_info->expr_item->walk(&Item::register_field_in_read_map,
 
3366
                                           1, (unsigned char *) 0);
 
3367
    read_set->set(tmp_vfield->field_index);
 
3368
    write_set->set(tmp_vfield->field_index);
 
3369
    bitmap_updated= true;
 
3370
  }
 
3371
  if (bitmap_updated)
 
3372
    file->column_bitmaps_signal();
 
3373
}
 
3374
 
 
3375
 
 
3376
/*
 
3377
  Cleanup this table for re-execution.
 
3378
 
 
3379
  SYNOPSIS
 
3380
    TableList::reinit_before_use()
 
3381
*/
 
3382
 
 
3383
void TableList::reinit_before_use(Session *session)
 
3384
{
 
3385
  /*
 
3386
    Reset old pointers to TABLEs: they are not valid since the tables
 
3387
    were closed in the end of previous prepare or execute call.
 
3388
  */
 
3389
  table= 0;
 
3390
  /* Reset is_schema_table_processed value(needed for I_S tables */
 
3391
  schema_table_state= NOT_PROCESSED;
 
3392
 
 
3393
  TableList *embedded; /* The table at the current level of nesting. */
 
3394
  TableList *parent_embedding= this; /* The parent nested table reference. */
 
3395
  do
 
3396
  {
 
3397
    embedded= parent_embedding;
 
3398
    if (embedded->prep_on_expr)
 
3399
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
 
3400
    parent_embedding= embedded->embedding;
 
3401
  }
 
3402
  while (parent_embedding &&
 
3403
         parent_embedding->nested_join->join_list.head() == embedded);
 
3404
}
 
3405
 
 
3406
/*
 
3407
  Return subselect that contains the FROM list this table is taken from
 
3408
 
 
3409
  SYNOPSIS
 
3410
    TableList::containing_subselect()
 
3411
 
 
3412
  RETURN
 
3413
    Subselect item for the subquery that contains the FROM list
 
3414
    this table is taken from if there is any
 
3415
    0 - otherwise
 
3416
 
 
3417
*/
 
3418
 
 
3419
Item_subselect *TableList::containing_subselect()
 
3420
{
 
3421
  return (select_lex ? select_lex->master_unit()->item : 0);
 
3422
}
 
3423
 
 
3424
/*
 
3425
  Compiles the tagged hints list and fills up the bitmasks.
 
3426
 
 
3427
  SYNOPSIS
 
3428
    process_index_hints()
 
3429
      table         the Table to operate on.
 
3430
 
 
3431
  DESCRIPTION
 
3432
    The parser collects the index hints for each table in a "tagged list"
 
3433
    (TableList::index_hints). Using the information in this tagged list
 
3434
    this function sets the members Table::keys_in_use_for_query,
 
3435
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
 
3436
    Table::force_index and Table::covering_keys.
 
3437
 
 
3438
    Current implementation of the runtime does not allow mixing FORCE INDEX
 
3439
    and USE INDEX, so this is checked here. Then the FORCE INDEX list
 
3440
    (if non-empty) is appended to the USE INDEX list and a flag is set.
 
3441
 
 
3442
    Multiple hints of the same kind are processed so that each clause
 
3443
    is applied to what is computed in the previous clause.
 
3444
    For example:
 
3445
        USE INDEX (i1) USE INDEX (i2)
 
3446
    is equivalent to
 
3447
        USE INDEX (i1,i2)
 
3448
    and means "consider only i1 and i2".
 
3449
 
 
3450
    Similarly
 
3451
        USE INDEX () USE INDEX (i1)
 
3452
    is equivalent to
 
3453
        USE INDEX (i1)
 
3454
    and means "consider only the index i1"
 
3455
 
 
3456
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
 
3457
    not an error.
 
3458
 
 
3459
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
 
3460
    order:
 
3461
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
 
3462
      2. All IGNORE INDEX
 
3463
 
 
3464
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
 
3465
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
 
3466
 
 
3467
    As an optimization if there is a covering index, and we have
 
3468
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
 
3469
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
 
3470
 
 
3471
  RETURN VALUE
 
3472
    false                no errors found
 
3473
    TRUE                 found and reported an error.
 
3474
*/
 
3475
bool TableList::process_index_hints(Table *tbl)
 
3476
{
 
3477
  /* initialize the result variables */
 
3478
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
 
3479
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
 
3480
 
 
3481
  /* index hint list processing */
 
3482
  if (index_hints)
 
3483
  {
 
3484
    key_map index_join[INDEX_HINT_FORCE + 1];
 
3485
    key_map index_order[INDEX_HINT_FORCE + 1];
 
3486
    key_map index_group[INDEX_HINT_FORCE + 1];
 
3487
    Index_hint *hint;
 
3488
    int type;
 
3489
    bool have_empty_use_join= false, have_empty_use_order= false,
 
3490
         have_empty_use_group= false;
 
3491
    List_iterator <Index_hint> iter(*index_hints);
 
3492
 
 
3493
    /* initialize temporary variables used to collect hints of each kind */
 
3494
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
 
3495
    {
 
3496
      index_join[type].clear_all();
 
3497
      index_order[type].clear_all();
 
3498
      index_group[type].clear_all();
 
3499
    }
 
3500
 
 
3501
    /* iterate over the hints list */
 
3502
    while ((hint= iter++))
 
3503
    {
 
3504
      uint32_t pos;
 
3505
 
 
3506
      /* process empty USE INDEX () */
 
3507
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
 
3508
      {
 
3509
        if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3510
        {
 
3511
          index_join[hint->type].clear_all();
 
3512
          have_empty_use_join= true;
 
3513
        }
 
3514
        if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3515
        {
 
3516
          index_order[hint->type].clear_all();
 
3517
          have_empty_use_order= true;
 
3518
        }
 
3519
        if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3520
        {
 
3521
          index_group[hint->type].clear_all();
 
3522
          have_empty_use_group= true;
 
3523
        }
 
3524
        continue;
 
3525
      }
 
3526
 
 
3527
      /*
 
3528
        Check if an index with the given name exists and get his offset in
 
3529
        the keys bitmask for the table
 
3530
      */
 
3531
      if (tbl->s->keynames.type_names == 0 ||
 
3532
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
 
3533
                          hint->key_name.length, 1)) <= 0)
 
3534
      {
 
3535
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
 
3536
        return 1;
 
3537
      }
 
3538
 
 
3539
      pos--;
 
3540
 
 
3541
      /* add to the appropriate clause mask */
 
3542
      if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3543
        index_join[hint->type].set_bit (pos);
 
3544
      if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3545
        index_order[hint->type].set_bit (pos);
 
3546
      if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3547
        index_group[hint->type].set_bit (pos);
 
3548
    }
 
3549
 
 
3550
    /* cannot mix USE INDEX and FORCE INDEX */
 
3551
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3552
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3553
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
 
3554
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
 
3555
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
 
3556
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
 
3557
    {
 
3558
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
 
3559
               index_hint_type_name[INDEX_HINT_FORCE]);
 
3560
      return 1;
 
3561
    }
 
3562
 
 
3563
    /* process FORCE INDEX as USE INDEX with a flag */
 
3564
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3565
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3566
        !index_group[INDEX_HINT_FORCE].is_clear_all())
 
3567
    {
 
3568
      tbl->force_index= true;
 
3569
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
 
3570
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
 
3571
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
 
3572
    }
 
3573
 
 
3574
    /* apply USE INDEX */
 
3575
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
 
3576
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
 
3577
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
 
3578
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
 
3579
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
 
3580
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
 
3581
 
 
3582
    /* apply IGNORE INDEX */
 
3583
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
 
3584
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
 
3585
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
 
3586
  }
 
3587
 
 
3588
  /* make sure covering_keys don't include indexes disabled with a hint */
 
3589
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
 
3590
  return 0;
 
3591
}
2229
3592
 
2230
3593
 
2231
3594
size_t Table::max_row_length(const unsigned char *data)
2255
3618
/**
2256
3619
  Create field for temporary table from given field.
2257
3620
 
2258
 
  @param session               Thread Cursor
 
3621
  @param session               Thread handler
2259
3622
  @param org_field    field from which new field will be created
2260
3623
  @param name         New field name
2261
3624
  @param table         Temporary table
2314
3677
 
2315
3678
 
2316
3679
/**
 
3680
  Create field for information schema table.
 
3681
 
 
3682
  @param session                Thread handler
 
3683
  @param table          Temporary table
 
3684
  @param item           Item to create a field for
 
3685
 
 
3686
  @retval
 
3687
    0                   on error
 
3688
  @retval
 
3689
    new_created field
 
3690
*/
 
3691
 
 
3692
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
 
3693
{
 
3694
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
3695
  {
 
3696
    Field *field;
 
3697
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
3698
      field= new Field_blob(item->max_length, item->maybe_null,
 
3699
                            item->name, item->collation.collation);
 
3700
    else
 
3701
      field= new Field_varstring(item->max_length, item->maybe_null,
 
3702
                                 item->name,
 
3703
                                 table->s, item->collation.collation);
 
3704
    if (field)
 
3705
      field->init(table);
 
3706
    return field;
 
3707
  }
 
3708
  return item->tmp_table_field_from_field_type(table, 0);
 
3709
}
 
3710
 
 
3711
 
 
3712
/**
2317
3713
  Create a temp table according to a field list.
2318
3714
 
2319
3715
  Given field pointers are changed to point at tmp_table for
2343
3739
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
2344
3740
#define RATIO_TO_PACK_ROWS             2
2345
3741
 
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
3742
Table *
2355
3743
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
2356
3744
                 order_st *group, bool distinct, bool save_sum_fields,
2357
3745
                 uint64_t select_options, ha_rows rows_limit,
2358
 
                 const char *table_alias)
 
3746
                 char *table_alias)
2359
3747
{
2360
 
  memory::Root *mem_root_save, own_root;
 
3748
  MEM_ROOT *mem_root_save, own_root;
2361
3749
  Table *table;
2362
 
  TableShare *share;
 
3750
  TABLE_SHARE *share;
2363
3751
  uint  i,field_count,null_count,null_pack_length;
2364
3752
  uint32_t  copy_func_count= param->func_count;
2365
3753
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
2366
3754
  uint32_t  blob_count,group_null_items, string_count;
 
3755
  uint32_t  temp_pool_slot= MY_BIT_NONE;
2367
3756
  uint32_t fieldnr= 0;
2368
3757
  ulong reclength, string_total_length;
2369
 
  bool  using_unique_constraint= false;
2370
 
  bool  use_packed_rows= true;
 
3758
  bool  using_unique_constraint= 0;
 
3759
  bool  use_packed_rows= 0;
2371
3760
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
2372
 
  char  *tmpname;
2373
 
  char  path[FN_REFLEN];
 
3761
  char  *tmpname,path[FN_REFLEN];
2374
3762
  unsigned char *pos, *group_buff, *bitmaps;
2375
3763
  unsigned char *null_flags;
2376
3764
  Field **reg_field, **from_field, **default_field;
2377
3765
  uint32_t *blob_field;
2378
 
  CopyField *copy= 0;
 
3766
  Copy_field *copy=0;
2379
3767
  KEY *keyinfo;
2380
3768
  KEY_PART_INFO *key_part_info;
2381
3769
  Item **copy_func;
2382
3770
  MI_COLUMNDEF *recinfo;
2383
3771
  uint32_t total_uneven_bit_length= 0;
2384
3772
  bool force_copy_fields= param->force_copy_fields;
2385
 
  uint64_t max_rows= 0;
2386
3773
 
2387
3774
  status_var_increment(session->status_var.created_tmp_tables);
2388
3775
 
2389
 
  make_internal_temporary_table_path(session, path);
 
3776
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
 
3777
    setNextBit(temp_pool);
 
3778
 
 
3779
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
 
3780
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
 
3781
            (unsigned long)current_pid, temp_pool_slot);
 
3782
  else
 
3783
  {
 
3784
    /* if we run out of slots or we are not using tempool */
 
3785
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
3786
            session->thread_id, session->tmp_table++);
 
3787
  }
 
3788
 
 
3789
  /*
 
3790
    No need to change table name to lower case as we are only creating
 
3791
    MyISAM or HEAP tables here
 
3792
  */
 
3793
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3794
 
2390
3795
 
2391
3796
  if (group)
2392
3797
  {
2393
 
    if (! param->quick_group)
2394
 
      group= 0;                                 // Can't use group key
 
3798
    if (!param->quick_group)
 
3799
      group=0;                                  // Can't use group key
2395
3800
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
2396
3801
    {
2397
3802
      /*
2402
3807
      */
2403
3808
      (*tmp->item)->marker= 4;
2404
3809
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
2405
 
        using_unique_constraint= true;
 
3810
        using_unique_constraint=1;
2406
3811
    }
2407
3812
    if (param->group_length >= MAX_BLOB_WIDTH)
2408
 
      using_unique_constraint= true;
 
3813
      using_unique_constraint=1;
2409
3814
    if (group)
2410
 
      distinct= 0;                              // Can't use distinct
 
3815
      distinct=0;                               // Can't use distinct
2411
3816
  }
2412
3817
 
2413
3818
  field_count=param->field_count+param->func_count+param->sum_func_count;
2423
3828
  if (param->precomputed_group_by)
2424
3829
    copy_func_count+= param->sum_func_count;
2425
3830
 
2426
 
  memory::init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
3831
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
2427
3832
 
2428
3833
  if (!multi_alloc_root(&own_root,
2429
3834
                        &table, sizeof(*table),
2444
3849
                        &bitmaps, bitmap_buffer_size(field_count)*2,
2445
3850
                        NULL))
2446
3851
  {
2447
 
    return NULL;
 
3852
    if (temp_pool_slot != MY_BIT_NONE)
 
3853
      temp_pool.reset(temp_pool_slot);
 
3854
    return(NULL);                               /* purecov: inspected */
2448
3855
  }
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]))
 
3856
  /* Copy_field belongs to Tmp_Table_Param, allocate it in Session mem_root */
 
3857
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
2451
3858
  {
2452
 
    free_root(&own_root, MYF(0));
2453
 
    return NULL;
 
3859
    if (temp_pool_slot != MY_BIT_NONE)
 
3860
      temp_pool.reset(temp_pool_slot);
 
3861
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
3862
    return(NULL);                               /* purecov: inspected */
2454
3863
  }
2455
3864
  param->items_to_copy= copy_func;
2456
3865
  strcpy(tmpname,path);
2470
3879
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
2471
3880
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
2472
3881
  table->map=1;
 
3882
  table->temp_pool_slot= temp_pool_slot;
2473
3883
  table->copy_blobs= 1;
2474
3884
  table->in_use= session;
2475
 
  table->quick_keys.reset();
2476
 
  table->covering_keys.reset();
2477
 
  table->keys_in_use_for_query.reset();
 
3885
  table->quick_keys.init();
 
3886
  table->covering_keys.init();
 
3887
  table->keys_in_use_for_query.init();
2478
3888
 
2479
3889
  table->setShare(share);
2480
 
  share->init(tmpname, tmpname);
 
3890
  init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
2481
3891
  share->blob_field= blob_field;
2482
3892
  share->blob_ptr_size= portable_sizeof_char_ptr;
2483
3893
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
2484
3894
  share->table_charset= param->table_charset;
2485
3895
  share->primary_key= MAX_KEY;               // Indicate no primary key
2486
 
  share->keys_for_keyread.reset();
2487
 
  share->keys_in_use.reset();
 
3896
  share->keys_for_keyread.init();
 
3897
  share->keys_in_use.init();
2488
3898
 
2489
3899
  /* Calculate which type of fields we will store in the temporary table */
2490
3900
 
2491
3901
  reclength= string_total_length= 0;
2492
3902
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
2493
 
  param->using_indirect_summary_function= 0;
 
3903
  param->using_indirect_summary_function=0;
2494
3904
 
2495
3905
  List_iterator_fast<Item> li(fields);
2496
3906
  Item *item;
2521
3931
    }
2522
3932
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
2523
3933
    {                                           /* Can't calc group yet */
2524
 
      ((Item_sum*) item)->result_field= 0;
2525
 
      for (i= 0 ; i < ((Item_sum*) item)->arg_count ; i++)
 
3934
      ((Item_sum*) item)->result_field=0;
 
3935
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
2526
3936
      {
2527
3937
        Item **argp= ((Item_sum*) item)->args + i;
2528
3938
        Item *arg= *argp;
2532
3942
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
2533
3943
                             tmp_from_field, &default_field[fieldnr],
2534
3944
                             group != 0,not_all_columns,
2535
 
                             false,
 
3945
                             distinct, 0,
2536
3946
                             param->convert_blob_length);
2537
3947
          if (!new_field)
2538
3948
            goto err;                                   // Should be OOM
2577
3987
        We here distinguish between UNION and multi-table-updates by the fact
2578
3988
        that in the later case group is set to the row pointer.
2579
3989
      */
2580
 
      Field *new_field=
 
3990
      Field *new_field= (param->schema_table) ?
 
3991
        create_tmp_field_for_schema(session, item, table) :
2581
3992
        create_tmp_field(session, table, item, type, &copy_func,
2582
3993
                         tmp_from_field, &default_field[fieldnr],
2583
3994
                         group != 0,
2584
3995
                         !force_copy_fields &&
2585
 
                           (not_all_columns || group != 0),
 
3996
                           (not_all_columns || group !=0),
 
3997
                         /*
 
3998
                           If item->marker == 4 then we force create_tmp_field
 
3999
                           to create a 64-bit longs for BIT fields because HEAP
 
4000
                           tables can't index BIT fields directly. We do the same
 
4001
                           for distinct, as we want the distinct index to be
 
4002
                           usable in this case too.
 
4003
                         */
 
4004
                         item->marker == 4 || param->bit_fields_as_long,
2586
4005
                         force_copy_fields,
2587
4006
                         param->convert_blob_length);
2588
4007
 
2636
4055
  /* If result table is small; use a heap */
2637
4056
  /* future: storage engine selection can be made dynamic? */
2638
4057
  if (blob_count || using_unique_constraint ||
2639
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
 
4058
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
4059
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
2640
4060
  {
2641
4061
    share->storage_engine= myisam_engine;
2642
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
4062
    table->file= get_new_handler(share, &table->mem_root,
 
4063
                                 share->db_type());
2643
4064
    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;
 
4065
        (param->group_parts > table->file->max_key_parts() ||
 
4066
         param->group_length > table->file->max_key_length()))
 
4067
      using_unique_constraint=1;
2647
4068
  }
2648
4069
  else
2649
4070
  {
2650
4071
    share->storage_engine= heap_engine;
2651
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
4072
    table->file= get_new_handler(share, &table->mem_root,
 
4073
                                 share->db_type());
2652
4074
  }
2653
 
  if (! table->cursor)
 
4075
  if (!table->file)
2654
4076
    goto err;
2655
4077
 
2656
4078
 
2657
 
  if (! using_unique_constraint)
 
4079
  if (!using_unique_constraint)
2658
4080
    reclength+= group_null_items;       // null flag is stored separately
2659
4081
 
2660
4082
  share->blob_fields= blob_count;
2686
4108
    table->record[1]= table->record[0]+alloc_length;
2687
4109
    share->default_values= table->record[1]+alloc_length;
2688
4110
  }
2689
 
  copy_func[0]= 0;                              // End marker
 
4111
  copy_func[0]=0;                               // End marker
2690
4112
  param->func_count= copy_func - param->items_to_copy;
2691
4113
 
2692
 
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
4114
  table->setup_tmp_table_column_bitmaps();
2693
4115
 
2694
4116
  recinfo=param->start_recinfo;
2695
4117
  null_flags=(unsigned char*) table->record[0];
2708
4130
  }
2709
4131
  null_count= (blob_count == 0) ? 1 : 0;
2710
4132
  hidden_field_count=param->hidden_field_count;
2711
 
  for (i= 0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
 
4133
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
2712
4134
  {
2713
4135
    Field *field= *reg_field;
2714
4136
    uint32_t length;
2722
4144
          We have to reserve one byte here for NULL bits,
2723
4145
          as this is updated by 'end_update()'
2724
4146
        */
2725
 
        *pos++= '\0';                           // Null is stored here
2726
 
        recinfo->length= 1;
 
4147
        *pos++=0;                               // Null is stored here
 
4148
        recinfo->length=1;
2727
4149
        recinfo->type=FIELD_NORMAL;
2728
4150
        recinfo++;
2729
4151
        memset(recinfo, 0, sizeof(*recinfo));
2752
4174
         inherit the default value that is defined for the field referred
2753
4175
         by the Item_field object from which 'field' has been created.
2754
4176
      */
2755
 
      ptrdiff_t diff;
 
4177
      my_ptrdiff_t diff;
2756
4178
      Field *orig_field= default_field[i];
2757
4179
      /* Get the value from default_values */
2758
 
      diff= (ptrdiff_t) (orig_field->table->s->default_values-
 
4180
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
2759
4181
                            orig_field->table->record[0]);
2760
4182
      orig_field->move_field_offset(diff);      // Points now at default_values
2761
4183
      if (orig_field->is_real_null())
2791
4213
 
2792
4214
  param->copy_field_end=copy;
2793
4215
  param->recinfo=recinfo;
2794
 
  table->storeRecordAsDefault();        // Make empty default record
 
4216
  store_record(table,s->default_values);        // Make empty default record
2795
4217
 
2796
4218
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
2797
 
    max_rows= ~(uint64_t) 0;
 
4219
    share->max_rows= ~(ha_rows) 0;
2798
4220
  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
 
4221
    share->max_rows= (ha_rows) (((share->db_type() == heap_engine) ?
 
4222
                                 cmin(session->variables.tmp_table_size,
 
4223
                                     session->variables.max_heap_table_size) :
 
4224
                                 session->variables.tmp_table_size) /
 
4225
                                 share->reclength);
 
4226
  set_if_bigger(share->max_rows,(ha_rows)1);    // For dummy start options
2806
4227
  /*
2807
4228
    Push the LIMIT clause to the temporary table creation, so that we
2808
4229
    materialize only up to 'rows_limit' records instead of all result records.
2809
4230
  */
2810
 
  set_if_smaller(max_rows, rows_limit);
2811
 
 
2812
 
  share->setMaxRows(max_rows);
2813
 
 
 
4231
  set_if_smaller(share->max_rows, rows_limit);
2814
4232
  param->end_write_records= rows_limit;
2815
4233
 
2816
4234
  keyinfo= param->keyinfo;
2825
4243
    keyinfo->key_part=key_part_info;
2826
4244
    keyinfo->flags=HA_NOSAME;
2827
4245
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
2828
 
    keyinfo->key_length= 0;
2829
 
    keyinfo->rec_per_key= 0;
 
4246
    keyinfo->key_length=0;
 
4247
    keyinfo->rec_per_key=0;
2830
4248
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
2831
4249
    keyinfo->name= (char*) "group_key";
2832
4250
    order_st *cur_group= group;
2834
4252
    {
2835
4253
      Field *field=(*cur_group->item)->get_tmp_table_field();
2836
4254
      bool maybe_null=(*cur_group->item)->maybe_null;
2837
 
      key_part_info->null_bit= 0;
 
4255
      key_part_info->null_bit=0;
2838
4256
      key_part_info->field=  field;
2839
4257
      key_part_info->offset= field->offset(table->record[0]);
2840
4258
      key_part_info->length= (uint16_t) field->key_length();
2841
4259
      key_part_info->type=   (uint8_t) field->key_type();
2842
 
      key_part_info->key_type= 
 
4260
      key_part_info->key_type =
2843
4261
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2844
4262
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2845
4263
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2846
 
        0 : 1;
 
4264
        0 : FIELDFLAG_BINARY;
2847
4265
      if (!using_unique_constraint)
2848
4266
      {
2849
4267
        cur_group->buff=(char*) group_buff;
2852
4270
                                                     test(maybe_null),
2853
4271
                                                     field->null_ptr,
2854
4272
                                                     field->null_bit)))
2855
 
          goto err;
 
4273
          goto err; /* purecov: inspected */
2856
4274
        if (maybe_null)
2857
4275
        {
2858
4276
          /*
2909
4327
    keyinfo->key_length=(uint16_t) reclength;
2910
4328
    keyinfo->name= (char*) "distinct_key";
2911
4329
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
2912
 
    keyinfo->rec_per_key= 0;
 
4330
    keyinfo->rec_per_key=0;
2913
4331
 
2914
4332
    /*
2915
4333
      Create an extra field to hold NULL bits so that unique indexes on
2918
4336
    */
2919
4337
    if (null_pack_length && share->uniques)
2920
4338
    {
2921
 
      key_part_info->null_bit= 0;
 
4339
      key_part_info->null_bit=0;
2922
4340
      key_part_info->offset=hidden_null_pack_length;
2923
4341
      key_part_info->length=null_pack_length;
2924
4342
      key_part_info->field= new Field_varstring(table->record[0],
2926
4344
                                                0,
2927
4345
                                                (unsigned char*) 0,
2928
4346
                                                (uint32_t) 0,
 
4347
                                                Field::NONE,
2929
4348
                                                NULL,
2930
4349
                                                table->s,
2931
4350
                                                &my_charset_bin);
2932
4351
      if (!key_part_info->field)
2933
4352
        goto err;
2934
4353
      key_part_info->field->init(table);
2935
 
      key_part_info->key_type= 1; /* binary comparison */
 
4354
      key_part_info->key_type=FIELDFLAG_BINARY;
2936
4355
      key_part_info->type=    HA_KEYTYPE_BINARY;
2937
4356
      key_part_info++;
2938
4357
    }
2941
4360
         i < field_count;
2942
4361
         i++, reg_field++, key_part_info++)
2943
4362
    {
2944
 
      key_part_info->null_bit= 0;
 
4363
      key_part_info->null_bit=0;
2945
4364
      key_part_info->field=    *reg_field;
2946
4365
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
2947
4366
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
2948
4367
      /* TODO:
2949
4368
        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.
 
4369
        key part is a copy/paste from opt_range.cc, and table.cc.
2951
4370
        This should be factored out, e.g. as a method of Field.
2952
4371
        In addition it is not clear if any of the Field::*_length
2953
4372
        methods is supposed to compute the same length. If so, it
2966
4385
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2967
4386
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2968
4387
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2969
 
        0 : 1;
 
4388
        0 : FIELDFLAG_BINARY;
2970
4389
    }
2971
4390
  }
2972
4391
 
2973
4392
  if (session->is_fatal_error)                          // If end of memory
2974
 
    goto err;
 
4393
    goto err;                                    /* purecov: inspected */
2975
4394
  share->db_record_offset= 1;
2976
4395
  if (share->db_type() == myisam_engine)
2977
4396
  {
2988
4407
 
2989
4408
err:
2990
4409
  session->mem_root= mem_root_save;
2991
 
  table->free_tmp_table(session);
2992
 
  return NULL;
 
4410
  table->free_tmp_table(session);                    /* purecov: inspected */
 
4411
  if (temp_pool_slot != MY_BIT_NONE)
 
4412
    temp_pool.reset(temp_pool_slot);
 
4413
  return(NULL);                         /* purecov: inspected */
2993
4414
}
2994
4415
 
2995
4416
/****************************************************************************/
2998
4419
  Create a reduced Table object with properly set up Field list from a
2999
4420
  list of field definitions.
3000
4421
 
3001
 
    The created table doesn't have a table Cursor associated with
 
4422
    The created table doesn't have a table handler associated with
3002
4423
    it, has no keys, no group/distinct, no copy_funcs array.
3003
4424
    The sole purpose of this Table object is to use the power of Field
3004
4425
    class to read/write data to/from table->record[0]. Then one can store
3013
4434
    0 if out of memory, Table object in case of success
3014
4435
*/
3015
4436
 
3016
 
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
 
4437
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
3017
4438
{
3018
4439
  uint32_t field_count= field_list.elements;
3019
4440
  uint32_t blob_count= 0;
3020
4441
  Field **field;
3021
 
  CreateField *cdef;                           /* column definition */
 
4442
  Create_field *cdef;                           /* column definition */
3022
4443
  uint32_t record_length= 0;
3023
4444
  uint32_t null_count= 0;                 /* number of columns which may be null */
3024
4445
  uint32_t null_pack_length;              /* NULL representation array length */
3025
4446
  uint32_t *blob_field;
3026
4447
  unsigned char *bitmaps;
3027
4448
  Table *table;
3028
 
  TableShare *share;
 
4449
  TABLE_SHARE *share;
3029
4450
 
3030
4451
  if (!multi_alloc_root(session->mem_root,
3031
4452
                        &table, sizeof(*table),
3034
4455
                        &blob_field, (field_count+1) *sizeof(uint32_t),
3035
4456
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3036
4457
                        NULL))
3037
 
    return NULL;
 
4458
    return 0;
3038
4459
 
3039
4460
  memset(table, 0, sizeof(*table));
3040
4461
  memset(share, 0, sizeof(*share));
3043
4464
  share->blob_field= blob_field;
3044
4465
  share->fields= field_count;
3045
4466
  share->blob_ptr_size= portable_sizeof_char_ptr;
3046
 
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
4467
  table->setup_tmp_table_column_bitmaps();
3047
4468
 
3048
4469
  /* Create all fields and calculate the total length of record */
3049
 
  List_iterator_fast<CreateField> it(field_list);
 
4470
  List_iterator_fast<Create_field> it(field_list);
3050
4471
  while ((cdef= it++))
3051
4472
  {
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,
 
4473
    *field= make_field(share, NULL, 0, cdef->length,
 
4474
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
4475
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
4476
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
3062
4477
                       cdef->unireg_check,
3063
 
                       cdef->interval,
3064
 
                       cdef->field_name);
 
4478
                       cdef->interval, cdef->field_name);
3065
4479
    if (!*field)
3066
4480
      goto error;
3067
4481
    (*field)->init(table);
3126
4540
  return 0;
3127
4541
}
3128
4542
 
 
4543
 
3129
4544
bool Table::open_tmp_table()
3130
4545
{
3131
4546
  int error;
3132
 
  if ((error=cursor->ha_open(this, s->table_name.str,O_RDWR,
 
4547
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
3133
4548
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3134
4549
  {
3135
 
    print_error(error, MYF(0));
3136
 
    db_stat= 0;
3137
 
    return true;
 
4550
    file->print_error(error,MYF(0)); /* purecov: inspected */
 
4551
    db_stat=0;
 
4552
    return(1);
3138
4553
  }
3139
 
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
3140
 
  return false;
 
4554
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
4555
  return(0);
3141
4556
}
3142
4557
 
3143
4558
 
3178
4593
  int error;
3179
4594
  MI_KEYDEF keydef;
3180
4595
  MI_UNIQUEDEF uniquedef;
3181
 
  TableShare *share= s;
 
4596
  TABLE_SHARE *share= s;
3182
4597
 
3183
4598
  if (share->keys)
3184
4599
  {                                             // Get keys for ni_create
3185
 
    bool using_unique_constraint= false;
 
4600
    bool using_unique_constraint=0;
3186
4601
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3187
4602
                                            sizeof(*seg) * keyinfo->key_parts);
3188
4603
    if (!seg)
3189
4604
      goto err;
3190
4605
 
3191
4606
    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() ||
 
4607
    if (keyinfo->key_length >= file->max_key_length() ||
 
4608
        keyinfo->key_parts > file->max_key_parts() ||
3194
4609
        share->uniques)
3195
4610
    {
3196
4611
      /* Can't create a key; Make a unique constraint instead of a key */
3197
4612
      share->keys=    0;
3198
4613
      share->uniques= 1;
3199
 
      using_unique_constraint= true;
 
4614
      using_unique_constraint=1;
3200
4615
      memset(&uniquedef, 0, sizeof(uniquedef));
3201
4616
      uniquedef.keysegs=keyinfo->key_parts;
3202
4617
      uniquedef.seg=seg;
3217
4632
      keydef.keysegs=  keyinfo->key_parts;
3218
4633
      keydef.seg= seg;
3219
4634
    }
3220
 
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
4635
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
3221
4636
    {
3222
4637
      Field *key_field=keyinfo->key_part[i].field;
3223
4638
      seg->flag=     0;
3226
4641
      seg->start=    keyinfo->key_part[i].offset;
3227
4642
      if (key_field->flags & BLOB_FLAG)
3228
4643
      {
3229
 
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
4644
        seg->type=
 
4645
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
3230
4646
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3231
4647
        seg->bit_start= (uint8_t)(key_field->pack_length()
3232
4648
                                  - share->blob_ptr_size);
3233
4649
        seg->flag= HA_BLOB_PART;
3234
 
        seg->length= 0;                 // Whole blob in unique constraint
 
4650
        seg->length=0;                  // Whole blob in unique constraint
3235
4651
      }
3236
4652
      else
3237
4653
      {
3246
4662
          In this case we have to tell MyISAM that two NULL should
3247
4663
          on INSERT be regarded at the same value
3248
4664
        */
3249
 
        if (! using_unique_constraint)
 
4665
        if (!using_unique_constraint)
3250
4666
          keydef.flag|= HA_NULL_ARE_EQUAL;
3251
4667
      }
3252
4668
    }
3265
4681
                       &create_info,
3266
4682
                       HA_CREATE_TMP_TABLE)))
3267
4683
  {
3268
 
    print_error(error, MYF(0));
3269
 
    db_stat= 0;
 
4684
    file->print_error(error,MYF(0));    /* purecov: inspected */
 
4685
    db_stat=0;
3270
4686
    goto err;
3271
4687
  }
3272
4688
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
3279
4695
 
3280
4696
void Table::free_tmp_table(Session *session)
3281
4697
{
3282
 
  memory::Root own_root= mem_root;
 
4698
  MEM_ROOT own_root= mem_root;
3283
4699
  const char *save_proc_info;
3284
4700
 
3285
4701
  save_proc_info=session->get_proc_info();
3286
4702
  session->set_proc_info("removing tmp table");
3287
4703
 
3288
4704
  // Release latches since this can take a long time
3289
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
4705
  ha_release_temporary_latches(session);
3290
4706
 
3291
 
  if (cursor)
 
4707
  if (file)
3292
4708
  {
3293
4709
    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;
 
4710
      file->ha_drop_table(s->table_name.str);
 
4711
    else
 
4712
      file->ha_delete_table(s->table_name.str);
 
4713
    delete file;
3300
4714
  }
3301
4715
 
3302
4716
  /* free blobs */
3303
4717
  for (Field **ptr= field ; *ptr ; ptr++)
3304
4718
    (*ptr)->free();
3305
 
  free_io_cache();
 
4719
  free_io_cache(this);
 
4720
 
 
4721
  if (temp_pool_slot != MY_BIT_NONE)
 
4722
    temp_pool.reset(temp_pool_slot);
3306
4723
 
3307
4724
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
3308
4725
  session->set_proc_info(save_proc_info);
 
4726
 
 
4727
  return;
3309
4728
}
3310
4729
 
3311
4730
/**
3319
4738
                             int error, bool ignore_last_dupp_key_error)
3320
4739
{
3321
4740
  Table new_table;
3322
 
  TableShare share;
 
4741
  TABLE_SHARE share;
3323
4742
  const char *save_proc_info;
3324
4743
  int write_err;
3325
4744
 
3326
4745
  if (table->s->db_type() != heap_engine ||
3327
4746
      error != HA_ERR_RECORD_FILE_FULL)
3328
4747
  {
3329
 
    table->print_error(error, MYF(0));
3330
 
    return true;
 
4748
    table->file->print_error(error,MYF(0));
 
4749
    return(1);
3331
4750
  }
3332
4751
 
3333
4752
  // Release latches since this can take a long time
3334
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
 
4753
  ha_release_temporary_latches(session);
3335
4754
 
3336
4755
  new_table= *table;
3337
4756
  share= *table->s;
3338
4757
  new_table.s= &share;
3339
4758
  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
 
4759
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
4760
                                        new_table.s->db_type())))
 
4761
    return(1);                          // End of memory
3342
4762
 
3343
4763
  save_proc_info=session->get_proc_info();
3344
4764
  session->set_proc_info("converting HEAP to MyISAM");
3349
4769
    goto err2;
3350
4770
  if (new_table.open_tmp_table())
3351
4771
    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);
 
4772
  if (table->file->indexes_are_disabled())
 
4773
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
4774
  table->file->ha_index_or_rnd_end();
 
4775
  table->file->ha_rnd_init(1);
3356
4776
  if (table->no_rows)
3357
4777
  {
3358
 
    new_table.cursor->extra(HA_EXTRA_NO_ROWS);
 
4778
    new_table.file->extra(HA_EXTRA_NO_ROWS);
3359
4779
    new_table.no_rows=1;
3360
4780
  }
3361
4781
 
3362
4782
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3363
 
  new_table.cursor->extra(HA_EXTRA_WRITE_CACHE);
 
4783
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
3364
4784
 
3365
4785
  /*
3366
4786
    copy all old rows from heap table to MyISAM table
3367
4787
    This is the only code that uses record[1] to read/write but this
3368
4788
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3369
4789
  */
3370
 
  while (!table->cursor->rnd_next(new_table.record[1]))
 
4790
  while (!table->file->rnd_next(new_table.record[1]))
3371
4791
  {
3372
 
    write_err= new_table.cursor->ha_write_row(new_table.record[1]);
 
4792
    write_err= new_table.file->ha_write_row(new_table.record[1]);
3373
4793
    if (write_err)
3374
4794
      goto err;
3375
4795
  }
3376
4796
  /* copy row that filled HEAP table */
3377
 
  if ((write_err=new_table.cursor->ha_write_row(table->record[0])))
 
4797
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
3378
4798
  {
3379
 
    if (new_table.cursor->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
4799
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
3380
4800
        !ignore_last_dupp_key_error)
3381
4801
      goto err;
3382
4802
  }
3383
4803
 
3384
4804
  /* 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;
 
4805
  (void) table->file->ha_rnd_end();
 
4806
  (void) table->file->close();                  // This deletes the table !
 
4807
  delete table->file;
 
4808
  table->file=0;
3389
4809
  new_table.s= table->s;                       // Keep old share
3390
4810
  *table= new_table;
3391
4811
  *table->s= share;
3392
4812
 
3393
 
  table->cursor->change_table_ptr(table, table->s);
 
4813
  table->file->change_table_ptr(table, table->s);
3394
4814
  table->use_all_columns();
3395
4815
  if (save_proc_info)
3396
4816
  {
3399
4819
      "Copying to tmp table on disk" : save_proc_info);
3400
4820
    session->set_proc_info(new_proc_info);
3401
4821
  }
3402
 
  return false;
 
4822
  return(0);
3403
4823
 
3404
4824
 err:
3405
 
  table->print_error(write_err, MYF(0));
3406
 
  (void) table->cursor->ha_rnd_end();
3407
 
  (void) new_table.cursor->close();
3408
 
 
 
4825
  table->file->print_error(write_err, MYF(0));
 
4826
  (void) table->file->ha_rnd_end();
 
4827
  (void) new_table.file->close();
3409
4828
 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
 
 
 
4829
  new_table.file->ha_delete_table(new_table.s->table_name.str);
3415
4830
 err2:
3416
 
  delete new_table.cursor;
 
4831
  delete new_table.file;
3417
4832
  session->set_proc_info(save_proc_info);
3418
4833
  table->mem_root= new_table.mem_root;
3419
 
  return true;
 
4834
  return(1);
3420
4835
}
3421
4836
 
3422
 
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
4837
bitset<MAX_FIELDS> *Table::use_all_columns(bitset<MAX_FIELDS> *bitmap)
3423
4838
{
3424
 
  my_bitmap_map *old= bitmap->getBitmap();
3425
 
  bitmap->setBitmap(s->all_set.getBitmap());
 
4839
  bitset<MAX_FIELDS> *old= bitmap;
 
4840
  bitmap= &s->all_set;
3426
4841
  return old;
3427
4842
}
3428
4843
 
3429
 
void Table::restore_column_map(my_bitmap_map *old)
 
4844
void Table::restore_column_map(bitset<MAX_FIELDS> *old)
3430
4845
{
3431
 
  read_set->setBitmap(old);
 
4846
  read_set= old;
3432
4847
}
3433
4848
 
3434
4849
uint32_t Table::find_shortest_key(const key_map *usable_keys)
3435
4850
{
3436
4851
  uint32_t min_length= UINT32_MAX;
3437
4852
  uint32_t best= MAX_KEY;
3438
 
  if (usable_keys->any())
 
4853
  if (!usable_keys->is_clear_all())
3439
4854
  {
3440
 
    for (uint32_t nr= 0; nr < s->keys ; nr++)
 
4855
    for (uint32_t nr=0; nr < s->keys ; nr++)
3441
4856
    {
3442
 
      if (usable_keys->test(nr))
 
4857
      if (usable_keys->is_set(nr))
3443
4858
      {
3444
4859
        if (key_info[nr].key_length < min_length)
3445
4860
        {
3475
4890
bool Table::compare_record()
3476
4891
{
3477
4892
  if (s->blob_fields + s->varchar_fields == 0)
3478
 
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
3479
 
  
 
4893
    return cmp_record(this, record[1]);
3480
4894
  /* 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
 
 
 
4895
  if (memcmp(null_flags,
 
4896
             null_flags + s->rec_buff_length,
 
4897
             s->null_bytes))
 
4898
    return true;                                // Diff in NULL value
3484
4899
  /* Compare updated fields */
3485
4900
  for (Field **ptr= field ; *ptr ; ptr++)
3486
4901
  {
3487
 
    if (isWriteSet((*ptr)->field_index) &&
 
4902
    if (write_set->test((*ptr)->field_index) &&
3488
4903
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
3489
4904
      return true;
3490
4905
  }
3491
4906
  return false;
3492
4907
}
3493
4908
 
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
 
}
 
4909
 
 
4910
 
 
4911
 
3616
4912
 
3617
4913
/*****************************************************************************
3618
4914
  The different ways to read a record
3619
4915
  Returns -1 if row was not found, 0 if row was found and 1 on errors
3620
4916
*****************************************************************************/
3621
4917
 
3622
 
/** Help function when we get some an error from the table Cursor. */
 
4918
/** Help function when we get some an error from the table handler. */
3623
4919
 
3624
4920
int Table::report_error(int error)
3625
4921
{
3635
4931
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
3636
4932
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
3637
4933
                    error, s->path.str);
3638
 
  print_error(error, MYF(0));
 
4934
  file->print_error(error,MYF(0));
3639
4935
 
3640
4936
  return 1;
3641
4937
}
3642
4938
 
3643
4939
 
 
4940
/*
 
4941
  Calculate data for each virtual field marked for write in the
 
4942
  corresponding column map.
 
4943
 
 
4944
  SYNOPSIS
 
4945
    update_virtual_fields_marked_for_write()
 
4946
    table                  The Table object
 
4947
    ignore_stored          Indication whether physically stored virtual
 
4948
                           fields do not need updating.
 
4949
                           This value is false when during INSERT and UPDATE
 
4950
                           and true in all other cases.
 
4951
 
 
4952
  RETURN
 
4953
    0  - Success
 
4954
    >0 - Error occurred during the generation/calculation of a virtual field value
 
4955
 
 
4956
*/
 
4957
 
 
4958
int update_virtual_fields_marked_for_write(Table *table,
 
4959
                                           bool ignore_stored)
 
4960
{
 
4961
  Field **vfield_ptr, *vfield;
 
4962
  int error= 0;
 
4963
  if ((not table) or (not table->vfield))
 
4964
    return(0);
 
4965
 
 
4966
  /* Iterate over virtual fields in the table */
 
4967
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
 
4968
  {
 
4969
    vfield= (*vfield_ptr);
 
4970
    assert(vfield->vcol_info && vfield->vcol_info->expr_item);
 
4971
    /*
 
4972
      Only update those fields that are marked in the write_set bitmap
 
4973
      and not _already_ physically stored in the database.
 
4974
    */
 
4975
    if (table->write_set->test(vfield->field_index) &&
 
4976
        (not (ignore_stored && vfield->is_stored))
 
4977
       )
 
4978
    {
 
4979
      /* Generate the actual value of the virtual fields */
 
4980
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
 
4981
    }
 
4982
  }
 
4983
  return(0);
 
4984
}
 
4985
 
 
4986
 
3644
4987
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
3645
4988
{
3646
4989
  used_fields= 0;
3658
5001
  map= (table_map) 1 << table_number;
3659
5002
  force_index= table_list->force_index;
3660
5003
  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 */
 
5004
  merge_keys.clear_all();
 
5005
}
 
5006
 
 
5007
 
 
5008
/*****************************************************************************
 
5009
** Instansiate templates
 
5010
*****************************************************************************/
 
5011
 
 
5012
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
5013
template class List<String>;
 
5014
template class List_iterator<String>;
 
5015
#endif