~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Monty Taylor
  • Date: 2009-03-04 02:48:12 UTC
  • mto: (917.1.2 mordred)
  • mto: This revision was merged to the branch mainline in revision 918.
  • Revision ID: mordred@inaugust.com-20090304024812-5wb6wpye5c1iitbq
Applied atomic patch to current tree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/* Some general useful functions */
18
18
 
19
 
#include "config.h"
20
 
 
21
 
#include <float.h>
22
 
#include <fcntl.h>
23
 
 
24
 
#include <string>
25
 
#include <vector>
26
 
#include <algorithm>
27
 
 
 
19
#include <drizzled/server_includes.h>
28
20
#include <drizzled/error.h>
29
21
#include <drizzled/gettext.h>
30
22
 
31
 
#include "drizzled/plugin/transactional_storage_engine.h"
32
 
#include "drizzled/plugin/authorization.h"
 
23
#include <drizzled/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
 
43
37
#include <drizzled/unireg.h>
44
 
#include <drizzled/message/table.pb.h>
45
 
#include "drizzled/sql_table.h"
46
 
#include "drizzled/charset.h"
47
 
#include "drizzled/internal/m_string.h"
48
 
#include "plugin/myisam/myisam.h"
 
38
#include <drizzled/serialize/table.pb.h>
49
39
 
50
40
#include <drizzled/item/string.h>
51
41
#include <drizzled/item/int.h>
52
42
#include <drizzled/item/decimal.h>
53
43
#include <drizzled/item/float.h>
54
44
#include <drizzled/item/null.h>
55
 
#include <drizzled/temporal.h>
56
 
 
57
 
#include "drizzled/table/instance.h"
58
 
 
59
 
#include "drizzled/table_proto.h"
 
45
 
60
46
 
61
47
using namespace std;
62
48
 
63
 
namespace drizzled
64
 
{
65
 
 
66
 
extern pid_t current_pid;
67
 
extern plugin::StorageEngine *heap_engine;
68
 
extern plugin::StorageEngine *myisam_engine;
69
 
 
70
 
/* Functions defined in this cursor */
71
 
 
72
 
void open_table_error(TableShare *share, int error, int db_errno,
 
49
/* Keyword for parsing virtual column functions */
 
50
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
 
51
 
 
52
/* Functions defined in this file */
 
53
 
 
54
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
73
55
                      myf errortype, int errarg);
 
56
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
 
57
                              uint32_t types, char **names);
74
58
 
75
59
/*************************************************************************/
76
60
 
77
 
// @note this should all be the destructor
78
 
int Table::delete_table(bool free_share)
79
 
{
80
 
  int error= 0;
 
61
/* Get column name from column hash */
 
62
 
 
63
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
 
64
{
 
65
  *length= (uint32_t) strlen((*buff)->field_name);
 
66
  return (unsigned char*) (*buff)->field_name;
 
67
}
 
68
 
 
69
 
 
70
/*
 
71
  Returns pointer to '.frm' extension of the file name.
 
72
 
 
73
  SYNOPSIS
 
74
    fn_rext()
 
75
    name       file name
 
76
 
 
77
  DESCRIPTION
 
78
    Checks file name part starting with the rightmost '.' character,
 
79
    and returns it if it is equal to '.frm'.
 
80
 
 
81
  TODO
 
82
    It is a good idea to get rid of this function modifying the code
 
83
    to garantee that the functions presently calling fn_rext() always
 
84
    get arguments in the same format: either with '.frm' or without '.frm'.
 
85
 
 
86
  RETURN VALUES
 
87
    Pointer to the '.frm' extension. If there is no extension,
 
88
    or extension is not '.frm', pointer at the end of file name.
 
89
*/
 
90
 
 
91
char *fn_rext(char *name)
 
92
{
 
93
  char *res= strrchr(name, '.');
 
94
  if (res && !strcmp(res, reg_ext))
 
95
    return res;
 
96
  return name + strlen(name);
 
97
}
 
98
 
 
99
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
 
100
{
 
101
  assert(db != NULL);
 
102
  assert(name != NULL);
 
103
 
 
104
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
 
105
      (my_strcasecmp(system_charset_info,
 
106
                    INFORMATION_SCHEMA_NAME.c_str(),
 
107
                    db->str) == 0))
 
108
  {
 
109
    return TABLE_CATEGORY_INFORMATION;
 
110
  }
 
111
 
 
112
  return TABLE_CATEGORY_USER;
 
113
}
 
114
 
 
115
 
 
116
/*
 
117
  Allocate a setup TABLE_SHARE structure
 
118
 
 
119
  SYNOPSIS
 
120
    alloc_table_share()
 
121
    TableList           Take database and table name from there
 
122
    key                 Table cache key (db \0 table_name \0...)
 
123
    key_length          Length of key
 
124
 
 
125
  RETURN
 
126
    0  Error (out of memory)
 
127
    #  Share
 
128
*/
 
129
 
 
130
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
 
131
                               uint32_t key_length)
 
132
{
 
133
  MEM_ROOT mem_root;
 
134
  TABLE_SHARE *share;
 
135
  char *key_buff, *path_buff;
 
136
  char path[FN_REFLEN];
 
137
  uint32_t path_length;
 
138
 
 
139
  path_length= build_table_filename(path, sizeof(path) - 1,
 
140
                                    table_list->db,
 
141
                                    table_list->table_name, "", 0);
 
142
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
143
  if (multi_alloc_root(&mem_root,
 
144
                       &share, sizeof(*share),
 
145
                       &key_buff, key_length,
 
146
                       &path_buff, path_length + 1,
 
147
                       NULL))
 
148
  {
 
149
    memset(share, 0, sizeof(*share));
 
150
 
 
151
    share->set_table_cache_key(key_buff, key, key_length);
 
152
 
 
153
    share->path.str= path_buff;
 
154
    share->path.length= path_length;
 
155
    strcpy(share->path.str, path);
 
156
    share->normalized_path.str=    share->path.str;
 
157
    share->normalized_path.length= path_length;
 
158
 
 
159
    share->version=       refresh_version;
 
160
 
 
161
    /*
 
162
      This constant is used to mark that no table map version has been
 
163
      assigned.  No arithmetic is done on the value: it will be
 
164
      overwritten with a value taken from DRIZZLE_BIN_LOG.
 
165
    */
 
166
    share->table_map_version= UINT64_MAX;
 
167
 
 
168
    /*
 
169
      Since alloc_table_share() can be called without any locking (for
 
170
      example, ha_create_table... functions), we do not assign a table
 
171
      map id here.  Instead we assign a value that is not used
 
172
      elsewhere, and then assign a table map id inside open_table()
 
173
      under the protection of the LOCK_open mutex.
 
174
    */
 
175
    share->table_map_id= UINT32_MAX;
 
176
    share->cached_row_logging_check= -1;
 
177
 
 
178
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
 
179
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
 
180
    pthread_cond_init(&share->cond, NULL);
 
181
  }
 
182
  return(share);
 
183
}
 
184
 
 
185
 
 
186
/*
 
187
  Initialize share for temporary tables
 
188
 
 
189
  SYNOPSIS
 
190
    init_tmp_table_share()
 
191
    session         thread handle
 
192
    share       Share to fill
 
193
    key         Table_cache_key, as generated from create_table_def_key.
 
194
                must start with db name.
 
195
    key_length  Length of key
 
196
    table_name  Table name
 
197
    path        Path to file (possible in lower case) without .frm
 
198
 
 
199
  NOTES
 
200
    This is different from alloc_table_share() because temporary tables
 
201
    don't have to be shared between threads or put into the table def
 
202
    cache, so we can do some things notable simpler and faster
 
203
 
 
204
    If table is not put in session->temporary_tables (happens only when
 
205
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
 
206
    use key_length= 0 as neither table_cache_key or key_length will be used).
 
207
*/
 
208
 
 
209
void init_tmp_table_share(Session *session, TABLE_SHARE *share, const char *key,
 
210
                          uint32_t key_length, const char *table_name,
 
211
                          const char *path)
 
212
{
 
213
 
 
214
  memset(share, 0, sizeof(*share));
 
215
  init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
216
  share->table_category=         TABLE_CATEGORY_TEMPORARY;
 
217
  share->tmp_table=              INTERNAL_TMP_TABLE;
 
218
  share->db.str=                 (char*) key;
 
219
  share->db.length=              strlen(key);
 
220
  share->table_cache_key.str=    (char*) key;
 
221
  share->table_cache_key.length= key_length;
 
222
  share->table_name.str=         (char*) table_name;
 
223
  share->table_name.length=      strlen(table_name);
 
224
  share->path.str=               (char*) path;
 
225
  share->normalized_path.str=    (char*) path;
 
226
  share->path.length= share->normalized_path.length= strlen(path);
 
227
 
 
228
  /*
 
229
    Temporary tables are not replicated, but we set up these fields
 
230
    anyway to be able to catch errors.
 
231
   */
 
232
  share->table_map_version= ~(uint64_t)0;
 
233
  share->cached_row_logging_check= -1;
 
234
 
 
235
  /*
 
236
    table_map_id is also used for MERGE tables to suppress repeated
 
237
    compatibility checks.
 
238
  */
 
239
  share->table_map_id= (ulong) session->query_id;
 
240
 
 
241
  return;
 
242
}
 
243
 
 
244
 
 
245
/*
 
246
  Free table share and memory used by it
 
247
 
 
248
  SYNOPSIS
 
249
    free_table_share()
 
250
    share               Table share
 
251
 
 
252
  NOTES
 
253
    share->mutex must be locked when we come here if it's not a temp table
 
254
*/
 
255
 
 
256
void free_table_share(TABLE_SHARE *share)
 
257
{
 
258
  MEM_ROOT mem_root;
 
259
  assert(share->ref_count == 0);
 
260
 
 
261
  /*
 
262
    If someone is waiting for this to be deleted, inform it about this.
 
263
    Don't do a delete until we know that no one is refering to this anymore.
 
264
  */
 
265
  if (share->tmp_table == NO_TMP_TABLE)
 
266
  {
 
267
    /* share->mutex is locked in release_table_share() */
 
268
    while (share->waiting_on_cond)
 
269
    {
 
270
      pthread_cond_broadcast(&share->cond);
 
271
      pthread_cond_wait(&share->cond, &share->mutex);
 
272
    }
 
273
    /* No thread refers to this anymore */
 
274
    pthread_mutex_unlock(&share->mutex);
 
275
    pthread_mutex_destroy(&share->mutex);
 
276
    pthread_cond_destroy(&share->cond);
 
277
  }
 
278
  hash_free(&share->name_hash);
 
279
 
 
280
  plugin_unlock(NULL, share->db_plugin);
 
281
  share->db_plugin= 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)
 
290
{
 
291
  enum_field_types field_type;
 
292
 
 
293
  switch(proto_field_type)
 
294
  {
 
295
  case drizzle::Table::Field::TINYINT:
 
296
    field_type= DRIZZLE_TYPE_TINY;
 
297
    break;
 
298
  case drizzle::Table::Field::INTEGER:
 
299
    field_type= DRIZZLE_TYPE_LONG;
 
300
    break;
 
301
  case drizzle::Table::Field::DOUBLE:
 
302
    field_type= DRIZZLE_TYPE_DOUBLE;
 
303
    break;
 
304
  case drizzle::Table::Field::TIMESTAMP:
 
305
    field_type= DRIZZLE_TYPE_TIMESTAMP;
 
306
    break;
 
307
  case drizzle::Table::Field::BIGINT:
 
308
    field_type= DRIZZLE_TYPE_LONGLONG;
 
309
    break;
 
310
  case drizzle::Table::Field::DATETIME:
 
311
    field_type= DRIZZLE_TYPE_DATETIME;
 
312
    break;
 
313
  case drizzle::Table::Field::DATE:
 
314
    field_type= DRIZZLE_TYPE_DATE;
 
315
    break;
 
316
  case drizzle::Table::Field::VARCHAR:
 
317
    field_type= DRIZZLE_TYPE_VARCHAR;
 
318
    break;
 
319
  case drizzle::Table::Field::DECIMAL:
 
320
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
321
    break;
 
322
  case drizzle::Table::Field::ENUM:
 
323
    field_type= DRIZZLE_TYPE_ENUM;
 
324
    break;
 
325
  case drizzle::Table::Field::BLOB:
 
326
    field_type= DRIZZLE_TYPE_BLOB;
 
327
    break;
 
328
  case drizzle::Table::Field::VIRTUAL:
 
329
    field_type= DRIZZLE_TYPE_VIRTUAL;
 
330
    break;
 
331
  default:
 
332
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
 
333
    assert(1);
 
334
  }
 
335
 
 
336
  return field_type;
 
337
}
 
338
 
 
339
Item * default_value_item(enum_field_types field_type,
 
340
                          const CHARSET_INFO *charset,
 
341
                          bool default_null, string default_value,
 
342
                          string default_bin_value)
 
343
{
 
344
  Item *default_item= NULL;
 
345
  int error= 0;
 
346
 
 
347
  if(default_null)
 
348
  {
 
349
    return new Item_null();
 
350
  }
 
351
 
 
352
  switch(field_type)
 
353
  {
 
354
  case DRIZZLE_TYPE_TINY:
 
355
  case DRIZZLE_TYPE_LONG:
 
356
  case DRIZZLE_TYPE_LONGLONG:
 
357
    default_item= new Item_int(default_value.c_str(),
 
358
                               (int64_t) my_strtoll10(default_value.c_str(),
 
359
                                                      NULL,
 
360
                                                      &error),
 
361
                               default_value.length());
 
362
    break;
 
363
  case DRIZZLE_TYPE_DOUBLE:
 
364
    default_item= new Item_float(default_value.c_str(), default_value.length());
 
365
    break;
 
366
  case DRIZZLE_TYPE_NULL:
 
367
    return new Item_null();
 
368
  case DRIZZLE_TYPE_TIMESTAMP:
 
369
  case DRIZZLE_TYPE_DATETIME:
 
370
  case DRIZZLE_TYPE_DATE:
 
371
    if(default_value.compare("NOW()")==0)
 
372
      break;
 
373
  case DRIZZLE_TYPE_ENUM:
 
374
    default_item= new Item_string(default_value.c_str(),
 
375
                                  default_value.length(),
 
376
                                  system_charset_info);
 
377
    break;
 
378
  case DRIZZLE_TYPE_VARCHAR:
 
379
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
 
380
    if(charset==&my_charset_bin)
 
381
    {
 
382
      default_item= new Item_string(default_bin_value.c_str(),
 
383
                                    default_bin_value.length(),
 
384
                                    &my_charset_bin);
 
385
    }
 
386
    else
 
387
    {
 
388
      default_item= new Item_string(default_value.c_str(),
 
389
                                    default_value.length(),
 
390
                                    system_charset_info);
 
391
    }
 
392
    break;
 
393
  case DRIZZLE_TYPE_VIRTUAL:
 
394
    break;
 
395
  case DRIZZLE_TYPE_NEWDECIMAL:
 
396
    default_item= new Item_decimal(default_value.c_str(),
 
397
                                   default_value.length(),
 
398
                                   system_charset_info);
 
399
    break;
 
400
  }
 
401
 
 
402
  return default_item;
 
403
}
 
404
 
 
405
int parse_table_proto(Session *session, drizzle::Table &table, TABLE_SHARE *share)
 
406
{
 
407
  int error= 0;
 
408
 
 
409
  {
 
410
    LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
 
411
                              strlen(table.engine().name().c_str()) };
 
412
    share->db_plugin= ha_resolve_by_name(session, &engine_name);
 
413
  }
 
414
 
 
415
  share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
 
416
 
 
417
  drizzle::Table::TableOptions table_options;
 
418
 
 
419
  if(table.has_options())
 
420
    table_options= table.options();
 
421
 
 
422
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
 
423
 
 
424
  if(table_options.has_pack_keys())
 
425
  {
 
426
    if(table_options.pack_keys())
 
427
      db_create_options|= HA_OPTION_PACK_KEYS;
 
428
    else
 
429
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
 
430
  }
 
431
 
 
432
  if(table_options.pack_record())
 
433
    db_create_options|= HA_OPTION_PACK_RECORD;
 
434
 
 
435
  if(table_options.has_checksum())
 
436
  {
 
437
    if(table_options.checksum())
 
438
      db_create_options|= HA_OPTION_CHECKSUM;
 
439
    else
 
440
      db_create_options|= HA_OPTION_NO_CHECKSUM;
 
441
  }
 
442
 
 
443
  if(table_options.has_delay_key_write())
 
444
  {
 
445
    if(table_options.delay_key_write())
 
446
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
 
447
    else
 
448
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
 
449
  }
 
450
 
 
451
  /* db_create_options was stored as 2 bytes in FRM
 
452
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
 
453
   */
 
454
  share->db_create_options= (db_create_options & 0x0000FFFF);
 
455
  share->db_options_in_use= share->db_create_options;
 
456
 
 
457
 
 
458
  share->avg_row_length= table_options.has_avg_row_length() ?
 
459
    table_options.avg_row_length() : 0;
 
460
 
 
461
  share->page_checksum= table_options.has_page_checksum() ?
 
462
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
463
    : HA_CHOICE_UNDEF;
 
464
 
 
465
  share->row_type= table_options.has_row_type() ?
 
466
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
467
 
 
468
  share->block_size= table_options.has_block_size() ?
 
469
    table_options.block_size() : 0;
 
470
 
 
471
  share->table_charset= get_charset(table_options.has_collation_id()?
 
472
                                    table_options.collation_id() : 0);
 
473
 
 
474
  if (!share->table_charset)
 
475
  {
 
476
    /* unknown charset in head[38] or pre-3.23 frm */
 
477
    if (use_mb(default_charset_info))
 
478
    {
 
479
      /* Warn that we may be changing the size of character columns */
 
480
      errmsg_printf(ERRMSG_LVL_WARN,
 
481
                    _("'%s' had no or invalid character set, "
 
482
                      "and default character set is multi-byte, "
 
483
                      "so character column sizes may have changed"),
 
484
                    share->path.str);
 
485
    }
 
486
    share->table_charset= default_charset_info;
 
487
  }
 
488
 
 
489
  share->db_record_offset= 1;
 
490
 
 
491
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
492
 
 
493
  share->db_low_byte_first= true;
 
494
 
 
495
  share->max_rows= table_options.has_max_rows() ?
 
496
    table_options.max_rows() : 0;
 
497
 
 
498
  share->min_rows= table_options.has_min_rows() ?
 
499
    table_options.min_rows() : 0;
 
500
 
 
501
  share->keys= table.indexes_size();
 
502
 
 
503
  share->key_parts= 0;
 
504
  for(int indx= 0; indx < table.indexes_size(); indx++)
 
505
    share->key_parts+= table.indexes(indx).index_part_size();
 
506
 
 
507
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
508
                                     table.indexes_size() * sizeof(KEY)
 
509
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
510
 
 
511
  KEY_PART_INFO *key_part;
 
512
 
 
513
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
514
    (share->key_info+table.indexes_size());
 
515
 
 
516
 
 
517
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
518
                                            sizeof(ulong*)*share->key_parts);
 
519
 
 
520
  share->keynames.count= table.indexes_size();
 
521
  share->keynames.name= NULL;
 
522
  share->keynames.type_names= (const char**)
 
523
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
524
 
 
525
  share->keynames.type_lengths= (unsigned int*)
 
526
    alloc_root(&share->mem_root,
 
527
               sizeof(unsigned int) * (table.indexes_size()+1));
 
528
 
 
529
  share->keynames.type_names[share->keynames.count]= NULL;
 
530
  share->keynames.type_lengths[share->keynames.count]= 0;
 
531
 
 
532
  KEY* keyinfo= share->key_info;
 
533
  for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
534
  {
 
535
    drizzle::Table::Index indx= table.indexes(keynr);
 
536
 
 
537
    keyinfo->table= 0;
 
538
    keyinfo->flags= 0;
 
539
 
 
540
    if(indx.is_unique())
 
541
      keyinfo->flags|= HA_NOSAME;
 
542
 
 
543
    if(indx.has_options())
 
544
    {
 
545
      drizzle::Table::Index::IndexOptions indx_options= indx.options();
 
546
      if(indx_options.pack_key())
 
547
        keyinfo->flags|= HA_PACK_KEY;
 
548
 
 
549
      if(indx_options.var_length_key())
 
550
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
551
 
 
552
      if(indx_options.null_part_key())
 
553
        keyinfo->flags|= HA_NULL_PART_KEY;
 
554
 
 
555
      if(indx_options.binary_pack_key())
 
556
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
557
 
 
558
      if(indx_options.has_partial_segments())
 
559
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
560
 
 
561
      if(indx_options.auto_generated_key())
 
562
        keyinfo->flags|= HA_GENERATED_KEY;
 
563
 
 
564
      if(indx_options.has_key_block_size())
 
565
      {
 
566
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
567
        keyinfo->block_size= indx_options.key_block_size();
 
568
      }
 
569
      else
 
570
      {
 
571
        keyinfo->block_size= 0;
 
572
      }
 
573
 
 
574
    }
 
575
 
 
576
    switch(indx.type())
 
577
    {
 
578
    case drizzle::Table::Index::UNKNOWN_INDEX:
 
579
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
580
      break;
 
581
    case drizzle::Table::Index::BTREE:
 
582
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
583
      break;
 
584
    case drizzle::Table::Index::RTREE:
 
585
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
586
      break;
 
587
    case drizzle::Table::Index::HASH:
 
588
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
589
      break;
 
590
    case drizzle::Table::Index::FULLTEXT:
 
591
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
592
 
 
593
    default:
 
594
      /* TODO: suitable warning ? */
 
595
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
596
      break;
 
597
    }
 
598
 
 
599
    keyinfo->key_length= indx.key_length();
 
600
 
 
601
    keyinfo->key_parts= indx.index_part_size();
 
602
 
 
603
    keyinfo->key_part= key_part;
 
604
    keyinfo->rec_per_key= rec_per_key;
 
605
 
 
606
    for(unsigned int partnr= 0;
 
607
        partnr < keyinfo->key_parts;
 
608
        partnr++, key_part++)
 
609
    {
 
610
      drizzle::Table::Index::IndexPart part;
 
611
      part= indx.index_part(partnr);
 
612
 
 
613
      *rec_per_key++=0;
 
614
 
 
615
      key_part->field= NULL;
 
616
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
 
617
      key_part->null_bit= 0;
 
618
      /* key_part->null_offset is only set if null_bit (see later) */
 
619
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
620
      /* key_part->type ???? */
 
621
      key_part->key_part_flag= 0;
 
622
      if(part.has_in_reverse_order())
 
623
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
624
 
 
625
      key_part->length= part.compare_length();
 
626
 
 
627
      key_part->store_length= key_part->length;
 
628
 
 
629
      /* key_part->offset is set later */
 
630
      key_part->key_type= part.key_type();
 
631
 
 
632
    }
 
633
 
 
634
    if(!indx.has_comment())
 
635
    {
 
636
      keyinfo->comment.length= 0;
 
637
      keyinfo->comment.str= NULL;
 
638
    }
 
639
    else
 
640
    {
 
641
      keyinfo->flags|= HA_USES_COMMENT;
 
642
      keyinfo->comment.length= indx.comment().length();
 
643
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
644
                                         indx.comment().c_str(),
 
645
                                         keyinfo->comment.length);
 
646
    }
 
647
 
 
648
    keyinfo->name= strmake_root(&share->mem_root,
 
649
                                indx.name().c_str(),
 
650
                                indx.name().length());
 
651
 
 
652
    share->keynames.type_names[keynr]= keyinfo->name;
 
653
    share->keynames.type_lengths[keynr]= indx.name().length();
 
654
  }
 
655
 
 
656
  share->keys_for_keyread.init(0);
 
657
  share->keys_in_use.init(share->keys);
 
658
 
 
659
  if(table_options.has_connect_string())
 
660
  {
 
661
    size_t len= table_options.connect_string().length();
 
662
    const char* str= table_options.connect_string().c_str();
 
663
 
 
664
    share->connect_string.length= len;
 
665
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
666
  }
 
667
 
 
668
  if(table_options.has_comment())
 
669
  {
 
670
    size_t len= table_options.comment().length();
 
671
    const char* str= table_options.comment().c_str();
 
672
 
 
673
    share->comment.length= len;
 
674
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
675
  }
 
676
 
 
677
  share->key_block_size= table_options.has_key_block_size() ?
 
678
    table_options.key_block_size() : 0;
 
679
 
 
680
  share->fields= table.field_size();
 
681
  share->vfields= 0;
 
682
  share->stored_fields= share->fields;
 
683
 
 
684
  share->field= (Field**) alloc_root(&share->mem_root,
 
685
                                     ((share->fields+1) * sizeof(Field*)));
 
686
  share->field[share->fields]= NULL;
 
687
 
 
688
  uint32_t null_fields= 0;
 
689
  share->reclength= 0;
 
690
 
 
691
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
 
692
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
 
693
 
 
694
  assert(field_offsets && field_pack_length); // TODO: fixme
 
695
 
 
696
  uint32_t interval_count= 0;
 
697
  uint32_t interval_parts= 0;
 
698
 
 
699
  uint32_t stored_columns_reclength= 0;
 
700
 
 
701
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
702
  {
 
703
    drizzle::Table::Field pfield= table.field(fieldnr);
 
704
    if(pfield.has_constraints() && pfield.constraints().is_nullable())
 
705
      null_fields++;
 
706
 
 
707
    bool field_is_stored= true;
 
708
 
 
709
    enum_field_types drizzle_field_type=
 
710
      proto_field_type_to_drizzle_type(pfield.type());
 
711
 
 
712
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
713
    {
 
714
      drizzle::Table::Field::VirtualFieldOptions field_options=
 
715
        pfield.virtual_options();
 
716
 
 
717
      drizzle_field_type=proto_field_type_to_drizzle_type(field_options.type());
 
718
 
 
719
      field_is_stored= field_options.physically_stored();
 
720
    }
 
721
 
 
722
    field_offsets[fieldnr]= stored_columns_reclength;
 
723
 
 
724
    /* the below switch is very similar to
 
725
       Create_field::create_length_to_internal_length in field.cc
 
726
       (which should one day be replace by just this code)
 
727
    */
 
728
    switch(drizzle_field_type)
 
729
    {
 
730
    case DRIZZLE_TYPE_BLOB:
 
731
    case DRIZZLE_TYPE_VARCHAR:
 
732
      {
 
733
        drizzle::Table::Field::StringFieldOptions field_options=
 
734
          pfield.string_options();
 
735
 
 
736
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
737
                                            field_options.collation_id() : 0);
 
738
 
 
739
        if (!cs)
 
740
          cs= default_charset_info;
 
741
 
 
742
        field_pack_length[fieldnr]=
 
743
          calc_pack_length(drizzle_field_type,
 
744
                           field_options.length() * cs->mbmaxlen);
 
745
 
 
746
      }
 
747
      break;
 
748
    case DRIZZLE_TYPE_ENUM:
 
749
      {
 
750
        drizzle::Table::Field::SetFieldOptions field_options=
 
751
          pfield.set_options();
 
752
 
 
753
        field_pack_length[fieldnr]=
 
754
          get_enum_pack_length(field_options.field_value_size());
 
755
 
 
756
        interval_count++;
 
757
        interval_parts+= field_options.field_value_size();
 
758
      }
 
759
      break;
 
760
    case DRIZZLE_TYPE_NEWDECIMAL:
 
761
      {
 
762
        drizzle::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
763
 
 
764
        field_pack_length[fieldnr]=
 
765
          my_decimal_get_binary_size(fo.precision(), fo.scale());
 
766
      }
 
767
      break;
 
768
    default:
 
769
      /* Zero is okay here as length is fixed for other types. */
 
770
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
 
771
    }
 
772
 
 
773
    share->reclength+= field_pack_length[fieldnr];
 
774
 
 
775
    if(field_is_stored)
 
776
      stored_columns_reclength+= field_pack_length[fieldnr];
 
777
  }
 
778
 
 
779
  /* data_offset added to stored_rec_length later */
 
780
  share->stored_rec_length= stored_columns_reclength;
 
781
 
 
782
  /* fix up offsets for non-stored fields (at end of record) */
 
783
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
784
  {
 
785
    drizzle::Table::Field pfield= table.field(fieldnr);
 
786
 
 
787
    bool field_is_stored= true;
 
788
 
 
789
    enum_field_types drizzle_field_type=
 
790
      proto_field_type_to_drizzle_type(pfield.type());
 
791
 
 
792
    if(drizzle_field_type==DRIZZLE_TYPE_VIRTUAL)
 
793
    {
 
794
      drizzle::Table::Field::VirtualFieldOptions field_options=
 
795
        pfield.virtual_options();
 
796
 
 
797
      field_is_stored= field_options.physically_stored();
 
798
    }
 
799
 
 
800
    if(!field_is_stored)
 
801
    {
 
802
      field_offsets[fieldnr]= stored_columns_reclength;
 
803
      stored_columns_reclength+= field_pack_length[fieldnr];
 
804
    }
 
805
  }
 
806
  share->null_fields= null_fields;
 
807
 
 
808
  ulong null_bits= null_fields;
 
809
  if(!table_options.pack_record())
 
810
    null_bits++;
 
811
  ulong data_offset= (null_bits + 7)/8;
 
812
 
 
813
 
 
814
  share->reclength+= data_offset;
 
815
  share->stored_rec_length+= data_offset;
 
816
 
 
817
  ulong rec_buff_length;
 
818
 
 
819
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
820
  share->rec_buff_length= rec_buff_length;
 
821
 
 
822
  unsigned char* record= NULL;
 
823
 
 
824
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
 
825
                                     rec_buff_length)))
 
826
    abort();
 
827
 
 
828
  memset(record, 0, rec_buff_length);
 
829
 
 
830
  int null_count= 0;
 
831
 
 
832
  if(!table_options.pack_record())
 
833
  {
 
834
    null_count++; // one bit for delete mark.
 
835
    *record|= 1;
 
836
  }
 
837
 
 
838
  share->default_values= record;
 
839
 
 
840
  if(interval_count)
 
841
  {
 
842
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
843
                                           interval_count*sizeof(TYPELIB));
 
844
  }
 
845
  else
 
846
    share->intervals= NULL;
 
847
 
 
848
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
849
                                  (share->fields+1)*sizeof(char*));
 
850
 
 
851
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
852
                                  (share->fields+1)*sizeof(unsigned int));
 
853
 
 
854
  share->fieldnames.type_names[share->fields]= NULL;
 
855
  share->fieldnames.type_lengths[share->fields]= 0;
 
856
  share->fieldnames.count= share->fields;
 
857
 
 
858
 
 
859
  /* Now fix the TYPELIBs for the intervals (enum values)
 
860
     and field names.
 
861
   */
 
862
 
 
863
  uint32_t interval_nr= 0;
 
864
 
 
865
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
866
  {
 
867
    drizzle::Table::Field pfield= table.field(fieldnr);
 
868
 
 
869
    /* field names */
 
870
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
 
871
                                                        pfield.name().c_str(),
 
872
                                                        pfield.name().length());
 
873
 
 
874
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
 
875
 
 
876
    /* enum typelibs */
 
877
    if(pfield.type() != drizzle::Table::Field::ENUM)
 
878
      continue;
 
879
 
 
880
    drizzle::Table::Field::SetFieldOptions field_options=
 
881
      pfield.set_options();
 
882
 
 
883
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
884
                                             field_options.collation_id() : 0);
 
885
 
 
886
    if (!charset)
 
887
      charset= default_charset_info;
 
888
 
 
889
    TYPELIB *t= &(share->intervals[interval_nr]);
 
890
 
 
891
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
892
                           (field_options.field_value_size()+1)*sizeof(char*));
 
893
 
 
894
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
895
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
 
896
 
 
897
    t->type_names[field_options.field_value_size()]= NULL;
 
898
    t->type_lengths[field_options.field_value_size()]= 0;
 
899
 
 
900
    t->count= field_options.field_value_size();
 
901
    t->name= NULL;
 
902
 
 
903
    for(int n=0; n < field_options.field_value_size(); n++)
 
904
    {
 
905
      t->type_names[n]= strmake_root(&share->mem_root,
 
906
                                     field_options.field_value(n).c_str(),
 
907
                                     field_options.field_value(n).length());
 
908
 
 
909
      /* Go ask the charset what the length is as for "" length=1
 
910
         and there's stripping spaces or some other crack going on.
 
911
       */
 
912
      uint32_t lengthsp;
 
913
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
914
                                        field_options.field_value(n).length());
 
915
      t->type_lengths[n]= lengthsp;
 
916
    }
 
917
    interval_nr++;
 
918
  }
 
919
 
 
920
 
 
921
  /* and read the fields */
 
922
  interval_nr= 0;
 
923
 
 
924
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
925
 
 
926
  if(use_hash)
 
927
    use_hash= !hash_init(&share->name_hash,
 
928
                         system_charset_info,
 
929
                         share->fields, 0, 0,
 
930
                         (hash_get_key) get_field_name, 0, 0);
 
931
 
 
932
  unsigned char* null_pos= record;;
 
933
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
 
934
 
 
935
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
936
  {
 
937
    drizzle::Table::Field pfield= table.field(fieldnr);
 
938
 
 
939
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
940
 
 
941
    switch(pfield.format())
 
942
    {
 
943
    case drizzle::Table::Field::DefaultFormat:
 
944
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
945
      break;
 
946
    case drizzle::Table::Field::FixedFormat:
 
947
      column_format= COLUMN_FORMAT_TYPE_FIXED;
 
948
      break;
 
949
    case drizzle::Table::Field::DynamicFormat:
 
950
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
 
951
      break;
 
952
    default:
 
953
      assert(1);
 
954
    }
 
955
 
 
956
    Field::utype unireg_type= Field::NONE;
 
957
 
 
958
    if(pfield.has_numeric_options()
 
959
       && pfield.numeric_options().is_autoincrement())
 
960
    {
 
961
      unireg_type= Field::NEXT_NUMBER;
 
962
    }
 
963
 
 
964
    if(pfield.has_options()
 
965
       && pfield.options().has_default_value()
 
966
       && pfield.options().default_value().compare("NOW()")==0)
 
967
    {
 
968
      if(pfield.options().has_update_value()
 
969
         && pfield.options().update_value().compare("NOW()")==0)
 
970
      {
 
971
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
972
      }
 
973
      else if (!pfield.options().has_update_value())
 
974
      {
 
975
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
976
      }
 
977
      else
 
978
        assert(1); // Invalid update value.
 
979
    }
 
980
    else if (pfield.has_options()
 
981
             && pfield.options().has_update_value()
 
982
             && pfield.options().update_value().compare("NOW()")==0)
 
983
    {
 
984
      unireg_type= Field::TIMESTAMP_UN_FIELD;
 
985
    }
 
986
 
 
987
    LEX_STRING comment;
 
988
    if(!pfield.has_comment())
 
989
    {
 
990
      comment.str= (char*)"";
 
991
      comment.length= 0;
 
992
    }
 
993
    else
 
994
    {
 
995
      size_t len= pfield.comment().length();
 
996
      const char* str= pfield.comment().c_str();
 
997
 
 
998
      comment.str= strmake_root(&share->mem_root, str, len);
 
999
      comment.length= len;
 
1000
    }
 
1001
 
 
1002
    enum_field_types field_type;
 
1003
    virtual_column_info *vcol_info= NULL;
 
1004
    bool field_is_stored= true;
 
1005
 
 
1006
 
 
1007
    field_type= proto_field_type_to_drizzle_type(pfield.type());
 
1008
 
 
1009
    if(field_type==DRIZZLE_TYPE_VIRTUAL)
 
1010
    {
 
1011
      drizzle::Table::Field::VirtualFieldOptions field_options=
 
1012
        pfield.virtual_options();
 
1013
 
 
1014
      vcol_info= new virtual_column_info();
 
1015
      field_type= proto_field_type_to_drizzle_type(field_options.type());
 
1016
      field_is_stored= field_options.physically_stored();
 
1017
 
 
1018
      size_t len= field_options.expression().length();
 
1019
      const char* str= field_options.expression().c_str();
 
1020
 
 
1021
      vcol_info->expr_str.str= strmake_root(&share->mem_root, str, len);
 
1022
      vcol_info->expr_str.length= len;
 
1023
 
 
1024
      share->vfields++;
 
1025
    }
 
1026
 
 
1027
    const CHARSET_INFO *charset= &my_charset_bin;
 
1028
 
 
1029
    if(field_type==DRIZZLE_TYPE_BLOB
 
1030
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
1031
    {
 
1032
      drizzle::Table::Field::StringFieldOptions field_options=
 
1033
        pfield.string_options();
 
1034
 
 
1035
      charset= get_charset(field_options.has_collation_id()?
 
1036
                           field_options.collation_id() : 0);
 
1037
 
 
1038
      if (!charset)
 
1039
        charset= default_charset_info;
 
1040
 
 
1041
    }
 
1042
 
 
1043
    if(field_type==DRIZZLE_TYPE_ENUM)
 
1044
    {
 
1045
      drizzle::Table::Field::SetFieldOptions field_options=
 
1046
        pfield.set_options();
 
1047
 
 
1048
      charset= get_charset(field_options.has_collation_id()?
 
1049
                           field_options.collation_id() : 0);
 
1050
 
 
1051
      if (!charset)
 
1052
        charset= default_charset_info;
 
1053
 
 
1054
    }
 
1055
 
 
1056
    Item *default_value= NULL;
 
1057
 
 
1058
    if(pfield.options().has_default_value()
 
1059
       || pfield.options().has_default_null()
 
1060
       || pfield.options().has_default_bin_value())
 
1061
    {
 
1062
      default_value= default_value_item(field_type,
 
1063
                                        charset,
 
1064
                                        pfield.options().default_null(),
 
1065
                                        pfield.options().default_value(),
 
1066
                                        pfield.options().default_bin_value());
 
1067
    }
 
1068
 
 
1069
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
 
1070
 
 
1071
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
1072
    memset(&temp_table, 0, sizeof(temp_table));
 
1073
    temp_table.s= share;
 
1074
    temp_table.in_use= session;
 
1075
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
 
1076
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
1077
 
 
1078
    Field* f= make_field(share, &share->mem_root,
 
1079
                         record+field_offsets[fieldnr]+data_offset,
 
1080
                         pfield.options().length(),
 
1081
                         null_pos,
 
1082
                         null_bit_pos,
 
1083
                         pack_flag,
 
1084
                         field_type,
 
1085
                         charset,
 
1086
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
1087
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
1088
                         share->intervals+(interval_nr++)
 
1089
                         : (TYPELIB*) 0),
 
1090
                        share->fieldnames.type_names[fieldnr]);
 
1091
 
 
1092
    share->field[fieldnr]= f;
 
1093
 
 
1094
    f->init(&temp_table); /* blob default values need table obj */
 
1095
 
 
1096
    if(!(f->flags & NOT_NULL_FLAG))
 
1097
    {
 
1098
      *f->null_ptr|= f->null_bit;
 
1099
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
 
1100
        null_pos++;
 
1101
      null_count++;
 
1102
    }
 
1103
 
 
1104
    if(default_value)
 
1105
    {
 
1106
      int res= default_value->save_in_field(f, 1);
 
1107
      (void)res; // TODO error handle;
 
1108
    }
 
1109
    else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
 
1110
            (f->flags & NOT_NULL_FLAG))
 
1111
    {
 
1112
      f->set_notnull();
 
1113
      f->store((int64_t) 1, true);
 
1114
    }
 
1115
    else
 
1116
      f->reset();
 
1117
 
 
1118
    /* hack to undo f->init() */
 
1119
    f->table= NULL;
 
1120
    f->orig_table= NULL;
 
1121
 
 
1122
    f->field_index= fieldnr;
 
1123
    f->comment= comment;
 
1124
    f->vcol_info= vcol_info;
 
1125
    f->is_stored= field_is_stored;
 
1126
    if(!default_value
 
1127
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
1128
       && (f->flags & NOT_NULL_FLAG)
 
1129
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
 
1130
      f->flags|= NO_DEFAULT_VALUE_FLAG;
 
1131
 
 
1132
    if(f->unireg_check == Field::NEXT_NUMBER)
 
1133
      share->found_next_number_field= &(share->field[fieldnr]);
 
1134
 
 
1135
    if(share->timestamp_field == f)
 
1136
      share->timestamp_field_offset= fieldnr;
 
1137
 
 
1138
    if (use_hash) /* supposedly this never fails... but comments lie */
 
1139
      (void) my_hash_insert(&share->name_hash,
 
1140
                            (unsigned char*)&(share->field[fieldnr]));
 
1141
 
 
1142
    if(!f->is_stored)
 
1143
    {
 
1144
      share->stored_fields--;
 
1145
    }
 
1146
  }
 
1147
 
 
1148
  keyinfo= share->key_info;
 
1149
  for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
 
1150
  {
 
1151
    key_part= keyinfo->key_part;
 
1152
 
 
1153
    for(unsigned int partnr= 0;
 
1154
        partnr < keyinfo->key_parts;
 
1155
        partnr++, key_part++)
 
1156
    {
 
1157
      /* Fix up key_part->offset by adding data_offset.
 
1158
         We really should compute offset as well.
 
1159
         But at least this way we are a little better. */
 
1160
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
1161
    }
 
1162
  }
 
1163
 
 
1164
  /*
 
1165
    We need to set the unused bits to 1. If the number of bits is a multiple
 
1166
    of 8 there are no unused bits.
 
1167
  */
 
1168
 
 
1169
  if (null_count & 7)
 
1170
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
1171
 
 
1172
  share->null_bytes= (null_pos - (unsigned char*) record +
 
1173
                      (null_bit_pos + 7) / 8);
 
1174
 
 
1175
  share->last_null_bit_pos= null_bit_pos;
 
1176
 
 
1177
  free(field_offsets);
 
1178
  free(field_pack_length);
 
1179
 
 
1180
  handler *handler_file;
 
1181
 
 
1182
  if(!(handler_file= get_new_handler(share, session->mem_root,
 
1183
                                     share->db_type())))
 
1184
    abort(); // FIXME
 
1185
 
 
1186
  /* Fix key stuff */
 
1187
  if (share->key_parts)
 
1188
  {
 
1189
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
 
1190
                                       &share->keynames, 3) - 1);
 
1191
 
 
1192
    int64_t ha_option= handler_file->ha_table_flags();
 
1193
 
 
1194
    keyinfo= share->key_info;
 
1195
    key_part= keyinfo->key_part;
 
1196
 
 
1197
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
 
1198
    {
 
1199
      uint32_t usable_parts= 0;
 
1200
 
 
1201
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
 
1202
      {
 
1203
        /*
 
1204
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
1205
          declare this as a primary key.
 
1206
        */
 
1207
        primary_key=key;
 
1208
        for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
 
1209
        {
 
1210
          uint32_t fieldnr= key_part[i].fieldnr;
 
1211
          if (!fieldnr ||
 
1212
              share->field[fieldnr-1]->null_ptr ||
 
1213
              share->field[fieldnr-1]->key_length() !=
 
1214
              key_part[i].length)
 
1215
          {
 
1216
            primary_key=MAX_KEY;                // Can't be used
 
1217
            break;
 
1218
          }
 
1219
        }
 
1220
      }
 
1221
 
 
1222
      for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1223
      {
 
1224
        Field *field;
 
1225
        if (!key_part->fieldnr)
 
1226
        {
 
1227
//          error= 4;                             // Wrong file
 
1228
          abort(); // goto err;
 
1229
        }
 
1230
        field= key_part->field= share->field[key_part->fieldnr-1];
 
1231
        key_part->type= field->key_type();
 
1232
        if (field->null_ptr)
 
1233
        {
 
1234
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
 
1235
                                        share->default_values);
 
1236
          key_part->null_bit= field->null_bit;
 
1237
          key_part->store_length+=HA_KEY_NULL_LENGTH;
 
1238
          keyinfo->flags|=HA_NULL_PART_KEY;
 
1239
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
 
1240
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
 
1241
        }
 
1242
        if (field->type() == DRIZZLE_TYPE_BLOB ||
 
1243
            field->real_type() == DRIZZLE_TYPE_VARCHAR)
 
1244
        {
 
1245
          if (field->type() == DRIZZLE_TYPE_BLOB)
 
1246
            key_part->key_part_flag|= HA_BLOB_PART;
 
1247
          else
 
1248
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
 
1249
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
 
1250
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
 
1251
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
 
1252
        }
 
1253
        if (i == 0 && key != primary_key)
 
1254
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
 
1255
                           (keyinfo->key_parts == 1)) ?
 
1256
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
 
1257
        if (i == 0)
 
1258
          field->key_start.set_bit(key);
 
1259
        if (field->key_length() == key_part->length &&
 
1260
            !(field->flags & BLOB_FLAG))
 
1261
        {
 
1262
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
 
1263
          {
 
1264
            share->keys_for_keyread.set_bit(key);
 
1265
            field->part_of_key.set_bit(key);
 
1266
            field->part_of_key_not_clustered.set_bit(key);
 
1267
          }
 
1268
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
 
1269
            field->part_of_sortkey.set_bit(key);
 
1270
        }
 
1271
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
 
1272
            usable_parts == i)
 
1273
          usable_parts++;                       // For FILESORT
 
1274
        field->flags|= PART_KEY_FLAG;
 
1275
        if (key == primary_key)
 
1276
        {
 
1277
          field->flags|= PRI_KEY_FLAG;
 
1278
          /*
 
1279
            If this field is part of the primary key and all keys contains
 
1280
            the primary key, then we can use any key to find this column
 
1281
          */
 
1282
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
 
1283
          {
 
1284
            field->part_of_key= share->keys_in_use;
 
1285
            if (field->part_of_sortkey.is_set(key))
 
1286
              field->part_of_sortkey= share->keys_in_use;
 
1287
          }
 
1288
        }
 
1289
        if (field->key_length() != key_part->length)
 
1290
        {
 
1291
          key_part->key_part_flag|= HA_PART_KEY_SEG;
 
1292
        }
 
1293
      }
 
1294
      keyinfo->usable_key_parts= usable_parts; // Filesort
 
1295
 
 
1296
      set_if_bigger(share->max_key_length,keyinfo->key_length+
 
1297
                    keyinfo->key_parts);
 
1298
      share->total_key_length+= keyinfo->key_length;
 
1299
      /*
 
1300
        MERGE tables do not have unique indexes. But every key could be
 
1301
        an unique index on the underlying MyISAM table. (Bug #10400)
 
1302
      */
 
1303
      if ((keyinfo->flags & HA_NOSAME) ||
 
1304
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
 
1305
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
 
1306
    }
 
1307
    if (primary_key < MAX_KEY &&
 
1308
        (share->keys_in_use.is_set(primary_key)))
 
1309
    {
 
1310
      share->primary_key= primary_key;
 
1311
      /*
 
1312
        If we are using an integer as the primary key then allow the user to
 
1313
        refer to it as '_rowid'
 
1314
      */
 
1315
      if (share->key_info[primary_key].key_parts == 1)
 
1316
      {
 
1317
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1318
        if (field && field->result_type() == INT_RESULT)
 
1319
        {
 
1320
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
 
1321
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1322
                                      fieldnr);
 
1323
        }
 
1324
      }
 
1325
 
 
1326
    }
 
1327
    else
 
1328
      share->primary_key = MAX_KEY; // we do not have a primary key
 
1329
  }
 
1330
  else
 
1331
    share->primary_key= MAX_KEY;
 
1332
 
 
1333
  if (share->found_next_number_field)
 
1334
  {
 
1335
    Field *reg_field= *share->found_next_number_field;
 
1336
    if ((int) (share->next_number_index= (uint32_t)
 
1337
               find_ref_key(share->key_info, share->keys,
 
1338
                            share->default_values, reg_field,
 
1339
                            &share->next_number_key_offset,
 
1340
                            &share->next_number_keypart)) < 0)
 
1341
    {
 
1342
      /* Wrong field definition */
 
1343
      error= 4;
 
1344
      goto err;
 
1345
    }
 
1346
    else
 
1347
      reg_field->flags |= AUTO_INCREMENT_FLAG;
 
1348
  }
 
1349
 
 
1350
  if (share->blob_fields)
 
1351
  {
 
1352
    Field **ptr;
 
1353
    uint32_t k, *save;
 
1354
 
 
1355
    /* Store offsets to blob fields to find them fast */
 
1356
    if (!(share->blob_field= save=
 
1357
          (uint*) alloc_root(&share->mem_root,
 
1358
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
 
1359
      goto err;
 
1360
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
 
1361
    {
 
1362
      if ((*ptr)->flags & BLOB_FLAG)
 
1363
        (*save++)= k;
 
1364
    }
 
1365
  }
 
1366
 
 
1367
  share->db_low_byte_first= handler_file->low_byte_first();
 
1368
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
 
1369
 
 
1370
  my_bitmap_map *bitmaps;
 
1371
 
 
1372
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
 
1373
                                             share->column_bitmap_size)))
 
1374
    goto err;
 
1375
  bitmap_init(&share->all_set, bitmaps, share->fields, false);
 
1376
  bitmap_set_all(&share->all_set);
 
1377
 
 
1378
  delete handler_file;
 
1379
  return (0);
 
1380
 
 
1381
err:
 
1382
  share->error= error;
 
1383
  share->open_errno= my_errno;
 
1384
  share->errarg= 0;
 
1385
  hash_free(&share->name_hash);
 
1386
  delete handler_file;
 
1387
  open_table_error(share, error, share->open_errno, 0);
 
1388
  return error;
 
1389
}
 
1390
 
 
1391
/*
 
1392
  Read table definition from a binary / text based .frm file
 
1393
 
 
1394
  SYNOPSIS
 
1395
  open_table_def()
 
1396
  session               Thread handler
 
1397
  share         Fill this with table definition
 
1398
  db_flags      Bit mask of the following flags: OPEN_VIEW
 
1399
 
 
1400
  NOTES
 
1401
    This function is called when the table definition is not cached in
 
1402
    table_def_cache
 
1403
    The data is returned in 'share', which is alloced by
 
1404
    alloc_table_share().. The code assumes that share is initialized.
 
1405
 
 
1406
  RETURN VALUES
 
1407
   0    ok
 
1408
   1    Error (see open_table_error)
 
1409
   2    Error (see open_table_error)
 
1410
   3    Wrong data in .frm file
 
1411
   4    Error (see open_table_error)
 
1412
   5    Error (see open_table_error: charset unavailable)
 
1413
   6    Unknown .frm version
 
1414
*/
 
1415
 
 
1416
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
 
1417
{
 
1418
  int error;
 
1419
  bool error_given;
 
1420
  string        path("");
 
1421
 
 
1422
  error= 1;
 
1423
  error_given= 0;
 
1424
 
 
1425
  path.reserve(FN_REFLEN);
 
1426
  path.append(share->normalized_path.str);
 
1427
  string proto_path= path;
 
1428
 
 
1429
  path.append(reg_ext);
 
1430
 
 
1431
  proto_path.append(".dfe");
 
1432
 
 
1433
  drizzle::Table table;
 
1434
 
 
1435
  if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
 
1436
  {
 
1437
    if(error>0)
 
1438
    {
 
1439
      my_errno= error;
 
1440
      error= 1;
 
1441
    }
 
1442
    else
 
1443
    {
 
1444
      if(!table.IsInitialized())
 
1445
      {
 
1446
        error= 4;
 
1447
      }
 
1448
    }
 
1449
    goto err_not_open;
 
1450
  }
 
1451
 
 
1452
  parse_table_proto(session, table, share);
 
1453
 
 
1454
  share->table_category= get_table_category(& share->db, & share->table_name);
 
1455
 
 
1456
  if (!error)
 
1457
    session->status_var.opened_shares++;
 
1458
 
 
1459
err_not_open:
 
1460
  if (error && !error_given)
 
1461
  {
 
1462
    share->error= error;
 
1463
    open_table_error(share, error, (share->open_errno= my_errno), 0);
 
1464
  }
 
1465
 
 
1466
  return(error);
 
1467
}
 
1468
 
 
1469
/*
 
1470
  Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
 
1471
  This routine is used for error handling purposes.
 
1472
 
 
1473
  SYNOPSIS
 
1474
    clear_field_flag()
 
1475
    table                Table object for which virtual columns are set-up
 
1476
 
 
1477
  RETURN VALUE
 
1478
    NONE
 
1479
*/
 
1480
static void clear_field_flag(Table *table)
 
1481
{
 
1482
  Field **ptr;
 
1483
 
 
1484
  for (ptr= table->field; *ptr; ptr++)
 
1485
    (*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
 
1486
}
 
1487
 
 
1488
/*
 
1489
  The function uses the feature in fix_fields where the flag
 
1490
  GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
 
1491
  This field must always be reset before returning from the function
 
1492
  since it is used for other purposes as well.
 
1493
 
 
1494
  SYNOPSIS
 
1495
    fix_fields_vcol_func()
 
1496
    session                  The thread object
 
1497
    func_item            The item tree reference of the virtual columnfunction
 
1498
    table                The table object
 
1499
    field_name           The name of the processed field
 
1500
 
 
1501
  RETURN VALUE
 
1502
    true                 An error occurred, something was wrong with the
 
1503
                         function.
 
1504
    false                Ok, a partition field array was created
 
1505
*/
 
1506
 
 
1507
bool fix_fields_vcol_func(Session *session,
 
1508
                          Item* func_expr,
 
1509
                          Table *table,
 
1510
                          const char *field_name)
 
1511
{
 
1512
  uint32_t dir_length, home_dir_length;
 
1513
  bool result= true;
 
1514
  TableList tables;
 
1515
  TableList *save_table_list, *save_first_table, *save_last_table;
 
1516
  int error;
 
1517
  Name_resolution_context *context;
 
1518
  const char *save_where;
 
1519
  char* db_name;
 
1520
  char db_name_string[FN_REFLEN];
 
1521
  bool save_use_only_table_context;
 
1522
  Field **ptr, *field;
 
1523
  enum_mark_columns save_mark_used_columns= session->mark_used_columns;
 
1524
  assert(func_expr);
 
1525
 
 
1526
  /*
 
1527
    Set-up the TABLE_LIST object to be a list with a single table
 
1528
    Set the object to zero to create NULL pointers and set alias
 
1529
    and real name to table name and get database name from file name.
 
1530
  */
 
1531
 
 
1532
  bzero((void*)&tables, sizeof(TableList));
 
1533
  tables.alias= tables.table_name= (char*) table->s->table_name.str;
 
1534
  tables.table= table;
 
1535
  tables.next_local= NULL;
 
1536
  tables.next_name_resolution_table= NULL;
 
1537
  memcpy(db_name_string,
 
1538
         table->s->normalized_path.str,
 
1539
         table->s->normalized_path.length);
 
1540
  db_name_string[table->s->normalized_path.length]= '\0';
 
1541
  dir_length= dirname_length(db_name_string);
 
1542
  db_name_string[dir_length - 1]= 0;
 
1543
  home_dir_length= dirname_length(db_name_string);
 
1544
  db_name= &db_name_string[home_dir_length];
 
1545
  tables.db= db_name;
 
1546
 
 
1547
  session->mark_used_columns= MARK_COLUMNS_NONE;
 
1548
 
 
1549
  context= session->lex->current_context();
 
1550
  table->map= 1; //To ensure correct calculation of const item
 
1551
  table->get_fields_in_item_tree= true;
 
1552
  save_table_list= context->table_list;
 
1553
  save_first_table= context->first_name_resolution_table;
 
1554
  save_last_table= context->last_name_resolution_table;
 
1555
  context->table_list= &tables;
 
1556
  context->first_name_resolution_table= &tables;
 
1557
  context->last_name_resolution_table= NULL;
 
1558
  func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
 
1559
  save_where= session->where;
 
1560
  session->where= "virtual column function";
 
1561
 
 
1562
  /* Save the context before fixing the fields*/
 
1563
  save_use_only_table_context= session->lex->use_only_table_context;
 
1564
  session->lex->use_only_table_context= true;
 
1565
  /* Fix fields referenced to by the virtual column function */
 
1566
  error= func_expr->fix_fields(session, (Item**)0);
 
1567
  /* Restore the original context*/
 
1568
  session->lex->use_only_table_context= save_use_only_table_context;
 
1569
  context->table_list= save_table_list;
 
1570
  context->first_name_resolution_table= save_first_table;
 
1571
  context->last_name_resolution_table= save_last_table;
 
1572
 
 
1573
  if (unlikely(error))
 
1574
  {
 
1575
    clear_field_flag(table);
 
1576
    goto end;
 
1577
  }
 
1578
  session->where= save_where;
 
1579
  /*
 
1580
    Walk through the Item tree checking if all items are valid
 
1581
   to be part of the virtual column
 
1582
 */
 
1583
  error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
 
1584
  if (error)
 
1585
  {
 
1586
    my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
 
1587
    clear_field_flag(table);
 
1588
    goto end;
 
1589
  }
 
1590
  if (unlikely(func_expr->const_item()))
 
1591
  {
 
1592
    my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
 
1593
    clear_field_flag(table);
 
1594
    goto end;
 
1595
  }
 
1596
  /* Ensure that this virtual column is not based on another virtual field. */
 
1597
  ptr= table->field;
 
1598
  while ((field= *(ptr++)))
 
1599
  {
 
1600
    if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
 
1601
        (field->vcol_info))
 
1602
    {
 
1603
      my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
 
1604
      clear_field_flag(table);
 
1605
      goto end;
 
1606
    }
 
1607
  }
 
1608
  /*
 
1609
    Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
 
1610
    when calling fix_fields.
 
1611
  */
 
1612
  clear_field_flag(table);
 
1613
  result= false;
 
1614
 
 
1615
end:
 
1616
  table->get_fields_in_item_tree= false;
 
1617
  session->mark_used_columns= save_mark_used_columns;
 
1618
  table->map= 0; //Restore old value
 
1619
  return(result);
 
1620
}
 
1621
 
 
1622
/*
 
1623
  Unpack the definition of a virtual column
 
1624
 
 
1625
  SYNOPSIS
 
1626
    unpack_vcol_info_from_frm()
 
1627
    session                  Thread handler
 
1628
    table                Table with the checked field
 
1629
    field                Pointer to Field object
 
1630
    open_mode            Open table mode needed to determine
 
1631
                         which errors need to be generated in a failure
 
1632
    error_reported       updated flag for the caller that no other error
 
1633
                         messages are to be generated.
 
1634
 
 
1635
  RETURN VALUES
 
1636
    true            Failure
 
1637
    false           Success
 
1638
*/
 
1639
bool unpack_vcol_info_from_frm(Session *session,
 
1640
                               Table *table,
 
1641
                               Field *field,
 
1642
                               LEX_STRING *vcol_expr,
 
1643
                               open_table_mode open_mode,
 
1644
                               bool *error_reported)
 
1645
{
 
1646
  assert(vcol_expr);
 
1647
 
 
1648
  /*
 
1649
    Step 1: Construct a statement for the parser.
 
1650
    The parsed string needs to take the following format:
 
1651
    "PARSE_VCOL_EXPR (<expr_string_from_frm>)"
 
1652
  */
 
1653
  char *vcol_expr_str;
 
1654
  int str_len= 0;
 
1655
 
 
1656
  if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
 
1657
                                          vcol_expr->length +
 
1658
                                            parse_vcol_keyword.length + 3)))
 
1659
  {
 
1660
    return(true);
 
1661
  }
 
1662
  memcpy(vcol_expr_str,
 
1663
         (char*) parse_vcol_keyword.str,
 
1664
         parse_vcol_keyword.length);
 
1665
  str_len= parse_vcol_keyword.length;
 
1666
  memcpy(vcol_expr_str + str_len, "(", 1);
 
1667
  str_len++;
 
1668
  memcpy(vcol_expr_str + str_len,
 
1669
         (char*) vcol_expr->str,
 
1670
         vcol_expr->length);
 
1671
  str_len+= vcol_expr->length;
 
1672
  memcpy(vcol_expr_str + str_len, ")", 1);
 
1673
  str_len++;
 
1674
  memcpy(vcol_expr_str + str_len, "\0", 1);
 
1675
  str_len++;
 
1676
  Lex_input_stream lip(session, vcol_expr_str, str_len);
 
1677
 
 
1678
  /*
 
1679
    Step 2: Setup session for parsing.
 
1680
    1) make Item objects be created in the memory allocated for the Table
 
1681
       object (not TABLE_SHARE)
 
1682
    2) ensure that created Item's are not put on to session->free_list
 
1683
       (which is associated with the parsed statement and hence cleared after
 
1684
       the parsing)
 
1685
    3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
 
1686
       to be parsed as a SQL command.
 
1687
  */
 
1688
  MEM_ROOT **root_ptr, *old_root;
 
1689
  Item *backup_free_list= session->free_list;
 
1690
  root_ptr= current_mem_root_ptr();
 
1691
  old_root= *root_ptr;
 
1692
  *root_ptr= &table->mem_root;
 
1693
  session->free_list= NULL;
 
1694
  session->lex->parse_vcol_expr= true;
 
1695
 
 
1696
  /*
 
1697
    Step 3: Use the parser to build an Item object from.
 
1698
  */
 
1699
  if (parse_sql(session, &lip))
 
1700
  {
 
1701
    goto parse_err;
 
1702
  }
 
1703
  /* From now on use vcol_info generated by the parser. */
 
1704
  field->vcol_info= session->lex->vcol_info;
 
1705
 
 
1706
  /* Validate the Item tree. */
 
1707
  if (fix_fields_vcol_func(session,
 
1708
                           field->vcol_info->expr_item,
 
1709
                           table,
 
1710
                           field->field_name))
 
1711
  {
 
1712
    if (open_mode == OTM_CREATE)
 
1713
    {
 
1714
      /*
 
1715
        During CREATE/ALTER TABLE it is ok to receive errors here.
 
1716
        It is not ok if it happens during the opening of an frm
 
1717
        file as part of a normal query.
 
1718
      */
 
1719
      *error_reported= true;
 
1720
    }
 
1721
    field->vcol_info= NULL;
 
1722
    goto parse_err;
 
1723
  }
 
1724
  field->vcol_info->item_free_list= session->free_list;
 
1725
  session->free_list= backup_free_list;
 
1726
  *root_ptr= old_root;
 
1727
 
 
1728
  return(false);
 
1729
 
 
1730
parse_err:
 
1731
  session->lex->parse_vcol_expr= false;
 
1732
  session->free_items();
 
1733
  *root_ptr= old_root;
 
1734
  session->free_list= backup_free_list;
 
1735
  return(true);
 
1736
}
 
1737
 
 
1738
 
 
1739
/*
 
1740
  Open a table based on a TABLE_SHARE
 
1741
 
 
1742
  SYNOPSIS
 
1743
    open_table_from_share()
 
1744
    session                     Thread handler
 
1745
    share               Table definition
 
1746
    alias               Alias for table
 
1747
    db_stat             open flags (for example HA_OPEN_KEYFILE|
 
1748
                        HA_OPEN_RNDFILE..) can be 0 (example in
 
1749
                        ha_example_table)
 
1750
    prgflag             READ_ALL etc..
 
1751
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
 
1752
    outparam            result table
 
1753
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
 
1754
                        if OTM_CREATE some errors are ignore
 
1755
                        if OTM_ALTER HA_OPEN is not called
 
1756
 
 
1757
  RETURN VALUES
 
1758
   0    ok
 
1759
   1    Error (see open_table_error)
 
1760
   2    Error (see open_table_error)
 
1761
   3    Wrong data in .frm file
 
1762
   4    Error (see open_table_error)
 
1763
   5    Error (see open_table_error: charset unavailable)
 
1764
   7    Table definition has changed in engine
 
1765
*/
 
1766
 
 
1767
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
 
1768
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
 
1769
                          Table *outparam, open_table_mode open_mode)
 
1770
{
 
1771
  int error;
 
1772
  uint32_t records, i, bitmap_size;
 
1773
  bool error_reported= false;
 
1774
  unsigned char *record, *bitmaps;
 
1775
  Field **field_ptr, **vfield_ptr;
 
1776
 
 
1777
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1778
  assert(session->lex->is_lex_started);
 
1779
 
 
1780
  error= 1;
 
1781
  memset(outparam, 0, sizeof(*outparam));
 
1782
  outparam->in_use= session;
 
1783
  outparam->s= share;
 
1784
  outparam->db_stat= db_stat;
 
1785
  outparam->write_row_record= NULL;
 
1786
 
 
1787
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
1788
 
 
1789
  if (!(outparam->alias= strdup(alias)))
 
1790
    goto err;
 
1791
  outparam->quick_keys.init();
 
1792
  outparam->covering_keys.init();
 
1793
  outparam->keys_in_use_for_query.init();
 
1794
 
 
1795
  /* Allocate handler */
 
1796
  outparam->file= 0;
 
1797
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
 
1798
  {
 
1799
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
 
1800
                                          share->db_type())))
 
1801
      goto err;
 
1802
  }
 
1803
  else
 
1804
  {
 
1805
    assert(!db_stat);
 
1806
  }
 
1807
 
 
1808
  error= 4;
 
1809
  outparam->reginfo.lock_type= TL_UNLOCK;
 
1810
  outparam->current_lock= F_UNLCK;
 
1811
  records=0;
 
1812
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
 
1813
    records=1;
 
1814
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
1815
    records++;
 
1816
 
 
1817
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
 
1818
                                   share->rec_buff_length * records)))
 
1819
    goto err;                                   /* purecov: inspected */
 
1820
 
 
1821
  if (records == 0)
 
1822
  {
 
1823
    /* We are probably in hard repair, and the buffers should not be used */
 
1824
    outparam->record[0]= outparam->record[1]= share->default_values;
 
1825
  }
 
1826
  else
 
1827
  {
 
1828
    outparam->record[0]= record;
 
1829
    if (records > 1)
 
1830
      outparam->record[1]= record+ share->rec_buff_length;
 
1831
    else
 
1832
      outparam->record[1]= outparam->record[0];   // Safety
 
1833
  }
 
1834
 
 
1835
#ifdef HAVE_purify
 
1836
  /*
 
1837
    We need this because when we read var-length rows, we are not updating
 
1838
    bytes after end of varchar
 
1839
  */
 
1840
  if (records > 1)
 
1841
  {
 
1842
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
 
1843
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
 
1844
    if (records > 2)
 
1845
      memcpy(outparam->record[1], share->default_values,
 
1846
             share->rec_buff_length);
 
1847
  }
 
1848
#endif
 
1849
 
 
1850
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1851
                                          (uint32_t) ((share->fields+1)*
 
1852
                                                  sizeof(Field*)))))
 
1853
    goto err;                                   /* purecov: inspected */
 
1854
 
 
1855
  outparam->field= field_ptr;
 
1856
 
 
1857
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
 
1858
 
 
1859
  outparam->null_flags= (unsigned char*) record+1;
 
1860
 
 
1861
  /* Setup copy of fields from share, but use the right alias and record */
 
1862
  for (i=0 ; i < share->fields; i++, field_ptr++)
 
1863
  {
 
1864
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
 
1865
      goto err;
 
1866
  }
 
1867
  (*field_ptr)= 0;                              // End marker
 
1868
 
 
1869
  if (share->found_next_number_field)
 
1870
    outparam->found_next_number_field=
 
1871
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
 
1872
  if (share->timestamp_field)
 
1873
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
 
1874
 
 
1875
 
 
1876
  /* Fix key->name and key_part->field */
 
1877
  if (share->key_parts)
 
1878
  {
 
1879
    KEY *key_info, *key_info_end;
 
1880
    KEY_PART_INFO *key_part;
 
1881
    uint32_t n_length;
 
1882
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
 
1883
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
 
1884
      goto err;
 
1885
    outparam->key_info= key_info;
 
1886
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
 
1887
 
 
1888
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
 
1889
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
 
1890
                                                   share->key_parts));
 
1891
 
 
1892
    for (key_info_end= key_info + share->keys ;
 
1893
         key_info < key_info_end ;
 
1894
         key_info++)
 
1895
    {
 
1896
      KEY_PART_INFO *key_part_end;
 
1897
 
 
1898
      key_info->table= outparam;
 
1899
      key_info->key_part= key_part;
 
1900
 
 
1901
      for (key_part_end= key_part+ key_info->key_parts ;
 
1902
           key_part < key_part_end ;
 
1903
           key_part++)
 
1904
      {
 
1905
        Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
 
1906
 
 
1907
        if (field->key_length() != key_part->length &&
 
1908
            !(field->flags & BLOB_FLAG))
 
1909
        {
 
1910
          /*
 
1911
            We are using only a prefix of the column as a key:
 
1912
            Create a new field for the key part that matches the index
 
1913
          */
 
1914
          field= key_part->field=field->new_field(&outparam->mem_root,
 
1915
                                                  outparam, 0);
 
1916
          field->field_length= key_part->length;
 
1917
        }
 
1918
      }
 
1919
    }
 
1920
  }
 
1921
 
 
1922
  /*
 
1923
    Process virtual columns, if any.
 
1924
  */
 
1925
  if (not (vfield_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1926
                                              (uint32_t) ((share->vfields+1)*
 
1927
                                                      sizeof(Field*)))))
 
1928
    goto err;
 
1929
 
 
1930
  outparam->vfield= vfield_ptr;
 
1931
 
 
1932
  for (field_ptr= outparam->field; *field_ptr; field_ptr++)
 
1933
  {
 
1934
    if ((*field_ptr)->vcol_info)
 
1935
    {
 
1936
      if (unpack_vcol_info_from_frm(session,
 
1937
                                    outparam,
 
1938
                                    *field_ptr,
 
1939
                                    &(*field_ptr)->vcol_info->expr_str,
 
1940
                                    open_mode,
 
1941
                                    &error_reported))
 
1942
      {
 
1943
        error= 4; // in case no error is reported
 
1944
        goto err;
 
1945
      }
 
1946
      *(vfield_ptr++)= *field_ptr;
 
1947
    }
 
1948
  }
 
1949
  *vfield_ptr= NULL;                              // End marker
 
1950
  /* Check virtual columns against table's storage engine. */
 
1951
  if ((share->vfields && outparam->file) &&
 
1952
        (not outparam->file->check_if_supported_virtual_columns()))
 
1953
  {
 
1954
    my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN,
 
1955
             MYF(0),
 
1956
             "Specified storage engine");
 
1957
    error_reported= true;
 
1958
    goto err;
 
1959
  }
 
1960
 
 
1961
  /* Allocate bitmaps */
 
1962
 
 
1963
  bitmap_size= share->column_bitmap_size;
 
1964
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
 
1965
    goto err;
 
1966
  bitmap_init(&outparam->def_read_set,
 
1967
              (my_bitmap_map*) bitmaps, share->fields, false);
 
1968
  bitmap_init(&outparam->def_write_set,
 
1969
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
 
1970
  bitmap_init(&outparam->tmp_set,
 
1971
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
 
1972
  outparam->default_column_bitmaps();
 
1973
 
 
1974
  /* The table struct is now initialized;  Open the table */
 
1975
  error= 2;
 
1976
  if (db_stat && open_mode != OTM_ALTER)
 
1977
  {
 
1978
    int ha_err;
 
1979
    if ((ha_err= (outparam->file->
 
1980
                  ha_open(outparam, share->normalized_path.str,
 
1981
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
 
1982
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
 
1983
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
 
1984
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
 
1985
                          HA_OPEN_ABORT_IF_LOCKED :
 
1986
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
 
1987
    {
 
1988
      /* Set a flag if the table is crashed and it can be auto. repaired */
 
1989
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
 
1990
                       outparam->file->auto_repair() &&
 
1991
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
 
1992
 
 
1993
      switch (ha_err)
 
1994
      {
 
1995
        case HA_ERR_NO_SUCH_TABLE:
 
1996
          /*
 
1997
            The table did not exists in storage engine, use same error message
 
1998
            as if the .frm file didn't exist
 
1999
          */
 
2000
          error= 1;
 
2001
          my_errno= ENOENT;
 
2002
          break;
 
2003
        case EMFILE:
 
2004
          /*
 
2005
            Too many files opened, use same error message as if the .frm
 
2006
            file can't open
 
2007
           */
 
2008
          error= 1;
 
2009
          my_errno= EMFILE;
 
2010
          break;
 
2011
        default:
 
2012
          outparam->file->print_error(ha_err, MYF(0));
 
2013
          error_reported= true;
 
2014
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
 
2015
            error= 7;
 
2016
          break;
 
2017
      }
 
2018
      goto err;                                 /* purecov: inspected */
 
2019
    }
 
2020
  }
 
2021
 
 
2022
#if defined(HAVE_purify)
 
2023
  memset(bitmaps, 0, bitmap_size*3);
 
2024
#endif
 
2025
 
 
2026
  outparam->no_replicate= outparam->file;
 
2027
  session->status_var.opened_tables++;
 
2028
 
 
2029
  return (0);
 
2030
 
 
2031
 err:
 
2032
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
 
2033
    open_table_error(share, error, my_errno, 0);
 
2034
  delete outparam->file;
 
2035
  outparam->file= 0;                            // For easier error checking
 
2036
  outparam->db_stat=0;
 
2037
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
 
2038
  free((char*) outparam->alias);
 
2039
  return (error);
 
2040
}
 
2041
 
 
2042
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
 
2043
uint32_t  Table::tmpkeyval()
 
2044
{
 
2045
  return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
 
2046
}
 
2047
 
 
2048
/*
 
2049
  Free information allocated by openfrm
 
2050
 
 
2051
  SYNOPSIS
 
2052
    closefrm()
 
2053
    table               Table object to free
 
2054
    free_share          Is 1 if we also want to free table_share
 
2055
*/
 
2056
 
 
2057
int Table::closefrm(bool free_share)
 
2058
{
 
2059
  int error=0;
81
2060
 
82
2061
  if (db_stat)
83
 
    error= cursor->close();
84
 
  _alias.clear();
 
2062
    error= file->close();
 
2063
  free((char*) alias);
 
2064
  alias= NULL;
85
2065
  if (field)
86
2066
  {
87
2067
    for (Field **ptr=field ; *ptr ; ptr++)
88
 
    {
89
2068
      delete *ptr;
90
 
    }
91
2069
    field= 0;
92
2070
  }
93
 
  delete cursor;
94
 
  cursor= 0;                            /* For easier errorchecking */
95
 
 
 
2071
  delete file;
 
2072
  file= 0;                              /* For easier errorchecking */
96
2073
  if (free_share)
97
2074
  {
98
 
    release();
 
2075
    if (s->tmp_table == NO_TMP_TABLE)
 
2076
      release_table_share(s, RELEASE_NORMAL);
 
2077
    else
 
2078
      free_table_share(s);
99
2079
  }
 
2080
  free_root(&mem_root, MYF(0));
100
2081
 
101
2082
  return error;
102
2083
}
103
2084
 
104
 
Table::~Table()
105
 
{
106
 
  mem_root.free_root(MYF(0));
107
 
}
108
 
 
109
 
 
110
 
void Table::resetTable(Session *session,
111
 
                       TableShare *share,
112
 
                       uint32_t db_stat_arg)
113
 
{
114
 
  setShare(share);
115
 
  field= NULL;
116
 
 
117
 
  cursor= NULL;
118
 
  next= NULL;
119
 
  prev= NULL;
120
 
 
121
 
  read_set= NULL;
122
 
  write_set= NULL;
123
 
 
124
 
  tablenr= 0;
125
 
  db_stat= db_stat_arg;
126
 
 
127
 
  in_use= session;
128
 
  record[0]= (unsigned char *) NULL;
129
 
  record[1]= (unsigned char *) NULL;
130
 
 
131
 
  insert_values.clear();
132
 
  key_info= NULL;
133
 
  next_number_field= NULL;
134
 
  found_next_number_field= NULL;
135
 
  timestamp_field= NULL;
136
 
 
137
 
  pos_in_table_list= NULL;
138
 
  group= NULL;
139
 
  _alias.clear();
140
 
  null_flags= NULL;
141
 
 
142
 
  lock_position= 0;
143
 
  lock_data_start= 0;
144
 
  lock_count= 0;
145
 
  used_fields= 0;
146
 
  status= 0;
147
 
  derived_select_number= 0;
148
 
  current_lock= F_UNLCK;
149
 
  copy_blobs= false;
150
 
 
151
 
  maybe_null= false;
152
 
 
153
 
  null_row= false;
154
 
 
155
 
  force_index= false;
156
 
  distinct= false;
157
 
  const_table= false;
158
 
  no_rows= false;
159
 
  key_read= false;
160
 
  no_keyread= false;
161
 
 
162
 
  open_placeholder= false;
163
 
  locked_by_name= false;
164
 
  no_cache= false;
165
 
 
166
 
  auto_increment_field_not_null= false;
167
 
  alias_name_used= false;
168
 
 
169
 
  query_id= 0;
170
 
  quick_condition_rows= 0;
171
 
 
172
 
  timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
173
 
  map= 0;
174
 
 
175
 
  reginfo.reset();
176
 
 
177
 
  covering_keys.reset();
178
 
 
179
 
  quick_keys.reset();
180
 
  merge_keys.reset();
181
 
 
182
 
  keys_in_use_for_query.reset();
183
 
  keys_in_use_for_group_by.reset();
184
 
  keys_in_use_for_order_by.reset();
185
 
 
186
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
187
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
188
 
 
189
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
190
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
191
 
 
192
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
193
 
}
194
 
 
195
 
 
196
2085
 
197
2086
/* Deallocate temporary blob storage */
198
2087
 
202
2091
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
203
2092
       ptr != end ;
204
2093
       ptr++)
205
 
  {
206
 
    ((Field_blob*) table->getField(*ptr))->free();
207
 
  }
208
 
}
209
 
 
210
 
 
211
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
212
 
{
213
 
  TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
 
2094
    ((Field_blob*) table->field[*ptr])->free();
 
2095
}
 
2096
 
 
2097
 
 
2098
        /* Find where a form starts */
 
2099
        /* if formname is NULL then only formnames is read */
 
2100
 
 
2101
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
 
2102
{
 
2103
  uint32_t a_length,names,length;
 
2104
  unsigned char *pos,*buf;
 
2105
  ulong ret_value=0;
 
2106
 
 
2107
  names=uint2korr(head+8);
 
2108
  a_length=(names+2)*sizeof(char *);            /* Room for two extra */
 
2109
 
 
2110
  if (!save_names)
 
2111
    a_length=0;
 
2112
  else
 
2113
    save_names->type_names=0;                   /* Clear if error */
 
2114
 
 
2115
  if (names)
 
2116
  {
 
2117
    length=uint2korr(head+4);
 
2118
    lseek(file,64,SEEK_SET);
 
2119
    if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
 
2120
        my_read(file, buf+a_length, (size_t) (length+names*4),
 
2121
                MYF(MY_NABP)))
 
2122
    {                                           /* purecov: inspected */
 
2123
      if (buf)
 
2124
        free(buf);
 
2125
      return(0L);                               /* purecov: inspected */
 
2126
    }
 
2127
    pos= buf+a_length+length;
 
2128
    ret_value=uint4korr(pos);
 
2129
  }
 
2130
  if (! save_names)
 
2131
  {
 
2132
    if (names)
 
2133
      free((unsigned char*) buf);
 
2134
  }
 
2135
  else if (!names)
 
2136
    memset(save_names, 0, sizeof(save_names));
 
2137
  else
 
2138
  {
 
2139
    char *str;
 
2140
    str=(char *) (buf+a_length);
 
2141
    fix_type_pointers((const char ***) &buf,save_names,1,&str);
 
2142
  }
 
2143
  return(ret_value);
 
2144
}
 
2145
 
 
2146
 
 
2147
/*
 
2148
  Read string from a file with malloc
 
2149
 
 
2150
  NOTES:
 
2151
    We add an \0 at end of the read string to make reading of C strings easier
 
2152
*/
 
2153
 
 
2154
int read_string(File file, unsigned char**to, size_t length)
 
2155
{
 
2156
 
 
2157
  if (*to)
 
2158
    free(*to);
 
2159
  if (!(*to= (unsigned char*) malloc(length+1)) ||
 
2160
      my_read(file, *to, length,MYF(MY_NABP)))
 
2161
  {
 
2162
    if (*to)
 
2163
      free(*to);
 
2164
    *to= NULL;
 
2165
    return(1);                           /* purecov: inspected */
 
2166
  }
 
2167
  *((char*) *to+length)= '\0';
 
2168
  return (0);
 
2169
} /* read_string */
 
2170
 
 
2171
 
 
2172
        /* Add a new form to a form file */
 
2173
 
 
2174
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
 
2175
                     const char *newname)
 
2176
{
 
2177
  uint32_t i,bufflength,maxlength,n_length,length,names;
 
2178
  off_t endpos,newpos;
 
2179
  unsigned char buff[IO_SIZE];
 
2180
  unsigned char *pos;
 
2181
 
 
2182
  length=(uint32_t) strlen(newname)+1;
 
2183
  n_length=uint2korr(fileinfo+4);
 
2184
  maxlength=uint2korr(fileinfo+6);
 
2185
  names=uint2korr(fileinfo+8);
 
2186
  newpos=uint4korr(fileinfo+10);
 
2187
 
 
2188
  if (64+length+n_length+(names+1)*4 > maxlength)
 
2189
  {                                             /* Expand file */
 
2190
    newpos+=IO_SIZE;
 
2191
    int4store(fileinfo+10,newpos);
 
2192
    endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
 
2193
    bufflength= (uint32_t) (endpos & (IO_SIZE-1));      /* IO_SIZE is a power of 2 */
 
2194
 
 
2195
    while (endpos > maxlength)
 
2196
    {
 
2197
      lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
 
2198
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
 
2199
        return(0L);
 
2200
      lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
 
2201
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
 
2202
        return(0);
 
2203
      endpos-=bufflength; bufflength=IO_SIZE;
 
2204
    }
 
2205
    memset(buff, 0, IO_SIZE);                   /* Null new block */
 
2206
    lseek(file,(ulong) maxlength,SEEK_SET);
 
2207
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
 
2208
      return(0L);
 
2209
    maxlength+=IO_SIZE;                         /* Fix old ref */
 
2210
    int2store(fileinfo+6,maxlength);
 
2211
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
 
2212
         pos+=4)
 
2213
    {
 
2214
      endpos=uint4korr(pos)+IO_SIZE;
 
2215
      int4store(pos,endpos);
 
2216
    }
 
2217
  }
 
2218
 
 
2219
  if (n_length == 1 )
 
2220
  {                                             /* First name */
 
2221
    length++;
 
2222
    sprintf((char*)buff,"/%s/",newname);
 
2223
  }
 
2224
  else
 
2225
    sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
 
2226
  lseek(file, 63 + n_length,SEEK_SET);
 
2227
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
 
2228
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
 
2229
                         names*4, MYF(MY_NABP+MY_WME))) ||
 
2230
      my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
 
2231
    return(0L); /* purecov: inspected */
 
2232
 
 
2233
  int2store(fileinfo+8,names+1);
 
2234
  int2store(fileinfo+4,n_length+length);
 
2235
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
 
2236
  return(newpos);
 
2237
} /* make_new_entry */
 
2238
 
 
2239
 
 
2240
        /* error message when opening a form file */
 
2241
 
 
2242
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
 
2243
{
 
2244
  int err_no;
 
2245
  char buff[FN_REFLEN];
 
2246
  myf errortype= ME_ERROR+ME_WAITTANG;
 
2247
 
 
2248
  switch (error) {
 
2249
  case 7:
 
2250
  case 1:
 
2251
    if (db_errno == ENOENT)
 
2252
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
 
2253
    else
 
2254
    {
 
2255
      sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
 
2256
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
 
2257
               errortype, buff, db_errno);
 
2258
    }
 
2259
    break;
 
2260
  case 2:
 
2261
  {
 
2262
    handler *file= 0;
 
2263
    const char *datext= "";
 
2264
 
 
2265
    if (share->db_type() != NULL)
 
2266
    {
 
2267
      if ((file= get_new_handler(share, current_session->mem_root,
 
2268
                                 share->db_type())))
 
2269
      {
 
2270
        if (!(datext= *file->bas_ext()))
 
2271
          datext= "";
 
2272
      }
 
2273
    }
 
2274
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
 
2275
      ER_FILE_USED : ER_CANT_OPEN_FILE;
 
2276
    sprintf(buff,"%s%s", share->normalized_path.str,datext);
 
2277
    my_error(err_no,errortype, buff, db_errno);
 
2278
    delete file;
 
2279
    break;
 
2280
  }
 
2281
  case 5:
 
2282
  {
 
2283
    const char *csname= get_charset_name((uint32_t) errarg);
 
2284
    char tmp[10];
 
2285
    if (!csname || csname[0] =='?')
 
2286
    {
 
2287
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
 
2288
      csname= tmp;
 
2289
    }
 
2290
    my_printf_error(ER_UNKNOWN_COLLATION,
 
2291
                    _("Unknown collation '%s' in table '%-.64s' definition"),
 
2292
                    MYF(0), csname, share->table_name.str);
 
2293
    break;
 
2294
  }
 
2295
  case 6:
 
2296
    sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
 
2297
    my_printf_error(ER_NOT_FORM_FILE,
 
2298
                    _("Table '%-.64s' was created with a different version "
 
2299
                    "of Drizzle and cannot be read"),
 
2300
                    MYF(0), buff);
 
2301
    break;
 
2302
  case 8:
 
2303
    break;
 
2304
  default:                              /* Better wrong error than none */
 
2305
  case 4:
 
2306
    sprintf(buff,"%s%s",share->normalized_path.str,reg_ext);
 
2307
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
 
2308
    break;
 
2309
  }
 
2310
  return;
 
2311
} /* open_table_error */
 
2312
 
 
2313
 
 
2314
        /*
 
2315
        ** fix a str_type to a array type
 
2316
        ** typeparts separated with some char. differents types are separated
 
2317
        ** with a '\0'
 
2318
        */
 
2319
 
 
2320
static void
 
2321
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
 
2322
                  char **names)
 
2323
{
 
2324
  char *type_name, *ptr;
 
2325
  char chr;
 
2326
 
 
2327
  ptr= *names;
 
2328
  while (types--)
 
2329
  {
 
2330
    point_to_type->name=0;
 
2331
    point_to_type->type_names= *array;
 
2332
 
 
2333
    if ((chr= *ptr))                    /* Test if empty type */
 
2334
    {
 
2335
      while ((type_name=strchr(ptr+1,chr)) != NULL)
 
2336
      {
 
2337
        *((*array)++) = ptr+1;
 
2338
        *type_name= '\0';               /* End string */
 
2339
        ptr=type_name;
 
2340
      }
 
2341
      ptr+=2;                           /* Skip end mark and last 0 */
 
2342
    }
 
2343
    else
 
2344
      ptr++;
 
2345
    point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
 
2346
    point_to_type++;
 
2347
    *((*array)++)= NULL;                /* End of type */
 
2348
  }
 
2349
  *names=ptr;                           /* Update end */
 
2350
  return;
 
2351
} /* fix_type_pointers */
 
2352
 
 
2353
 
 
2354
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
 
2355
{
 
2356
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
214
2357
  if (!result)
215
2358
    return 0;
216
 
  result->count= strings.elements;
217
 
  result->name= "";
 
2359
  result->count=strings.elements;
 
2360
  result->name="";
218
2361
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
219
 
  
220
 
  if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
 
2362
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
221
2363
    return 0;
222
 
    
223
2364
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
224
 
 
225
2365
  List_iterator<String> it(strings);
226
2366
  String *tmp;
227
 
  for (uint32_t i= 0; (tmp= it++); i++)
 
2367
  for (uint32_t i=0; (tmp=it++) ; i++)
228
2368
  {
229
2369
    result->type_names[i]= tmp->ptr();
230
2370
    result->type_lengths[i]= tmp->length();
231
2371
  }
232
 
 
233
 
  result->type_names[result->count]= 0;   // End marker
 
2372
  result->type_names[result->count]= 0;         // End marker
234
2373
  result->type_lengths[result->count]= 0;
235
 
 
236
2374
  return result;
237
2375
}
238
2376
 
247
2385
  return (nr);
248
2386
} /* set_zone */
249
2387
 
 
2388
        /* Adjust number to next larger disk buffer */
 
2389
 
 
2390
ulong next_io_size(register ulong pos)
 
2391
{
 
2392
  register ulong offset;
 
2393
  if ((offset= pos & (IO_SIZE-1)))
 
2394
    return pos-offset+IO_SIZE;
 
2395
  return pos;
 
2396
} /* next_io_size */
 
2397
 
250
2398
 
251
2399
/*
252
2400
  Store an SQL quoted string.
269
2417
 
270
2418
  for (; pos != end ; pos++)
271
2419
  {
 
2420
#if defined(USE_MB)
272
2421
    uint32_t mblen;
273
2422
    if (use_mb(default_charset_info) &&
274
2423
        (mblen= my_ismbchar(default_charset_info, pos, end)))
275
2424
    {
276
2425
      res->append(pos, mblen);
277
 
      pos+= mblen - 1;
 
2426
      pos+= mblen;
278
2427
      if (pos >= end)
279
2428
        break;
280
2429
      continue;
281
2430
    }
 
2431
#endif
282
2432
 
283
2433
    switch (*pos) {
284
2434
    case 0:                             /* Must be escaped for 'mysql' */
310
2460
}
311
2461
 
312
2462
 
 
2463
        /* Create a .frm file */
 
2464
 
 
2465
File create_frm(Session *session, const char *name, const char *db,
 
2466
                const char *table, uint32_t reclength, unsigned char *fileinfo,
 
2467
                HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
 
2468
{
 
2469
  register File file;
 
2470
  ulong length;
 
2471
  unsigned char fill[IO_SIZE];
 
2472
  int create_flags= O_RDWR | O_TRUNC;
 
2473
  ulong key_comment_total_bytes= 0;
 
2474
  uint32_t i;
 
2475
 
 
2476
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
 
2477
    create_flags|= O_EXCL;
 
2478
 
 
2479
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
 
2480
  if (create_info->max_rows > UINT32_MAX)
 
2481
    create_info->max_rows= UINT32_MAX;
 
2482
  if (create_info->min_rows > UINT32_MAX)
 
2483
    create_info->min_rows= UINT32_MAX;
 
2484
 
 
2485
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
 
2486
  {
 
2487
    uint32_t key_length, tmp_key_length;
 
2488
    uint32_t tmp;
 
2489
    memset(fileinfo, 0, 64);
 
2490
    /* header */
 
2491
    fileinfo[0]=(unsigned char) 254;
 
2492
    fileinfo[1]= 1;
 
2493
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
 
2494
 
 
2495
    fileinfo[3]= (unsigned char) ha_legacy_type(
 
2496
          ha_checktype(session,ha_legacy_type(create_info->db_type),0,0));
 
2497
    fileinfo[4]=1;
 
2498
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
 
2499
    for (i= 0; i < keys; i++)
 
2500
    {
 
2501
      assert(test(key_info[i].flags & HA_USES_COMMENT) ==
 
2502
                 (key_info[i].comment.length > 0));
 
2503
      if (key_info[i].flags & HA_USES_COMMENT)
 
2504
        key_comment_total_bytes += 2 + key_info[i].comment.length;
 
2505
    }
 
2506
    /*
 
2507
      Keep in sync with pack_keys() in unireg.cc
 
2508
      For each key:
 
2509
      8 bytes for the key header
 
2510
      9 bytes for each key-part (MAX_REF_PARTS)
 
2511
      NAME_LEN bytes for the name
 
2512
      1 byte for the NAMES_SEP_CHAR (before the name)
 
2513
      For all keys:
 
2514
      6 bytes for the header
 
2515
      1 byte for the NAMES_SEP_CHAR (after the last name)
 
2516
      9 extra bytes (padding for safety? alignment?)
 
2517
      comments
 
2518
    */
 
2519
    key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
 
2520
                 key_comment_total_bytes);
 
2521
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
 
2522
                                  create_info->extra_size));
 
2523
    int4store(fileinfo+10,length);
 
2524
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
 
2525
    int2store(fileinfo+14,tmp_key_length);
 
2526
    int2store(fileinfo+16,reclength);
 
2527
    int4store(fileinfo+18,create_info->max_rows);
 
2528
    int4store(fileinfo+22,create_info->min_rows);
 
2529
    /* fileinfo[26] is set in mysql_create_frm() */
 
2530
    fileinfo[27]=2;                             // Use long pack-fields
 
2531
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
 
2532
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
 
2533
    int2store(fileinfo+30,create_info->table_options);
 
2534
    fileinfo[32]=0;                             // No filename anymore
 
2535
    fileinfo[33]=5;                             // Mark for 5.0 frm file
 
2536
    int4store(fileinfo+34,create_info->avg_row_length);
 
2537
    fileinfo[38]= (create_info->default_table_charset ?
 
2538
                   create_info->default_table_charset->number : 0);
 
2539
    fileinfo[39]= (unsigned char) create_info->page_checksum;
 
2540
    fileinfo[40]= (unsigned char) create_info->row_type;
 
2541
    /* Next few bytes were for RAID support */
 
2542
    fileinfo[41]= 0;
 
2543
    fileinfo[42]= 0;
 
2544
    int4store(fileinfo+43,create_info->block_size);
 
2545
 
 
2546
    fileinfo[44]= 0;
 
2547
    fileinfo[45]= 0;
 
2548
    fileinfo[46]= 0;
 
2549
    int4store(fileinfo+47, key_length);
 
2550
    tmp= DRIZZLE_VERSION_ID;          // Store to avoid warning from int4store
 
2551
    int4store(fileinfo+51, tmp);
 
2552
    int4store(fileinfo+55, create_info->extra_size);
 
2553
    /*
 
2554
      59-60 is reserved for extra_rec_buf_length (always 0),
 
2555
      61 for default_part_db_type
 
2556
    */
 
2557
    int2store(fileinfo+62, create_info->key_block_size);
 
2558
    memset(fill, 0, IO_SIZE);
 
2559
    for (; length > IO_SIZE ; length-= IO_SIZE)
 
2560
    {
 
2561
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
 
2562
      {
 
2563
        my_close(file,MYF(0));
 
2564
        my_delete(name,MYF(0));
 
2565
        return(-1);
 
2566
      }
 
2567
    }
 
2568
  }
 
2569
  else
 
2570
  {
 
2571
    if (my_errno == ENOENT)
 
2572
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
2573
    else
 
2574
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
 
2575
  }
 
2576
  return (file);
 
2577
} /* create_frm */
 
2578
 
 
2579
/*
 
2580
  Set up column usage bitmaps for a temporary table
 
2581
 
 
2582
  IMPLEMENTATION
 
2583
    For temporary tables, we need one bitmap with all columns set and
 
2584
    a tmp_set bitmap to be used by things like filesort.
 
2585
*/
 
2586
 
 
2587
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
 
2588
{
 
2589
  uint32_t field_count= s->fields;
 
2590
 
 
2591
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count, false);
 
2592
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count, false);
 
2593
 
 
2594
  /* write_set and all_set are copies of read_set */
 
2595
  def_write_set= def_read_set;
 
2596
  s->all_set= def_read_set;
 
2597
  bitmap_set_all(&this->s->all_set);
 
2598
  default_column_bitmaps();
 
2599
}
 
2600
 
 
2601
 
 
2602
 
 
2603
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
 
2604
{
 
2605
  create_info->max_rows= s->max_rows;
 
2606
  create_info->min_rows= s->min_rows;
 
2607
  create_info->table_options= s->db_create_options;
 
2608
  create_info->avg_row_length= s->avg_row_length;
 
2609
  create_info->block_size= s->block_size;
 
2610
  create_info->row_type= s->row_type;
 
2611
  create_info->default_table_charset= s->table_charset;
 
2612
  create_info->table_charset= 0;
 
2613
  create_info->comment= s->comment;
 
2614
 
 
2615
  return;
 
2616
}
 
2617
 
313
2618
int rename_file_ext(const char * from,const char * to,const char * ext)
314
2619
{
315
2620
  string from_s, to_s;
318
2623
  from_s.append(ext);
319
2624
  to_s.append(to);
320
2625
  to_s.append(ext);
321
 
  return (internal::my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
2626
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
2627
}
 
2628
 
 
2629
 
 
2630
/*
 
2631
  Allocate string field in MEM_ROOT and return it as String
 
2632
 
 
2633
  SYNOPSIS
 
2634
    get_field()
 
2635
    mem         MEM_ROOT for allocating
 
2636
    field       Field for retrieving of string
 
2637
    res         result String
 
2638
 
 
2639
  RETURN VALUES
 
2640
    1   string is empty
 
2641
    0   all ok
 
2642
*/
 
2643
 
 
2644
bool get_field(MEM_ROOT *mem, Field *field, String *res)
 
2645
{
 
2646
  char buff[MAX_FIELD_WIDTH], *to;
 
2647
  String str(buff,sizeof(buff),&my_charset_bin);
 
2648
  uint32_t length;
 
2649
 
 
2650
  field->val_str(&str);
 
2651
  if (!(length= str.length()))
 
2652
  {
 
2653
    res->length(0);
 
2654
    return 1;
 
2655
  }
 
2656
  if (!(to= strmake_root(mem, str.ptr(), length)))
 
2657
    length= 0;                                  // Safety fix
 
2658
  res->set(to, length, ((Field_str*)field)->charset());
 
2659
  return 0;
 
2660
}
 
2661
 
 
2662
 
 
2663
/*
 
2664
  Allocate string field in MEM_ROOT and return it as NULL-terminated string
 
2665
 
 
2666
  SYNOPSIS
 
2667
    get_field()
 
2668
    mem         MEM_ROOT for allocating
 
2669
    field       Field for retrieving of string
 
2670
 
 
2671
  RETURN VALUES
 
2672
    NULL  string is empty
 
2673
    #      pointer to NULL-terminated string value of field
 
2674
*/
 
2675
 
 
2676
char *get_field(MEM_ROOT *mem, Field *field)
 
2677
{
 
2678
  char buff[MAX_FIELD_WIDTH], *to;
 
2679
  String str(buff,sizeof(buff),&my_charset_bin);
 
2680
  uint32_t length;
 
2681
 
 
2682
  field->val_str(&str);
 
2683
  length= str.length();
 
2684
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
 
2685
    return NULL;
 
2686
  memcpy(to,str.ptr(),(uint32_t) length);
 
2687
  to[length]=0;
 
2688
  return to;
 
2689
}
 
2690
 
 
2691
/*
 
2692
  DESCRIPTION
 
2693
    given a buffer with a key value, and a map of keyparts
 
2694
    that are present in this value, returns the length of the value
 
2695
*/
 
2696
uint32_t calculate_key_len(Table *table, uint32_t key,
 
2697
                       const unsigned char *,
 
2698
                       key_part_map keypart_map)
 
2699
{
 
2700
  /* works only with key prefixes */
 
2701
  assert(((keypart_map + 1) & keypart_map) == 0);
 
2702
 
 
2703
  KEY *key_info= table->s->key_info+key;
 
2704
  KEY_PART_INFO *key_part= key_info->key_part;
 
2705
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
 
2706
  uint32_t length= 0;
 
2707
 
 
2708
  while (key_part < end_key_part && keypart_map)
 
2709
  {
 
2710
    length+= key_part->store_length;
 
2711
    keypart_map >>= 1;
 
2712
    key_part++;
 
2713
  }
 
2714
  return length;
322
2715
}
323
2716
 
324
2717
/*
328
2721
    check_db_name()
329
2722
    org_name            Name of database and length
330
2723
 
 
2724
  NOTES
 
2725
    If lower_case_table_names is set then database is converted to lower case
 
2726
 
331
2727
  RETURN
332
 
    false error
333
 
    true ok
 
2728
    0   ok
 
2729
    1   error
334
2730
*/
335
2731
 
336
 
bool check_db_name(Session *session, SchemaIdentifier &schema_identifier)
 
2732
bool check_db_name(LEX_STRING *org_name)
337
2733
{
338
 
  if (not plugin::Authorization::isAuthorized(session->getSecurityContext(), schema_identifier))
339
 
  {
340
 
    return false;
341
 
  }
342
 
 
343
 
  return schema_identifier.isValid();
 
2734
  char *name= org_name->str;
 
2735
  uint32_t name_length= org_name->length;
 
2736
 
 
2737
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
 
2738
    return 1;
 
2739
 
 
2740
  if (lower_case_table_names && name != any_db)
 
2741
    my_casedn_str(files_charset_info, name);
 
2742
 
 
2743
  return check_identifier_name(org_name);
344
2744
}
345
2745
 
 
2746
 
346
2747
/*
347
2748
  Allow anything as a table name, as long as it doesn't contain an
348
2749
  ' ' at the end
349
2750
  returns 1 on error
350
2751
*/
 
2752
 
 
2753
 
351
2754
bool check_table_name(const char *name, uint32_t length)
352
2755
{
353
2756
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
371
2774
 
372
2775
  while (*name)
373
2776
  {
 
2777
#if defined(USE_MB) && defined(USE_MB_IDENT)
374
2778
    last_char_is_space= my_isspace(system_charset_info, *name);
375
2779
    if (use_mb(system_charset_info))
376
2780
    {
385
2789
        continue;
386
2790
      }
387
2791
    }
 
2792
#else
 
2793
    last_char_is_space= *name==' ';
 
2794
#endif
388
2795
    /*
389
2796
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
390
2797
      It is defined as 0xFF, which is a not valid byte in utf8.
400
2807
}
401
2808
 
402
2809
 
 
2810
/**
 
2811
  Checks whether a table is intact. Should be done *just* after the table has
 
2812
  been opened.
 
2813
 
 
2814
  @param[in] table             The table to check
 
2815
  @param[in] table_f_count     Expected number of columns in the table
 
2816
  @param[in] table_def         Expected structure of the table (column name
 
2817
                               and type)
 
2818
 
 
2819
  @retval  false  OK
 
2820
  @retval  TRUE   There was an error. An error message is output
 
2821
                  to the error log.  We do not push an error
 
2822
                  message into the error stack because this
 
2823
                  function is currently only called at start up,
 
2824
                  and such errors never reach the user.
 
2825
*/
 
2826
 
 
2827
bool
 
2828
Table::table_check_intact(const uint32_t table_f_count,
 
2829
                          const TABLE_FIELD_W_TYPE *table_def)
 
2830
{
 
2831
  uint32_t i;
 
2832
  bool error= false;
 
2833
  bool fields_diff_count;
 
2834
 
 
2835
  fields_diff_count= (s->fields != table_f_count);
 
2836
  if (fields_diff_count)
 
2837
  {
 
2838
 
 
2839
    /* previous MySQL version */
 
2840
    if (DRIZZLE_VERSION_ID > s->mysql_version)
 
2841
    {
 
2842
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
 
2843
                      alias, table_f_count, s->fields,
 
2844
                      s->mysql_version, DRIZZLE_VERSION_ID);
 
2845
      return(true);
 
2846
    }
 
2847
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
 
2848
    {
 
2849
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
 
2850
                      table_f_count, s->fields);
 
2851
      return(true);
 
2852
    }
 
2853
    /*
 
2854
      Something has definitely changed, but we're running an older
 
2855
      version of MySQL with new system tables.
 
2856
      Let's check column definitions. If a column was added at
 
2857
      the end of the table, then we don't care much since such change
 
2858
      is backward compatible.
 
2859
    */
 
2860
  }
 
2861
  char buffer[STRING_BUFFER_USUAL_SIZE];
 
2862
  for (i=0 ; i < table_f_count; i++, table_def++)
 
2863
  {
 
2864
    String sql_type(buffer, sizeof(buffer), system_charset_info);
 
2865
    sql_type.length(0);
 
2866
    if (i < s->fields)
 
2867
    {
 
2868
      Field *cur_field= this->field[i];
 
2869
 
 
2870
      if (strncmp(cur_field->field_name, table_def->name.str,
 
2871
                  table_def->name.length))
 
2872
      {
 
2873
        /*
 
2874
          Name changes are not fatal, we use ordinal numbers to access columns.
 
2875
          Still this can be a sign of a tampered table, output an error
 
2876
          to the error log.
 
2877
        */
 
2878
        errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
 
2879
                        "expected column '%s' at position %d, found '%s'."),
 
2880
                        s->db.str, alias, table_def->name.str, i,
 
2881
                        cur_field->field_name);
 
2882
      }
 
2883
      cur_field->sql_type(sql_type);
 
2884
      /*
 
2885
        Generally, if column types don't match, then something is
 
2886
        wrong.
 
2887
 
 
2888
        However, we only compare column definitions up to the
 
2889
        length of the original definition, since we consider the
 
2890
        following definitions compatible:
 
2891
 
 
2892
        1. DATETIME and DATETIM
 
2893
        2. INT(11) and INT(11
 
2894
        3. SET('one', 'two') and SET('one', 'two', 'more')
 
2895
 
 
2896
        For SETs or ENUMs, if the same prefix is there it's OK to
 
2897
        add more elements - they will get higher ordinal numbers and
 
2898
        the new table definition is backward compatible with the
 
2899
        original one.
 
2900
       */
 
2901
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
 
2902
                  table_def->type.length - 1))
 
2903
      {
 
2904
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2905
                      _("Incorrect definition of table %s.%s: "
 
2906
                        "expected column '%s' at position %d to have type "
 
2907
                        "%s, found type %s."),
 
2908
                      s->db.str, alias,
 
2909
                      table_def->name.str, i, table_def->type.str,
 
2910
                      sql_type.c_ptr_safe());
 
2911
        error= true;
 
2912
      }
 
2913
      else if (table_def->cset.str && !cur_field->has_charset())
 
2914
      {
 
2915
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2916
                      _("Incorrect definition of table %s.%s: "
 
2917
                        "expected the type of column '%s' at position %d "
 
2918
                        "to have character set '%s' but the type has no "
 
2919
                        "character set."),
 
2920
                      s->db.str, alias,
 
2921
                      table_def->name.str, i, table_def->cset.str);
 
2922
        error= true;
 
2923
      }
 
2924
      else if (table_def->cset.str &&
 
2925
               strcmp(cur_field->charset()->csname, table_def->cset.str))
 
2926
      {
 
2927
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2928
                      _("Incorrect definition of table %s.%s: "
 
2929
                        "expected the type of column '%s' at position %d "
 
2930
                        "to have character set '%s' but found "
 
2931
                        "character set '%s'."),
 
2932
                      s->db.str, alias,
 
2933
                      table_def->name.str, i, table_def->cset.str,
 
2934
                      cur_field->charset()->csname);
 
2935
        error= true;
 
2936
      }
 
2937
    }
 
2938
    else
 
2939
    {
 
2940
      errmsg_printf(ERRMSG_LVL_ERROR,
 
2941
                    _("Incorrect definition of table %s.%s: "
 
2942
                      "expected column '%s' at position %d to have type %s "
 
2943
                      " but the column is not found."),
 
2944
                    s->db.str, alias,
 
2945
                    table_def->name.str, i, table_def->type.str);
 
2946
      error= true;
 
2947
    }
 
2948
  }
 
2949
  return(error);
 
2950
}
 
2951
 
 
2952
 
 
2953
/*
 
2954
  Create Item_field for each column in the table.
 
2955
 
 
2956
  SYNPOSIS
 
2957
    Table::fill_item_list()
 
2958
      item_list          a pointer to an empty list used to store items
 
2959
 
 
2960
  DESCRIPTION
 
2961
    Create Item_field object for each column in the table and
 
2962
    initialize it with the corresponding Field. New items are
 
2963
    created in the current Session memory root.
 
2964
 
 
2965
  RETURN VALUE
 
2966
    0                    success
 
2967
    1                    out of memory
 
2968
*/
 
2969
 
 
2970
bool Table::fill_item_list(List<Item> *item_list) const
 
2971
{
 
2972
  /*
 
2973
    All Item_field's created using a direct pointer to a field
 
2974
    are fixed in Item_field constructor.
 
2975
  */
 
2976
  for (Field **ptr= field; *ptr; ptr++)
 
2977
  {
 
2978
    Item_field *item= new Item_field(*ptr);
 
2979
    if (!item || item_list->push_back(item))
 
2980
      return true;
 
2981
  }
 
2982
  return false;
 
2983
}
 
2984
 
 
2985
/*
 
2986
  Reset an existing list of Item_field items to point to the
 
2987
  Fields of this table.
 
2988
 
 
2989
  SYNPOSIS
 
2990
    Table::fill_item_list()
 
2991
      item_list          a non-empty list with Item_fields
 
2992
 
 
2993
  DESCRIPTION
 
2994
    This is a counterpart of fill_item_list used to redirect
 
2995
    Item_fields to the fields of a newly created table.
 
2996
    The caller must ensure that number of items in the item_list
 
2997
    is the same as the number of columns in the table.
 
2998
*/
 
2999
 
 
3000
void Table::reset_item_list(List<Item> *item_list) const
 
3001
{
 
3002
  List_iterator_fast<Item> it(*item_list);
 
3003
  for (Field **ptr= field; *ptr; ptr++)
 
3004
  {
 
3005
    Item_field *item_field= (Item_field*) it++;
 
3006
    assert(item_field != 0);
 
3007
    item_field->reset_field(*ptr);
 
3008
  }
 
3009
}
 
3010
 
 
3011
 
 
3012
/*
 
3013
  Find underlying base tables (TableList) which represent given
 
3014
  table_to_find (Table)
 
3015
 
 
3016
  SYNOPSIS
 
3017
    TableList::find_underlying_table()
 
3018
    table_to_find table to find
 
3019
 
 
3020
  RETURN
 
3021
    0  table is not found
 
3022
    found table reference
 
3023
*/
 
3024
 
 
3025
TableList *TableList::find_underlying_table(Table *table_to_find)
 
3026
{
 
3027
  /* is this real table and table which we are looking for? */
 
3028
  if (table == table_to_find && merge_underlying_list == 0)
 
3029
    return this;
 
3030
 
 
3031
  for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
 
3032
  {
 
3033
    TableList *result;
 
3034
    if ((result= tbl->find_underlying_table(table_to_find)))
 
3035
      return result;
 
3036
  }
 
3037
  return 0;
 
3038
}
 
3039
 
 
3040
/*
 
3041
  cleunup items belonged to view fields translation table
 
3042
 
 
3043
  SYNOPSIS
 
3044
    TableList::cleanup_items()
 
3045
*/
 
3046
 
 
3047
void TableList::cleanup_items()
 
3048
{
 
3049
}
 
3050
 
 
3051
 
 
3052
bool TableList::placeholder()
 
3053
{
 
3054
  return derived || schema_table || (create && !table->getDBStat()) || !table;
 
3055
}
 
3056
 
 
3057
 
 
3058
/*
 
3059
  Set insert_values buffer
 
3060
 
 
3061
  SYNOPSIS
 
3062
    set_insert_values()
 
3063
    mem_root   memory pool for allocating
 
3064
 
 
3065
  RETURN
 
3066
    false - OK
 
3067
    TRUE  - out of memory
 
3068
*/
 
3069
 
 
3070
bool TableList::set_insert_values(MEM_ROOT *mem_root)
 
3071
{
 
3072
  if (table)
 
3073
  {
 
3074
    if (!table->insert_values &&
 
3075
        !(table->insert_values= (unsigned char *)alloc_root(mem_root,
 
3076
                                                   table->s->rec_buff_length)))
 
3077
      return true;
 
3078
  }
 
3079
 
 
3080
  return false;
 
3081
}
 
3082
 
 
3083
 
 
3084
/*
 
3085
  Test if this is a leaf with respect to name resolution.
 
3086
 
 
3087
  SYNOPSIS
 
3088
    TableList::is_leaf_for_name_resolution()
 
3089
 
 
3090
  DESCRIPTION
 
3091
    A table reference is a leaf with respect to name resolution if
 
3092
    it is either a leaf node in a nested join tree (table, view,
 
3093
    schema table, subquery), or an inner node that represents a
 
3094
    NATURAL/USING join, or a nested join with materialized join
 
3095
    columns.
 
3096
 
 
3097
  RETURN
 
3098
    TRUE if a leaf, false otherwise.
 
3099
*/
 
3100
bool TableList::is_leaf_for_name_resolution()
 
3101
{
 
3102
  return (is_natural_join || is_join_columns_complete || !nested_join);
 
3103
}
 
3104
 
 
3105
 
 
3106
/*
 
3107
  Retrieve the first (left-most) leaf in a nested join tree with
 
3108
  respect to name resolution.
 
3109
 
 
3110
  SYNOPSIS
 
3111
    TableList::first_leaf_for_name_resolution()
 
3112
 
 
3113
  DESCRIPTION
 
3114
    Given that 'this' is a nested table reference, recursively walk
 
3115
    down the left-most children of 'this' until we reach a leaf
 
3116
    table reference with respect to name resolution.
 
3117
 
 
3118
  IMPLEMENTATION
 
3119
    The left-most child of a nested table reference is the last element
 
3120
    in the list of children because the children are inserted in
 
3121
    reverse order.
 
3122
 
 
3123
  RETURN
 
3124
    If 'this' is a nested table reference - the left-most child of
 
3125
      the tree rooted in 'this',
 
3126
    else return 'this'
 
3127
*/
 
3128
 
 
3129
TableList *TableList::first_leaf_for_name_resolution()
 
3130
{
 
3131
  TableList *cur_table_ref= NULL;
 
3132
  nested_join_st *cur_nested_join;
 
3133
 
 
3134
  if (is_leaf_for_name_resolution())
 
3135
    return this;
 
3136
  assert(nested_join);
 
3137
 
 
3138
  for (cur_nested_join= nested_join;
 
3139
       cur_nested_join;
 
3140
       cur_nested_join= cur_table_ref->nested_join)
 
3141
  {
 
3142
    List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
3143
    cur_table_ref= it++;
 
3144
    /*
 
3145
      If the current nested join is a RIGHT JOIN, the operands in
 
3146
      'join_list' are in reverse order, thus the first operand is
 
3147
      already at the front of the list. Otherwise the first operand
 
3148
      is in the end of the list of join operands.
 
3149
    */
 
3150
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
3151
    {
 
3152
      TableList *next;
 
3153
      while ((next= it++))
 
3154
        cur_table_ref= next;
 
3155
    }
 
3156
    if (cur_table_ref->is_leaf_for_name_resolution())
 
3157
      break;
 
3158
  }
 
3159
  return cur_table_ref;
 
3160
}
 
3161
 
 
3162
 
 
3163
/*
 
3164
  Retrieve the last (right-most) leaf in a nested join tree with
 
3165
  respect to name resolution.
 
3166
 
 
3167
  SYNOPSIS
 
3168
    TableList::last_leaf_for_name_resolution()
 
3169
 
 
3170
  DESCRIPTION
 
3171
    Given that 'this' is a nested table reference, recursively walk
 
3172
    down the right-most children of 'this' until we reach a leaf
 
3173
    table reference with respect to name resolution.
 
3174
 
 
3175
  IMPLEMENTATION
 
3176
    The right-most child of a nested table reference is the first
 
3177
    element in the list of children because the children are inserted
 
3178
    in reverse order.
 
3179
 
 
3180
  RETURN
 
3181
    - If 'this' is a nested table reference - the right-most child of
 
3182
      the tree rooted in 'this',
 
3183
    - else - 'this'
 
3184
*/
 
3185
 
 
3186
TableList *TableList::last_leaf_for_name_resolution()
 
3187
{
 
3188
  TableList *cur_table_ref= this;
 
3189
  nested_join_st *cur_nested_join;
 
3190
 
 
3191
  if (is_leaf_for_name_resolution())
 
3192
    return this;
 
3193
  assert(nested_join);
 
3194
 
 
3195
  for (cur_nested_join= nested_join;
 
3196
       cur_nested_join;
 
3197
       cur_nested_join= cur_table_ref->nested_join)
 
3198
  {
 
3199
    cur_table_ref= cur_nested_join->join_list.head();
 
3200
    /*
 
3201
      If the current nested is a RIGHT JOIN, the operands in
 
3202
      'join_list' are in reverse order, thus the last operand is in the
 
3203
      end of the list.
 
3204
    */
 
3205
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
3206
    {
 
3207
      List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
3208
      TableList *next;
 
3209
      cur_table_ref= it++;
 
3210
      while ((next= it++))
 
3211
        cur_table_ref= next;
 
3212
    }
 
3213
    if (cur_table_ref->is_leaf_for_name_resolution())
 
3214
      break;
 
3215
  }
 
3216
  return cur_table_ref;
 
3217
}
 
3218
 
 
3219
 
403
3220
/*****************************************************************************
404
3221
  Functions to handle column usage bitmaps (read_set, write_set etc...)
405
3222
*****************************************************************************/
413
3230
    bitmap_clear_all(&table->def_read_set);
414
3231
    bitmap_clear_all(&table->def_write_set);
415
3232
  */
416
 
  def_read_set.reset();
417
 
  def_write_set.reset();
418
 
  column_bitmaps_set(def_read_set, def_write_set);
 
3233
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
 
3234
  column_bitmaps_set(&def_read_set, &def_write_set);
419
3235
}
420
3236
 
421
3237
 
422
3238
/*
423
 
  Tell Cursor we are going to call position() and rnd_pos() later.
 
3239
  Tell handler we are going to call position() and rnd_pos() later.
424
3240
 
425
3241
  NOTES:
426
3242
  This is needed for handlers that uses the primary key to find the
431
3247
void Table::prepare_for_position()
432
3248
{
433
3249
 
434
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
435
 
      getShare()->hasPrimaryKey())
 
3250
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
 
3251
      s->primary_key < MAX_KEY)
436
3252
  {
437
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
3253
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3254
    /* signal change */
 
3255
    file->column_bitmaps_signal();
438
3256
  }
439
3257
  return;
440
3258
}
452
3270
 
453
3271
void Table::mark_columns_used_by_index(uint32_t index)
454
3272
{
455
 
  boost::dynamic_bitset<> *bitmap= &tmp_set;
 
3273
  MY_BITMAP *bitmap= &tmp_set;
456
3274
 
457
 
  (void) cursor->extra(HA_EXTRA_KEYREAD);
458
 
  bitmap->reset();
459
 
  mark_columns_used_by_index_no_reset(index, *bitmap);
460
 
  column_bitmaps_set(*bitmap, *bitmap);
 
3275
  (void) file->extra(HA_EXTRA_KEYREAD);
 
3276
  bitmap_clear_all(bitmap);
 
3277
  mark_columns_used_by_index_no_reset(index, bitmap);
 
3278
  column_bitmaps_set(bitmap, bitmap);
461
3279
  return;
462
3280
}
463
3281
 
477
3295
{
478
3296
 
479
3297
  key_read= 0;
480
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3298
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
481
3299
  default_column_bitmaps();
 
3300
  file->column_bitmaps_signal();
482
3301
  return;
483
3302
}
484
3303
 
487
3306
  mark columns used by key, but don't reset other fields
488
3307
*/
489
3308
 
490
 
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
491
 
{
492
 
    mark_columns_used_by_index_no_reset(index, *read_set);
493
 
}
494
 
 
495
 
 
496
3309
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
497
 
                                                boost::dynamic_bitset<>& bitmap)
 
3310
                                                   MY_BITMAP *bitmap)
498
3311
{
499
 
  KeyPartInfo *key_part= key_info[index].key_part;
500
 
  KeyPartInfo *key_part_end= (key_part + key_info[index].key_parts);
501
 
  for (; key_part != key_part_end; key_part++)
 
3312
  KEY_PART_INFO *key_part= key_info[index].key_part;
 
3313
  KEY_PART_INFO *key_part_end= (key_part +
 
3314
                                key_info[index].key_parts);
 
3315
  for (;key_part != key_part_end; key_part++)
502
3316
  {
503
 
    if (! bitmap.empty())
504
 
      bitmap.set(key_part->fieldnr-1);
 
3317
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
 
3318
    if (key_part->field->vcol_info &&
 
3319
        key_part->field->vcol_info->expr_item)
 
3320
      key_part->field->vcol_info->
 
3321
               expr_item->walk(&Item::register_field_in_bitmap,
 
3322
                               1, (unsigned char *) bitmap);
505
3323
  }
506
3324
}
507
3325
 
521
3339
    We must set bit in read set as update_auto_increment() is using the
522
3340
    store() to check overflow of auto_increment values
523
3341
  */
524
 
  setReadSet(found_next_number_field->position());
525
 
  setWriteSet(found_next_number_field->position());
526
 
  if (getShare()->next_number_keypart)
527
 
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
 
3342
  bitmap_set_bit(read_set, found_next_number_field->field_index);
 
3343
  bitmap_set_bit(write_set, found_next_number_field->field_index);
 
3344
  if (s->next_number_keypart)
 
3345
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
 
3346
  file->column_bitmaps_signal();
528
3347
}
529
3348
 
530
3349
 
548
3367
 
549
3368
void Table::mark_columns_needed_for_delete()
550
3369
{
551
 
  /*
552
 
    If the Cursor has no cursor capabilites, or we have row-based
553
 
    replication active for the current statement, we have to read
554
 
    either the primary key, the hidden primary key or all columns to
555
 
    be able to do an delete
556
 
 
557
 
  */
558
 
  if (not getShare()->hasPrimaryKey())
559
 
  {
560
 
    /* fallback to use all columns in the table to identify row */
561
 
    use_all_columns();
562
 
    return;
563
 
  }
564
 
  else
565
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
566
 
 
567
 
  /* If we the engine wants all predicates we mark all keys */
568
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
3370
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
569
3371
  {
570
3372
    Field **reg_field;
571
3373
    for (reg_field= field ; *reg_field ; reg_field++)
572
3374
    {
573
3375
      if ((*reg_field)->flags & PART_KEY_FLAG)
574
 
        setReadSet((*reg_field)->position());
 
3376
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
3377
    }
 
3378
    file->column_bitmaps_signal();
 
3379
  }
 
3380
 
 
3381
  {
 
3382
    /*
 
3383
      If the handler has no cursor capabilites, or we have row-based
 
3384
      replication active for the current statement, we have to read
 
3385
      either the primary key, the hidden primary key or all columns to
 
3386
      be able to do an delete
 
3387
    */
 
3388
    if (s->primary_key == MAX_KEY)
 
3389
      file->use_hidden_primary_key();
 
3390
    else
 
3391
    {
 
3392
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3393
      file->column_bitmaps_signal();
575
3394
    }
576
3395
  }
577
3396
}
589
3408
    if neeed, either the primary key column or all columns to be read.
590
3409
    (see mark_columns_needed_for_delete() for details)
591
3410
 
592
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
3411
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
593
3412
    mark all USED key columns as 'to-be-read'. This allows the engine to
594
3413
    loop over the given record to find all changed keys and doesn't have to
595
3414
    retrieve the row again.
597
3416
 
598
3417
void Table::mark_columns_needed_for_update()
599
3418
{
600
 
  /*
601
 
    If the Cursor has no cursor capabilites, or we have row-based
602
 
    logging active for the current statement, we have to read either
603
 
    the primary key, the hidden primary key or all columns to be
604
 
    able to do an update
605
 
  */
606
 
  if (not getShare()->hasPrimaryKey())
607
 
  {
608
 
    /* fallback to use all columns in the table to identify row */
609
 
    use_all_columns();
610
 
    return;
611
 
  }
612
 
  else
613
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
614
 
 
615
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
3419
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
616
3420
  {
617
3421
    /* Mark all used key columns for read */
618
3422
    Field **reg_field;
619
3423
    for (reg_field= field ; *reg_field ; reg_field++)
620
3424
    {
621
3425
      /* Merge keys is all keys that had a column refered to in the query */
622
 
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
623
 
        setReadSet((*reg_field)->position());
 
3426
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
 
3427
        bitmap_set_bit(read_set, (*reg_field)->field_index);
624
3428
    }
 
3429
    file->column_bitmaps_signal();
625
3430
  }
626
3431
 
 
3432
  {
 
3433
    /*
 
3434
      If the handler has no cursor capabilites, or we have row-based
 
3435
      logging active for the current statement, we have to read either
 
3436
      the primary key, the hidden primary key or all columns to be
 
3437
      able to do an update
 
3438
    */
 
3439
    if (s->primary_key == MAX_KEY)
 
3440
      file->use_hidden_primary_key();
 
3441
    else
 
3442
    {
 
3443
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
3444
      file->column_bitmaps_signal();
 
3445
    }
 
3446
  }
 
3447
  /* Mark all virtual columns as writable */
 
3448
  mark_virtual_columns();
 
3449
  return;
627
3450
}
628
3451
 
629
3452
 
630
3453
/*
631
 
  Mark columns the Cursor needs for doing an insert
 
3454
  Mark columns the handler needs for doing an insert
632
3455
 
633
3456
  For now, this is used to mark fields used by the trigger
634
3457
  as changed.
638
3461
{
639
3462
  if (found_next_number_field)
640
3463
    mark_auto_increment_column();
641
 
}
642
 
 
 
3464
  /* Mark all virtual columns as writable */
 
3465
  mark_virtual_columns();
 
3466
}
 
3467
 
 
3468
/*
 
3469
  @brief Update the write and read table bitmap to allow
 
3470
         using procedure save_in_field for all virtual columns
 
3471
         in the table.
 
3472
 
 
3473
  @return       void
 
3474
 
 
3475
  @detail
 
3476
    Each virtual field is set in the write column map.
 
3477
    All fields that the virtual columns are based on are set in the
 
3478
    read bitmap.
 
3479
*/
 
3480
 
 
3481
void Table::mark_virtual_columns(void)
 
3482
{
 
3483
  Field **vfield_ptr, *tmp_vfield;
 
3484
  bool bitmap_updated= false;
 
3485
 
 
3486
  for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
 
3487
  {
 
3488
    tmp_vfield= *vfield_ptr;
 
3489
    assert(tmp_vfield->vcol_info && tmp_vfield->vcol_info->expr_item);
 
3490
    tmp_vfield->vcol_info->expr_item->walk(&Item::register_field_in_read_map,
 
3491
                                           1, (unsigned char *) 0);
 
3492
    bitmap_set_bit(read_set, tmp_vfield->field_index);
 
3493
    bitmap_set_bit(write_set, tmp_vfield->field_index);
 
3494
    bitmap_updated= true;
 
3495
  }
 
3496
  if (bitmap_updated)
 
3497
    file->column_bitmaps_signal();
 
3498
}
 
3499
 
 
3500
 
 
3501
/*
 
3502
  Cleanup this table for re-execution.
 
3503
 
 
3504
  SYNOPSIS
 
3505
    TableList::reinit_before_use()
 
3506
*/
 
3507
 
 
3508
void TableList::reinit_before_use(Session *session)
 
3509
{
 
3510
  /*
 
3511
    Reset old pointers to TABLEs: they are not valid since the tables
 
3512
    were closed in the end of previous prepare or execute call.
 
3513
  */
 
3514
  table= 0;
 
3515
  /* Reset is_schema_table_processed value(needed for I_S tables */
 
3516
  schema_table_state= NOT_PROCESSED;
 
3517
 
 
3518
  TableList *embedded; /* The table at the current level of nesting. */
 
3519
  TableList *parent_embedding= this; /* The parent nested table reference. */
 
3520
  do
 
3521
  {
 
3522
    embedded= parent_embedding;
 
3523
    if (embedded->prep_on_expr)
 
3524
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
 
3525
    parent_embedding= embedded->embedding;
 
3526
  }
 
3527
  while (parent_embedding &&
 
3528
         parent_embedding->nested_join->join_list.head() == embedded);
 
3529
}
 
3530
 
 
3531
/*
 
3532
  Return subselect that contains the FROM list this table is taken from
 
3533
 
 
3534
  SYNOPSIS
 
3535
    TableList::containing_subselect()
 
3536
 
 
3537
  RETURN
 
3538
    Subselect item for the subquery that contains the FROM list
 
3539
    this table is taken from if there is any
 
3540
    0 - otherwise
 
3541
 
 
3542
*/
 
3543
 
 
3544
Item_subselect *TableList::containing_subselect()
 
3545
{
 
3546
  return (select_lex ? select_lex->master_unit()->item : 0);
 
3547
}
 
3548
 
 
3549
/*
 
3550
  Compiles the tagged hints list and fills up the bitmasks.
 
3551
 
 
3552
  SYNOPSIS
 
3553
    process_index_hints()
 
3554
      table         the Table to operate on.
 
3555
 
 
3556
  DESCRIPTION
 
3557
    The parser collects the index hints for each table in a "tagged list"
 
3558
    (TableList::index_hints). Using the information in this tagged list
 
3559
    this function sets the members Table::keys_in_use_for_query,
 
3560
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
 
3561
    Table::force_index and Table::covering_keys.
 
3562
 
 
3563
    Current implementation of the runtime does not allow mixing FORCE INDEX
 
3564
    and USE INDEX, so this is checked here. Then the FORCE INDEX list
 
3565
    (if non-empty) is appended to the USE INDEX list and a flag is set.
 
3566
 
 
3567
    Multiple hints of the same kind are processed so that each clause
 
3568
    is applied to what is computed in the previous clause.
 
3569
    For example:
 
3570
        USE INDEX (i1) USE INDEX (i2)
 
3571
    is equivalent to
 
3572
        USE INDEX (i1,i2)
 
3573
    and means "consider only i1 and i2".
 
3574
 
 
3575
    Similarly
 
3576
        USE INDEX () USE INDEX (i1)
 
3577
    is equivalent to
 
3578
        USE INDEX (i1)
 
3579
    and means "consider only the index i1"
 
3580
 
 
3581
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
 
3582
    not an error.
 
3583
 
 
3584
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
 
3585
    order:
 
3586
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
 
3587
      2. All IGNORE INDEX
 
3588
 
 
3589
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
 
3590
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
 
3591
 
 
3592
    As an optimization if there is a covering index, and we have
 
3593
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
 
3594
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
 
3595
 
 
3596
  RETURN VALUE
 
3597
    false                no errors found
 
3598
    TRUE                 found and reported an error.
 
3599
*/
 
3600
bool TableList::process_index_hints(Table *tbl)
 
3601
{
 
3602
  /* initialize the result variables */
 
3603
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
 
3604
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
 
3605
 
 
3606
  /* index hint list processing */
 
3607
  if (index_hints)
 
3608
  {
 
3609
    key_map index_join[INDEX_HINT_FORCE + 1];
 
3610
    key_map index_order[INDEX_HINT_FORCE + 1];
 
3611
    key_map index_group[INDEX_HINT_FORCE + 1];
 
3612
    Index_hint *hint;
 
3613
    int type;
 
3614
    bool have_empty_use_join= false, have_empty_use_order= false,
 
3615
         have_empty_use_group= false;
 
3616
    List_iterator <Index_hint> iter(*index_hints);
 
3617
 
 
3618
    /* initialize temporary variables used to collect hints of each kind */
 
3619
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
 
3620
    {
 
3621
      index_join[type].clear_all();
 
3622
      index_order[type].clear_all();
 
3623
      index_group[type].clear_all();
 
3624
    }
 
3625
 
 
3626
    /* iterate over the hints list */
 
3627
    while ((hint= iter++))
 
3628
    {
 
3629
      uint32_t pos;
 
3630
 
 
3631
      /* process empty USE INDEX () */
 
3632
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
 
3633
      {
 
3634
        if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3635
        {
 
3636
          index_join[hint->type].clear_all();
 
3637
          have_empty_use_join= true;
 
3638
        }
 
3639
        if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3640
        {
 
3641
          index_order[hint->type].clear_all();
 
3642
          have_empty_use_order= true;
 
3643
        }
 
3644
        if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3645
        {
 
3646
          index_group[hint->type].clear_all();
 
3647
          have_empty_use_group= true;
 
3648
        }
 
3649
        continue;
 
3650
      }
 
3651
 
 
3652
      /*
 
3653
        Check if an index with the given name exists and get his offset in
 
3654
        the keys bitmask for the table
 
3655
      */
 
3656
      if (tbl->s->keynames.type_names == 0 ||
 
3657
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
 
3658
                          hint->key_name.length, 1)) <= 0)
 
3659
      {
 
3660
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
 
3661
        return 1;
 
3662
      }
 
3663
 
 
3664
      pos--;
 
3665
 
 
3666
      /* add to the appropriate clause mask */
 
3667
      if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3668
        index_join[hint->type].set_bit (pos);
 
3669
      if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3670
        index_order[hint->type].set_bit (pos);
 
3671
      if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3672
        index_group[hint->type].set_bit (pos);
 
3673
    }
 
3674
 
 
3675
    /* cannot mix USE INDEX and FORCE INDEX */
 
3676
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3677
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3678
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
 
3679
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
 
3680
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
 
3681
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
 
3682
    {
 
3683
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
 
3684
               index_hint_type_name[INDEX_HINT_FORCE]);
 
3685
      return 1;
 
3686
    }
 
3687
 
 
3688
    /* process FORCE INDEX as USE INDEX with a flag */
 
3689
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3690
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3691
        !index_group[INDEX_HINT_FORCE].is_clear_all())
 
3692
    {
 
3693
      tbl->force_index= true;
 
3694
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
 
3695
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
 
3696
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
 
3697
    }
 
3698
 
 
3699
    /* apply USE INDEX */
 
3700
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
 
3701
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
 
3702
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
 
3703
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
 
3704
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
 
3705
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
 
3706
 
 
3707
    /* apply IGNORE INDEX */
 
3708
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
 
3709
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
 
3710
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
 
3711
  }
 
3712
 
 
3713
  /* make sure covering_keys don't include indexes disabled with a hint */
 
3714
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
 
3715
  return 0;
 
3716
}
643
3717
 
644
3718
 
645
3719
size_t Table::max_row_length(const unsigned char *data)
652
3726
  {
653
3727
    Field_blob* const blob= (Field_blob*) field[*ptr];
654
3728
    length+= blob->get_length((const unsigned char*)
655
 
                              (data + blob->offset(getInsertRecord()))) +
 
3729
                              (data + blob->offset(record[0]))) +
656
3730
      HA_KEY_BLOB_LENGTH;
657
3731
  }
658
3732
  return length;
659
3733
}
660
3734
 
661
 
void Table::setVariableWidth(void)
662
 
{
663
 
  assert(in_use);
664
 
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
665
 
  {
666
 
    getMutableShare()->setVariableWidth();
667
 
    return;
668
 
  }
669
 
 
670
 
  assert(0); // Programming error, you can't set this on a plain old Table.
671
 
}
672
 
 
673
3735
/****************************************************************************
674
3736
 Functions for creating temporary tables.
675
3737
****************************************************************************/
 
3738
 
 
3739
 
 
3740
/* Prototypes */
 
3741
void free_tmp_table(Session *session, Table *entry);
 
3742
 
676
3743
/**
677
3744
  Create field for temporary table from given field.
678
3745
 
679
 
  @param session               Thread Cursor
 
3746
  @param session               Thread handler
680
3747
  @param org_field    field from which new field will be created
681
3748
  @param name         New field name
682
3749
  @param table         Temporary table
707
3774
  */
708
3775
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
709
3776
      (org_field->flags & BLOB_FLAG))
710
 
  {
711
 
    table->setVariableWidth();
712
3777
    new_field= new Field_varstring(convert_blob_length,
713
3778
                                   org_field->maybe_null(),
714
 
                                   org_field->field_name,
 
3779
                                   org_field->field_name, table->s,
715
3780
                                   org_field->charset());
716
 
  }
717
3781
  else
718
 
  {
719
3782
    new_field= org_field->new_field(session->mem_root, table,
720
 
                                    table == org_field->getTable());
721
 
  }
 
3783
                                    table == org_field->table);
722
3784
  if (new_field)
723
3785
  {
724
3786
    new_field->init(table);
731
3793
    if (org_field->maybe_null() || (item && item->maybe_null))
732
3794
      new_field->flags&= ~NOT_NULL_FLAG;        // Because of outer join
733
3795
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
734
 
      table->getMutableShare()->db_create_options|= HA_OPTION_PACK_RECORD;
 
3796
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
735
3797
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
736
3798
      ((Field_double *) new_field)->not_fixed= true;
737
3799
  }
740
3802
 
741
3803
 
742
3804
/**
 
3805
  Create field for information schema table.
 
3806
 
 
3807
  @param session                Thread handler
 
3808
  @param table          Temporary table
 
3809
  @param item           Item to create a field for
 
3810
 
 
3811
  @retval
 
3812
    0                   on error
 
3813
  @retval
 
3814
    new_created field
 
3815
*/
 
3816
 
 
3817
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
 
3818
{
 
3819
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
3820
  {
 
3821
    Field *field;
 
3822
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
3823
      field= new Field_blob(item->max_length, item->maybe_null,
 
3824
                            item->name, item->collation.collation);
 
3825
    else
 
3826
      field= new Field_varstring(item->max_length, item->maybe_null,
 
3827
                                 item->name,
 
3828
                                 table->s, item->collation.collation);
 
3829
    if (field)
 
3830
      field->init(table);
 
3831
    return field;
 
3832
  }
 
3833
  return item->tmp_table_field_from_field_type(table, 0);
 
3834
}
 
3835
 
 
3836
 
 
3837
/**
743
3838
  Create a temp table according to a field list.
744
3839
 
745
3840
  Given field pointers are changed to point at tmp_table for
771
3866
 
772
3867
Table *
773
3868
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
774
 
                 Order *group, bool distinct, bool save_sum_fields,
 
3869
                 order_st *group, bool distinct, bool save_sum_fields,
775
3870
                 uint64_t select_options, ha_rows rows_limit,
776
 
                 const char *table_alias)
 
3871
                 char *table_alias)
777
3872
{
778
 
  memory::Root *mem_root_save;
 
3873
  MEM_ROOT *mem_root_save, own_root;
 
3874
  Table *table;
 
3875
  TABLE_SHARE *share;
779
3876
  uint  i,field_count,null_count,null_pack_length;
780
3877
  uint32_t  copy_func_count= param->func_count;
781
3878
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
782
3879
  uint32_t  blob_count,group_null_items, string_count;
 
3880
  uint32_t  temp_pool_slot=MY_BIT_NONE;
783
3881
  uint32_t fieldnr= 0;
784
3882
  ulong reclength, string_total_length;
785
 
  bool  using_unique_constraint= false;
786
 
  bool  use_packed_rows= true;
 
3883
  bool  using_unique_constraint= 0;
 
3884
  bool  use_packed_rows= 0;
787
3885
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
788
 
  unsigned char *pos, *group_buff;
 
3886
  char  *tmpname,path[FN_REFLEN];
 
3887
  unsigned char *pos, *group_buff, *bitmaps;
789
3888
  unsigned char *null_flags;
790
3889
  Field **reg_field, **from_field, **default_field;
791
 
  CopyField *copy= 0;
792
 
  KeyInfo *keyinfo;
793
 
  KeyPartInfo *key_part_info;
 
3890
  uint32_t *blob_field;
 
3891
  Copy_field *copy=0;
 
3892
  KEY *keyinfo;
 
3893
  KEY_PART_INFO *key_part_info;
794
3894
  Item **copy_func;
795
3895
  MI_COLUMNDEF *recinfo;
796
3896
  uint32_t total_uneven_bit_length= 0;
797
3897
  bool force_copy_fields= param->force_copy_fields;
798
 
  uint64_t max_rows= 0;
799
 
 
800
 
  session->status_var.created_tmp_tables++;
 
3898
 
 
3899
  status_var_increment(session->status_var.created_tmp_tables);
 
3900
 
 
3901
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
 
3902
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
 
3903
 
 
3904
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
 
3905
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
 
3906
            (unsigned long)current_pid, temp_pool_slot);
 
3907
  else
 
3908
  {
 
3909
    /* if we run out of slots or we are not using tempool */
 
3910
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
3911
            session->thread_id, session->tmp_table++);
 
3912
  }
 
3913
 
 
3914
  /*
 
3915
    No need to change table name to lower case as we are only creating
 
3916
    MyISAM or HEAP tables here
 
3917
  */
 
3918
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3919
 
801
3920
 
802
3921
  if (group)
803
3922
  {
804
 
    if (! param->quick_group)
805
 
    {
806
 
      group= 0;                                 // Can't use group key
807
 
    }
808
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
3923
    if (!param->quick_group)
 
3924
      group=0;                                  // Can't use group key
 
3925
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
809
3926
    {
810
3927
      /*
811
3928
        marker == 4 means two things:
815
3932
      */
816
3933
      (*tmp->item)->marker= 4;
817
3934
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
818
 
        using_unique_constraint= true;
 
3935
        using_unique_constraint=1;
819
3936
    }
820
3937
    if (param->group_length >= MAX_BLOB_WIDTH)
821
 
      using_unique_constraint= true;
 
3938
      using_unique_constraint=1;
822
3939
    if (group)
823
 
      distinct= 0;                              // Can't use distinct
 
3940
      distinct=0;                               // Can't use distinct
824
3941
  }
825
3942
 
826
3943
  field_count=param->field_count+param->func_count+param->sum_func_count;
834
3951
    these items are stored in the temporary table.
835
3952
  */
836
3953
  if (param->precomputed_group_by)
837
 
  {
838
3954
    copy_func_count+= param->sum_func_count;
839
 
  }
840
 
 
841
 
  table::Instance *table;
842
 
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
843
 
 
844
 
  if (not table->getMemRoot()->multi_alloc_root(0,
845
 
                                                &default_field, sizeof(Field*) * (field_count),
846
 
                                                &from_field, sizeof(Field*)*field_count,
847
 
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
848
 
                                                &param->keyinfo, sizeof(*param->keyinfo),
849
 
                                                &key_part_info, sizeof(*key_part_info)*(param->group_parts+1),
850
 
                                                &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
851
 
                                                &group_buff, (group && ! using_unique_constraint ?
852
 
                                                              param->group_length : 0),
853
 
                                                NULL))
854
 
  {
855
 
    return NULL;
856
 
  }
857
 
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
858
 
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
859
 
  {
860
 
    return NULL;
 
3955
 
 
3956
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
3957
 
 
3958
  if (!multi_alloc_root(&own_root,
 
3959
                        &table, sizeof(*table),
 
3960
                        &share, sizeof(*share),
 
3961
                        &reg_field, sizeof(Field*) * (field_count+1),
 
3962
                        &default_field, sizeof(Field*) * (field_count),
 
3963
                        &blob_field, sizeof(uint32_t)*(field_count+1),
 
3964
                        &from_field, sizeof(Field*)*field_count,
 
3965
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
 
3966
                        &param->keyinfo, sizeof(*param->keyinfo),
 
3967
                        &key_part_info,
 
3968
                        sizeof(*key_part_info)*(param->group_parts+1),
 
3969
                        &param->start_recinfo,
 
3970
                        sizeof(*param->recinfo)*(field_count*2+4),
 
3971
                        &tmpname, (uint32_t) strlen(path)+1,
 
3972
                        &group_buff, (group && ! using_unique_constraint ?
 
3973
                                      param->group_length : 0),
 
3974
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
3975
                        NULL))
 
3976
  {
 
3977
    if (temp_pool_slot != MY_BIT_NONE)
 
3978
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3979
    return(NULL);                               /* purecov: inspected */
 
3980
  }
 
3981
  /* Copy_field belongs to Tmp_Table_Param, allocate it in Session mem_root */
 
3982
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
 
3983
  {
 
3984
    if (temp_pool_slot != MY_BIT_NONE)
 
3985
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3986
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
3987
    return(NULL);                               /* purecov: inspected */
861
3988
  }
862
3989
  param->items_to_copy= copy_func;
 
3990
  strcpy(tmpname,path);
863
3991
  /* make table according to fields */
864
3992
 
 
3993
  memset(table, 0, sizeof(*table));
 
3994
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
865
3995
  memset(default_field, 0, sizeof(Field*) * (field_count));
866
3996
  memset(from_field, 0, sizeof(Field*)*field_count);
867
3997
 
 
3998
  table->mem_root= own_root;
868
3999
  mem_root_save= session->mem_root;
869
 
  session->mem_root= table->getMemRoot();
 
4000
  session->mem_root= &table->mem_root;
870
4001
 
871
 
  table->getMutableShare()->setFields(field_count+1);
872
 
  table->setFields(table->getMutableShare()->getFields(true));
873
 
  reg_field= table->getMutableShare()->getFields(true);
874
 
  table->setAlias(table_alias);
 
4002
  table->field=reg_field;
 
4003
  table->alias= table_alias;
875
4004
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
876
4005
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
877
4006
  table->map=1;
 
4007
  table->temp_pool_slot = temp_pool_slot;
878
4008
  table->copy_blobs= 1;
879
 
  assert(session);
880
4009
  table->in_use= session;
881
 
  table->quick_keys.reset();
882
 
  table->covering_keys.reset();
883
 
  table->keys_in_use_for_query.reset();
 
4010
  table->quick_keys.init();
 
4011
  table->covering_keys.init();
 
4012
  table->keys_in_use_for_query.init();
884
4013
 
885
 
  table->getMutableShare()->blob_field.resize(field_count+1);
886
 
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
887
 
  table->getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
888
 
  table->getMutableShare()->db_low_byte_first=1;                // True for HEAP and MyISAM
889
 
  table->getMutableShare()->table_charset= param->table_charset;
890
 
  table->getMutableShare()->keys_for_keyread.reset();
891
 
  table->getMutableShare()->keys_in_use.reset();
 
4014
  table->setShare(share);
 
4015
  init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
 
4016
  share->blob_field= blob_field;
 
4017
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
4018
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
4019
  share->table_charset= param->table_charset;
 
4020
  share->primary_key= MAX_KEY;               // Indicate no primary key
 
4021
  share->keys_for_keyread.init();
 
4022
  share->keys_in_use.init();
892
4023
 
893
4024
  /* Calculate which type of fields we will store in the temporary table */
894
4025
 
895
4026
  reclength= string_total_length= 0;
896
4027
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
897
 
  param->using_indirect_summary_function= 0;
 
4028
  param->using_indirect_summary_function=0;
898
4029
 
899
4030
  List_iterator_fast<Item> li(fields);
900
4031
  Item *item;
925
4056
    }
926
4057
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
927
4058
    {                                           /* Can't calc group yet */
928
 
      ((Item_sum*) item)->result_field= 0;
929
 
      for (i= 0 ; i < ((Item_sum*) item)->arg_count ; i++)
 
4059
      ((Item_sum*) item)->result_field=0;
 
4060
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
930
4061
      {
931
4062
        Item **argp= ((Item_sum*) item)->args + i;
932
4063
        Item *arg= *argp;
936
4067
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
937
4068
                             tmp_from_field, &default_field[fieldnr],
938
4069
                             group != 0,not_all_columns,
939
 
                             false,
 
4070
                             distinct, 0,
940
4071
                             param->convert_blob_length);
941
4072
          if (!new_field)
942
4073
            goto err;                                   // Should be OOM
955
4086
          }
956
4087
          session->mem_root= mem_root_save;
957
4088
          session->change_item_tree(argp, new Item_field(new_field));
958
 
          session->mem_root= table->getMemRoot();
 
4089
          session->mem_root= &table->mem_root;
959
4090
          if (!(new_field->flags & NOT_NULL_FLAG))
960
4091
          {
961
4092
            null_count++;
965
4096
            */
966
4097
            (*argp)->maybe_null=1;
967
4098
          }
968
 
          new_field->setPosition(fieldnr++);
 
4099
          new_field->field_index= fieldnr++;
969
4100
        }
970
4101
      }
971
4102
    }
981
4112
        We here distinguish between UNION and multi-table-updates by the fact
982
4113
        that in the later case group is set to the row pointer.
983
4114
      */
984
 
      Field *new_field=
 
4115
      Field *new_field= (param->schema_table) ?
 
4116
        create_tmp_field_for_schema(session, item, table) :
985
4117
        create_tmp_field(session, table, item, type, &copy_func,
986
4118
                         tmp_from_field, &default_field[fieldnr],
987
4119
                         group != 0,
988
4120
                         !force_copy_fields &&
989
 
                           (not_all_columns || group != 0),
 
4121
                           (not_all_columns || group !=0),
 
4122
                         /*
 
4123
                           If item->marker == 4 then we force create_tmp_field
 
4124
                           to create a 64-bit longs for BIT fields because HEAP
 
4125
                           tables can't index BIT fields directly. We do the same
 
4126
                           for distinct, as we want the distinct index to be
 
4127
                           usable in this case too.
 
4128
                         */
 
4129
                         item->marker == 4 || param->bit_fields_as_long,
990
4130
                         force_copy_fields,
991
4131
                         param->convert_blob_length);
992
4132
 
1012
4152
        group_null_items++;
1013
4153
        new_field->flags|= GROUP_FLAG;
1014
4154
      }
1015
 
      new_field->setPosition(fieldnr++);
 
4155
      new_field->field_index= fieldnr++;
1016
4156
      *(reg_field++)= new_field;
1017
4157
    }
1018
4158
    if (!--hidden_field_count)
1030
4170
      null_count= 0;
1031
4171
    }
1032
4172
  }
1033
 
  assert(fieldnr == (uint32_t) (reg_field - table->getFields()));
1034
 
  assert(field_count >= (uint32_t) (reg_field - table->getFields()));
 
4173
  assert(fieldnr == (uint32_t) (reg_field - table->field));
 
4174
  assert(field_count >= (uint32_t) (reg_field - table->field));
1035
4175
  field_count= fieldnr;
1036
4176
  *reg_field= 0;
1037
4177
  *blob_field= 0;                               // End marker
1038
 
  table->getMutableShare()->fields= field_count;
 
4178
  share->fields= field_count;
1039
4179
 
1040
4180
  /* If result table is small; use a heap */
1041
4181
  /* future: storage engine selection can be made dynamic? */
1042
 
  if (blob_count || using_unique_constraint || 
1043
 
      (session->lex->select_lex.options & SELECT_BIG_RESULT) ||
1044
 
      (session->lex->current_select->olap == ROLLUP_TYPE) ||
1045
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
 
4182
  if (blob_count || using_unique_constraint ||
 
4183
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
4184
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
1046
4185
  {
1047
 
    table->getMutableShare()->storage_engine= myisam_engine;
1048
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
4186
    share->db_plugin= ha_lock_engine(0, myisam_hton);
 
4187
    table->file= get_new_handler(share, &table->mem_root,
 
4188
                                 share->db_type());
1049
4189
    if (group &&
1050
 
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
1051
 
         param->group_length > table->cursor->getEngine()->max_key_length()))
1052
 
    {
1053
 
      using_unique_constraint= true;
1054
 
    }
 
4190
        (param->group_parts > table->file->max_key_parts() ||
 
4191
         param->group_length > table->file->max_key_length()))
 
4192
      using_unique_constraint=1;
1055
4193
  }
1056
4194
  else
1057
4195
  {
1058
 
    table->getMutableShare()->storage_engine= heap_engine;
1059
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
4196
    share->db_plugin= ha_lock_engine(0, heap_hton);
 
4197
    table->file= get_new_handler(share, &table->mem_root,
 
4198
                                 share->db_type());
1060
4199
  }
1061
 
  if (! table->cursor)
 
4200
  if (!table->file)
1062
4201
    goto err;
1063
4202
 
1064
4203
 
1065
 
  if (! using_unique_constraint)
 
4204
  if (!using_unique_constraint)
1066
4205
    reclength+= group_null_items;       // null flag is stored separately
1067
4206
 
1068
 
  table->getMutableShare()->blob_fields= blob_count;
 
4207
  share->blob_fields= blob_count;
1069
4208
  if (blob_count == 0)
1070
4209
  {
1071
4210
    /* We need to ensure that first byte is not 0 for the delete link */
1084
4223
  if (blob_count || ((string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS) && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || (string_total_length / string_count) >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
1085
4224
    use_packed_rows= 1;
1086
4225
 
1087
 
  table->getMutableShare()->setRecordLength(reclength);
 
4226
  share->reclength= reclength;
1088
4227
  {
1089
4228
    uint32_t alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
1090
 
    table->getMutableShare()->rec_buff_length= alloc_length;
1091
 
    if (!(table->record[0]= (unsigned char*) table->alloc_root(alloc_length*2)))
1092
 
    {
 
4229
    share->rec_buff_length= alloc_length;
 
4230
    if (!(table->record[0]= (unsigned char*)
 
4231
                            alloc_root(&table->mem_root, alloc_length*3)))
1093
4232
      goto err;
1094
 
    }
1095
 
    table->record[1]= table->getInsertRecord()+alloc_length;
1096
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
4233
    table->record[1]= table->record[0]+alloc_length;
 
4234
    share->default_values= table->record[1]+alloc_length;
1097
4235
  }
1098
 
  copy_func[0]= 0;                              // End marker
 
4236
  copy_func[0]=0;                               // End marker
1099
4237
  param->func_count= copy_func - param->items_to_copy;
1100
4238
 
1101
 
  table->setup_tmp_table_column_bitmaps();
 
4239
  table->setup_tmp_table_column_bitmaps(bitmaps);
1102
4240
 
1103
4241
  recinfo=param->start_recinfo;
1104
 
  null_flags=(unsigned char*) table->getInsertRecord();
1105
 
  pos=table->getInsertRecord()+ null_pack_length;
 
4242
  null_flags=(unsigned char*) table->record[0];
 
4243
  pos=table->record[0]+ null_pack_length;
1106
4244
  if (null_pack_length)
1107
4245
  {
1108
4246
    memset(recinfo, 0, sizeof(*recinfo));
1111
4249
    recinfo++;
1112
4250
    memset(null_flags, 255, null_pack_length);  // Set null fields
1113
4251
 
1114
 
    table->null_flags= (unsigned char*) table->getInsertRecord();
1115
 
    table->getMutableShare()->null_fields= null_count+ hidden_null_count;
1116
 
    table->getMutableShare()->null_bytes= null_pack_length;
 
4252
    table->null_flags= (unsigned char*) table->record[0];
 
4253
    share->null_fields= null_count+ hidden_null_count;
 
4254
    share->null_bytes= null_pack_length;
1117
4255
  }
1118
4256
  null_count= (blob_count == 0) ? 1 : 0;
1119
4257
  hidden_field_count=param->hidden_field_count;
1120
 
  for (i= 0,reg_field= table->getFields(); i < field_count; i++,reg_field++,recinfo++)
 
4258
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
1121
4259
  {
1122
4260
    Field *field= *reg_field;
1123
4261
    uint32_t length;
1131
4269
          We have to reserve one byte here for NULL bits,
1132
4270
          as this is updated by 'end_update()'
1133
4271
        */
1134
 
        *pos++= '\0';                           // Null is stored here
1135
 
        recinfo->length= 1;
 
4272
        *pos++=0;                               // Null is stored here
 
4273
        recinfo->length=1;
1136
4274
        recinfo->type=FIELD_NORMAL;
1137
4275
        recinfo++;
1138
4276
        memset(recinfo, 0, sizeof(*recinfo));
1161
4299
         inherit the default value that is defined for the field referred
1162
4300
         by the Item_field object from which 'field' has been created.
1163
4301
      */
1164
 
      ptrdiff_t diff;
 
4302
      my_ptrdiff_t diff;
1165
4303
      Field *orig_field= default_field[i];
1166
4304
      /* Get the value from default_values */
1167
 
      diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
 
4305
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
 
4306
                            orig_field->table->record[0]);
1168
4307
      orig_field->move_field_offset(diff);      // Points now at default_values
1169
4308
      if (orig_field->is_real_null())
1170
4309
        field->set_null();
1173
4312
        field->set_notnull();
1174
4313
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
1175
4314
      }
1176
 
      orig_field->move_field_offset(-diff);     // Back to getInsertRecord()
 
4315
      orig_field->move_field_offset(-diff);     // Back to record[0]
1177
4316
    }
1178
4317
 
1179
4318
    if (from_field[i])
1192
4331
      recinfo->type=FIELD_NORMAL;
1193
4332
    if (!--hidden_field_count)
1194
4333
      null_count=(null_count+7) & ~7;           // move to next byte
 
4334
 
 
4335
    // fix table name in field entry
 
4336
    field->table_name= &table->alias;
1195
4337
  }
1196
4338
 
1197
4339
  param->copy_field_end=copy;
1198
4340
  param->recinfo=recinfo;
1199
 
  table->storeRecordAsDefault();        // Make empty default record
 
4341
  store_record(table,s->default_values);        // Make empty default record
1200
4342
 
1201
4343
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
1202
 
  {
1203
 
    max_rows= ~(uint64_t) 0;
1204
 
  }
 
4344
    share->max_rows= ~(ha_rows) 0;
1205
4345
  else
1206
 
  {
1207
 
    max_rows= (uint64_t) (((table->getMutableShare()->db_type() == heap_engine) ?
1208
 
                           min(session->variables.tmp_table_size,
1209
 
                               session->variables.max_heap_table_size) :
1210
 
                           session->variables.tmp_table_size) /
1211
 
                          table->getMutableShare()->getRecordLength());
1212
 
  }
1213
 
 
1214
 
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
 
4346
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
 
4347
                                 cmin(session->variables.tmp_table_size,
 
4348
                                     session->variables.max_heap_table_size) :
 
4349
                                 session->variables.tmp_table_size) /
 
4350
                                 share->reclength);
 
4351
  set_if_bigger(share->max_rows,1);             // For dummy start options
1215
4352
  /*
1216
4353
    Push the LIMIT clause to the temporary table creation, so that we
1217
4354
    materialize only up to 'rows_limit' records instead of all result records.
1218
4355
  */
1219
 
  set_if_smaller(max_rows, rows_limit);
1220
 
 
1221
 
  table->getMutableShare()->setMaxRows(max_rows);
1222
 
 
 
4356
  set_if_smaller(share->max_rows, rows_limit);
1223
4357
  param->end_write_records= rows_limit;
1224
4358
 
1225
4359
  keyinfo= param->keyinfo;
1228
4362
  {
1229
4363
    table->group=group;                         /* Table is grouped by key */
1230
4364
    param->group_buff=group_buff;
1231
 
    table->getMutableShare()->keys=1;
1232
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
4365
    share->keys=1;
 
4366
    share->uniques= test(using_unique_constraint);
1233
4367
    table->key_info=keyinfo;
1234
4368
    keyinfo->key_part=key_part_info;
1235
4369
    keyinfo->flags=HA_NOSAME;
1236
4370
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
1237
 
    keyinfo->key_length= 0;
1238
 
    keyinfo->rec_per_key= 0;
 
4371
    keyinfo->key_length=0;
 
4372
    keyinfo->rec_per_key=0;
1239
4373
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1240
4374
    keyinfo->name= (char*) "group_key";
1241
 
    Order *cur_group= group;
 
4375
    order_st *cur_group= group;
1242
4376
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1243
4377
    {
1244
4378
      Field *field=(*cur_group->item)->get_tmp_table_field();
1245
4379
      bool maybe_null=(*cur_group->item)->maybe_null;
1246
 
      key_part_info->null_bit= 0;
 
4380
      key_part_info->null_bit=0;
1247
4381
      key_part_info->field=  field;
1248
 
      key_part_info->offset= field->offset(table->getInsertRecord());
 
4382
      key_part_info->offset= field->offset(table->record[0]);
1249
4383
      key_part_info->length= (uint16_t) field->key_length();
1250
4384
      key_part_info->type=   (uint8_t) field->key_type();
1251
 
      key_part_info->key_type= 
 
4385
      key_part_info->key_type =
1252
4386
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1253
4387
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1254
4388
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1255
 
        0 : 1;
 
4389
        0 : FIELDFLAG_BINARY;
1256
4390
      if (!using_unique_constraint)
1257
4391
      {
1258
4392
        cur_group->buff=(char*) group_buff;
1261
4395
                                                     test(maybe_null),
1262
4396
                                                     field->null_ptr,
1263
4397
                                                     field->null_bit)))
1264
 
          goto err;
 
4398
          goto err; /* purecov: inspected */
1265
4399
        if (maybe_null)
1266
4400
        {
1267
4401
          /*
1273
4407
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
1274
4408
          key_part_info->null_bit=field->null_bit;
1275
4409
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
1276
 
                                              (unsigned char*) table->getInsertRecord());
 
4410
                                              (unsigned char*) table->record[0]);
1277
4411
          cur_group->buff++;                        // Pointer to field data
1278
4412
          group_buff++;                         // Skipp null flag
1279
4413
        }
1300
4434
        indexes on blobs with arbitrary length. Such indexes cannot be
1301
4435
        used for lookups.
1302
4436
      */
1303
 
      table->getMutableShare()->uniques= 1;
 
4437
      share->uniques= 1;
1304
4438
    }
1305
4439
    null_pack_length-=hidden_null_pack_length;
1306
4440
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1307
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
4441
                         (share->uniques ? test(null_pack_length) : 0));
1308
4442
    table->distinct= 1;
1309
 
    table->getMutableShare()->keys= 1;
1310
 
    if (!(key_part_info= (KeyPartInfo*)
1311
 
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
 
4443
    share->keys= 1;
 
4444
    if (!(key_part_info= (KEY_PART_INFO*)
 
4445
          alloc_root(&table->mem_root,
 
4446
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
1312
4447
      goto err;
1313
 
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KeyPartInfo));
 
4448
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
1314
4449
    table->key_info=keyinfo;
1315
4450
    keyinfo->key_part=key_part_info;
1316
4451
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
1317
4452
    keyinfo->key_length=(uint16_t) reclength;
1318
4453
    keyinfo->name= (char*) "distinct_key";
1319
4454
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1320
 
    keyinfo->rec_per_key= 0;
 
4455
    keyinfo->rec_per_key=0;
1321
4456
 
1322
4457
    /*
1323
4458
      Create an extra field to hold NULL bits so that unique indexes on
1324
4459
      blobs can distinguish NULL from 0. This extra field is not needed
1325
4460
      when we do not use UNIQUE indexes for blobs.
1326
4461
    */
1327
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
4462
    if (null_pack_length && share->uniques)
1328
4463
    {
1329
 
      key_part_info->null_bit= 0;
 
4464
      key_part_info->null_bit=0;
1330
4465
      key_part_info->offset=hidden_null_pack_length;
1331
4466
      key_part_info->length=null_pack_length;
1332
 
      table->setVariableWidth();
1333
 
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
 
4467
      key_part_info->field= new Field_varstring(table->record[0],
1334
4468
                                                (uint32_t) key_part_info->length,
1335
4469
                                                0,
1336
4470
                                                (unsigned char*) 0,
1337
4471
                                                (uint32_t) 0,
 
4472
                                                Field::NONE,
1338
4473
                                                NULL,
 
4474
                                                table->s,
1339
4475
                                                &my_charset_bin);
1340
4476
      if (!key_part_info->field)
1341
4477
        goto err;
1342
4478
      key_part_info->field->init(table);
1343
 
      key_part_info->key_type= 1; /* binary comparison */
 
4479
      key_part_info->key_type=FIELDFLAG_BINARY;
1344
4480
      key_part_info->type=    HA_KEYTYPE_BINARY;
1345
4481
      key_part_info++;
1346
4482
    }
1347
4483
    /* Create a distinct key over the columns we are going to return */
1348
 
    for (i=param->hidden_field_count, reg_field=table->getFields() + i ;
 
4484
    for (i=param->hidden_field_count, reg_field=table->field + i ;
1349
4485
         i < field_count;
1350
4486
         i++, reg_field++, key_part_info++)
1351
4487
    {
1352
 
      key_part_info->null_bit= 0;
 
4488
      key_part_info->null_bit=0;
1353
4489
      key_part_info->field=    *reg_field;
1354
 
      key_part_info->offset=   (*reg_field)->offset(table->getInsertRecord());
 
4490
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
1355
4491
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
1356
 
      /* @todo The below method of computing the key format length of the
1357
 
        key part is a copy/paste from optimizer/range.cc, and table.cc.
 
4492
      /* TODO:
 
4493
        The below method of computing the key format length of the
 
4494
        key part is a copy/paste from opt_range.cc, and table.cc.
1358
4495
        This should be factored out, e.g. as a method of Field.
1359
4496
        In addition it is not clear if any of the Field::*_length
1360
4497
        methods is supposed to compute the same length. If so, it
1373
4510
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1374
4511
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1375
4512
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1376
 
        0 : 1;
 
4513
        0 : FIELDFLAG_BINARY;
1377
4514
    }
1378
4515
  }
1379
4516
 
1380
4517
  if (session->is_fatal_error)                          // If end of memory
1381
 
    goto err;
1382
 
  table->getMutableShare()->db_record_offset= 1;
1383
 
  if (table->getShare()->db_type() == myisam_engine)
 
4518
    goto err;                                    /* purecov: inspected */
 
4519
  share->db_record_offset= 1;
 
4520
  if (share->db_type() == myisam_hton)
1384
4521
  {
1385
4522
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1386
4523
                                       &param->recinfo, select_options))
1387
4524
      goto err;
1388
4525
  }
1389
 
  assert(table->in_use);
1390
4526
  if (table->open_tmp_table())
1391
4527
    goto err;
1392
4528
 
1396
4532
 
1397
4533
err:
1398
4534
  session->mem_root= mem_root_save;
1399
 
  table= NULL;
1400
 
 
1401
 
  return NULL;
 
4535
  table->free_tmp_table(session);                    /* purecov: inspected */
 
4536
  if (temp_pool_slot != MY_BIT_NONE)
 
4537
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
4538
  return(NULL);                         /* purecov: inspected */
1402
4539
}
1403
4540
 
1404
4541
/****************************************************************************/
1405
4542
 
1406
 
void Table::column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
1407
 
                               boost::dynamic_bitset<>& write_set_arg)
1408
 
{
1409
 
  read_set= &read_set_arg;
1410
 
  write_set= &write_set_arg;
1411
 
}
1412
 
 
1413
 
 
1414
 
const boost::dynamic_bitset<> Table::use_all_columns(boost::dynamic_bitset<>& in_map)
1415
 
{
1416
 
  const boost::dynamic_bitset<> old= in_map;
1417
 
  in_map= getShare()->all_set;
 
4543
/**
 
4544
  Create a reduced Table object with properly set up Field list from a
 
4545
  list of field definitions.
 
4546
 
 
4547
    The created table doesn't have a table handler associated with
 
4548
    it, has no keys, no group/distinct, no copy_funcs array.
 
4549
    The sole purpose of this Table object is to use the power of Field
 
4550
    class to read/write data to/from table->record[0]. Then one can store
 
4551
    the record in any container (RB tree, hash, etc).
 
4552
    The table is created in Session mem_root, so are the table's fields.
 
4553
    Consequently, if you don't BLOB fields, you don't need to free it.
 
4554
 
 
4555
  @param session         connection handle
 
4556
  @param field_list  list of column definitions
 
4557
 
 
4558
  @return
 
4559
    0 if out of memory, Table object in case of success
 
4560
*/
 
4561
 
 
4562
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
 
4563
{
 
4564
  uint32_t field_count= field_list.elements;
 
4565
  uint32_t blob_count= 0;
 
4566
  Field **field;
 
4567
  Create_field *cdef;                           /* column definition */
 
4568
  uint32_t record_length= 0;
 
4569
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
4570
  uint32_t null_pack_length;              /* NULL representation array length */
 
4571
  uint32_t *blob_field;
 
4572
  unsigned char *bitmaps;
 
4573
  Table *table;
 
4574
  TABLE_SHARE *share;
 
4575
 
 
4576
  if (!multi_alloc_root(session->mem_root,
 
4577
                        &table, sizeof(*table),
 
4578
                        &share, sizeof(*share),
 
4579
                        &field, (field_count + 1) * sizeof(Field*),
 
4580
                        &blob_field, (field_count+1) *sizeof(uint32_t),
 
4581
                        &bitmaps, bitmap_buffer_size(field_count)*2,
 
4582
                        NULL))
 
4583
    return 0;
 
4584
 
 
4585
  memset(table, 0, sizeof(*table));
 
4586
  memset(share, 0, sizeof(*share));
 
4587
  table->field= field;
 
4588
  table->s= share;
 
4589
  share->blob_field= blob_field;
 
4590
  share->fields= field_count;
 
4591
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
4592
  table->setup_tmp_table_column_bitmaps(bitmaps);
 
4593
 
 
4594
  /* Create all fields and calculate the total length of record */
 
4595
  List_iterator_fast<Create_field> it(field_list);
 
4596
  while ((cdef= it++))
 
4597
  {
 
4598
    *field= make_field(share, NULL, 0, cdef->length,
 
4599
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
4600
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
4601
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
 
4602
                       cdef->unireg_check,
 
4603
                       cdef->interval, cdef->field_name);
 
4604
    if (!*field)
 
4605
      goto error;
 
4606
    (*field)->init(table);
 
4607
    record_length+= (*field)->pack_length();
 
4608
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
4609
      null_count++;
 
4610
 
 
4611
    if ((*field)->flags & BLOB_FLAG)
 
4612
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
 
4613
 
 
4614
    field++;
 
4615
  }
 
4616
  *field= NULL;                             /* mark the end of the list */
 
4617
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
4618
  share->blob_fields= blob_count;
 
4619
 
 
4620
  null_pack_length= (null_count + 7)/8;
 
4621
  share->reclength= record_length + null_pack_length;
 
4622
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
4623
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
 
4624
  if (!table->record[0])
 
4625
    goto error;
 
4626
 
 
4627
  if (null_pack_length)
 
4628
  {
 
4629
    table->null_flags= (unsigned char*) table->record[0];
 
4630
    share->null_fields= null_count;
 
4631
    share->null_bytes= null_pack_length;
 
4632
  }
 
4633
 
 
4634
  table->in_use= session;           /* field->reset() may access table->in_use */
 
4635
  {
 
4636
    /* Set up field pointers */
 
4637
    unsigned char *null_pos= table->record[0];
 
4638
    unsigned char *field_pos= null_pos + share->null_bytes;
 
4639
    uint32_t null_bit= 1;
 
4640
 
 
4641
    for (field= table->field; *field; ++field)
 
4642
    {
 
4643
      Field *cur_field= *field;
 
4644
      if ((cur_field->flags & NOT_NULL_FLAG))
 
4645
        cur_field->move_field(field_pos);
 
4646
      else
 
4647
      {
 
4648
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
4649
        null_bit<<= 1;
 
4650
        if (null_bit == (1 << 8))
 
4651
        {
 
4652
          ++null_pos;
 
4653
          null_bit= 1;
 
4654
        }
 
4655
      }
 
4656
      cur_field->reset();
 
4657
 
 
4658
      field_pos+= cur_field->pack_length();
 
4659
    }
 
4660
  }
 
4661
  return table;
 
4662
error:
 
4663
  for (field= table->field; *field; ++field)
 
4664
    delete *field;                         /* just invokes field destructor */
 
4665
  return 0;
 
4666
}
 
4667
 
 
4668
 
 
4669
bool Table::open_tmp_table()
 
4670
{
 
4671
  int error;
 
4672
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
 
4673
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
4674
  {
 
4675
    file->print_error(error,MYF(0)); /* purecov: inspected */
 
4676
    db_stat=0;
 
4677
    return(1);
 
4678
  }
 
4679
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
4680
  return(0);
 
4681
}
 
4682
 
 
4683
 
 
4684
/*
 
4685
  Create MyISAM temporary table
 
4686
 
 
4687
  SYNOPSIS
 
4688
    create_myisam_tmp_table()
 
4689
      keyinfo         Description of the index (there is always one index)
 
4690
      start_recinfo   MyISAM's column descriptions
 
4691
      recinfo INOUT   End of MyISAM's column descriptions
 
4692
      options         Option bits
 
4693
 
 
4694
  DESCRIPTION
 
4695
    Create a MyISAM temporary table according to passed description. The is
 
4696
    assumed to have one unique index or constraint.
 
4697
 
 
4698
    The passed array or MI_COLUMNDEF structures must have this form:
 
4699
 
 
4700
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
4701
         when there are many nullable columns)
 
4702
      2. Table columns
 
4703
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
4704
 
 
4705
    This function may use the free element to create hash column for unique
 
4706
    constraint.
 
4707
 
 
4708
   RETURN
 
4709
     false - OK
 
4710
     true  - Error
 
4711
*/
 
4712
 
 
4713
bool Table::create_myisam_tmp_table(KEY *keyinfo,
 
4714
                                    MI_COLUMNDEF *start_recinfo,
 
4715
                                    MI_COLUMNDEF **recinfo,
 
4716
                                    uint64_t options)
 
4717
{
 
4718
  int error;
 
4719
  MI_KEYDEF keydef;
 
4720
  MI_UNIQUEDEF uniquedef;
 
4721
  TABLE_SHARE *share= s;
 
4722
 
 
4723
  if (share->keys)
 
4724
  {                                             // Get keys for ni_create
 
4725
    bool using_unique_constraint=0;
 
4726
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
 
4727
                                            sizeof(*seg) * keyinfo->key_parts);
 
4728
    if (!seg)
 
4729
      goto err;
 
4730
 
 
4731
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
4732
    if (keyinfo->key_length >= file->max_key_length() ||
 
4733
        keyinfo->key_parts > file->max_key_parts() ||
 
4734
        share->uniques)
 
4735
    {
 
4736
      /* Can't create a key; Make a unique constraint instead of a key */
 
4737
      share->keys=    0;
 
4738
      share->uniques= 1;
 
4739
      using_unique_constraint=1;
 
4740
      memset(&uniquedef, 0, sizeof(uniquedef));
 
4741
      uniquedef.keysegs=keyinfo->key_parts;
 
4742
      uniquedef.seg=seg;
 
4743
      uniquedef.null_are_equal=1;
 
4744
 
 
4745
      /* Create extra column for hash value */
 
4746
      memset(*recinfo, 0, sizeof(**recinfo));
 
4747
      (*recinfo)->type= FIELD_CHECK;
 
4748
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
4749
      (*recinfo)++;
 
4750
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
 
4751
    }
 
4752
    else
 
4753
    {
 
4754
      /* Create an unique key */
 
4755
      memset(&keydef, 0, sizeof(keydef));
 
4756
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
4757
      keydef.keysegs=  keyinfo->key_parts;
 
4758
      keydef.seg= seg;
 
4759
    }
 
4760
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
 
4761
    {
 
4762
      Field *key_field=keyinfo->key_part[i].field;
 
4763
      seg->flag=     0;
 
4764
      seg->language= key_field->charset()->number;
 
4765
      seg->length=   keyinfo->key_part[i].length;
 
4766
      seg->start=    keyinfo->key_part[i].offset;
 
4767
      if (key_field->flags & BLOB_FLAG)
 
4768
      {
 
4769
        seg->type=
 
4770
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
 
4771
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
4772
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
4773
                                  - share->blob_ptr_size);
 
4774
        seg->flag= HA_BLOB_PART;
 
4775
        seg->length=0;                  // Whole blob in unique constraint
 
4776
      }
 
4777
      else
 
4778
      {
 
4779
        seg->type= keyinfo->key_part[i].type;
 
4780
      }
 
4781
      if (!(key_field->flags & NOT_NULL_FLAG))
 
4782
      {
 
4783
        seg->null_bit= key_field->null_bit;
 
4784
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
 
4785
        /*
 
4786
          We are using a GROUP BY on something that contains NULL
 
4787
          In this case we have to tell MyISAM that two NULL should
 
4788
          on INSERT be regarded at the same value
 
4789
        */
 
4790
        if (!using_unique_constraint)
 
4791
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
4792
      }
 
4793
    }
 
4794
  }
 
4795
  MI_CREATE_INFO create_info;
 
4796
  memset(&create_info, 0, sizeof(create_info));
 
4797
 
 
4798
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
4799
      OPTION_BIG_TABLES)
 
4800
    create_info.data_file_length= ~(uint64_t) 0;
 
4801
 
 
4802
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
 
4803
                       (uint32_t) (*recinfo-start_recinfo),
 
4804
                       start_recinfo,
 
4805
                       share->uniques, &uniquedef,
 
4806
                       &create_info,
 
4807
                       HA_CREATE_TMP_TABLE)))
 
4808
  {
 
4809
    file->print_error(error,MYF(0));    /* purecov: inspected */
 
4810
    db_stat=0;
 
4811
    goto err;
 
4812
  }
 
4813
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
 
4814
  share->db_record_offset= 1;
 
4815
  return false;
 
4816
 err:
 
4817
  return true;
 
4818
}
 
4819
 
 
4820
 
 
4821
void Table::free_tmp_table(Session *session)
 
4822
{
 
4823
  MEM_ROOT own_root= mem_root;
 
4824
  const char *save_proc_info;
 
4825
 
 
4826
  save_proc_info=session->get_proc_info();
 
4827
  session->set_proc_info("removing tmp table");
 
4828
 
 
4829
  // Release latches since this can take a long time
 
4830
  ha_release_temporary_latches(session);
 
4831
 
 
4832
  if (file)
 
4833
  {
 
4834
    if (db_stat)
 
4835
      file->ha_drop_table(s->table_name.str);
 
4836
    else
 
4837
      file->ha_delete_table(s->table_name.str);
 
4838
    delete file;
 
4839
  }
 
4840
 
 
4841
  /* free blobs */
 
4842
  for (Field **ptr= field ; *ptr ; ptr++)
 
4843
    (*ptr)->free();
 
4844
  free_io_cache(this);
 
4845
 
 
4846
  if (temp_pool_slot != MY_BIT_NONE)
 
4847
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
4848
 
 
4849
  plugin_unlock(0, s->db_plugin);
 
4850
 
 
4851
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
 
4852
  session->set_proc_info(save_proc_info);
 
4853
 
 
4854
  return;
 
4855
}
 
4856
 
 
4857
/**
 
4858
  If a HEAP table gets full, create a MyISAM table and copy all rows
 
4859
  to this.
 
4860
*/
 
4861
 
 
4862
bool create_myisam_from_heap(Session *session, Table *table,
 
4863
                             MI_COLUMNDEF *start_recinfo,
 
4864
                             MI_COLUMNDEF **recinfo,
 
4865
                             int error, bool ignore_last_dupp_key_error)
 
4866
{
 
4867
  Table new_table;
 
4868
  TABLE_SHARE share;
 
4869
  const char *save_proc_info;
 
4870
  int write_err;
 
4871
 
 
4872
  if (table->s->db_type() != heap_hton ||
 
4873
      error != HA_ERR_RECORD_FILE_FULL)
 
4874
  {
 
4875
    table->file->print_error(error,MYF(0));
 
4876
    return(1);
 
4877
  }
 
4878
 
 
4879
  // Release latches since this can take a long time
 
4880
  ha_release_temporary_latches(session);
 
4881
 
 
4882
  new_table= *table;
 
4883
  share= *table->s;
 
4884
  new_table.s= &share;
 
4885
  new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
 
4886
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
4887
                                        new_table.s->db_type())))
 
4888
    return(1);                          // End of memory
 
4889
 
 
4890
  save_proc_info=session->get_proc_info();
 
4891
  session->set_proc_info("converting HEAP to MyISAM");
 
4892
 
 
4893
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
 
4894
                                        recinfo, session->lex->select_lex.options |
 
4895
                                        session->options))
 
4896
    goto err2;
 
4897
  if (new_table.open_tmp_table())
 
4898
    goto err1;
 
4899
  if (table->file->indexes_are_disabled())
 
4900
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
4901
  table->file->ha_index_or_rnd_end();
 
4902
  table->file->ha_rnd_init(1);
 
4903
  if (table->no_rows)
 
4904
  {
 
4905
    new_table.file->extra(HA_EXTRA_NO_ROWS);
 
4906
    new_table.no_rows=1;
 
4907
  }
 
4908
 
 
4909
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
 
4910
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
 
4911
 
 
4912
  /*
 
4913
    copy all old rows from heap table to MyISAM table
 
4914
    This is the only code that uses record[1] to read/write but this
 
4915
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
 
4916
  */
 
4917
  while (!table->file->rnd_next(new_table.record[1]))
 
4918
  {
 
4919
    write_err= new_table.file->ha_write_row(new_table.record[1]);
 
4920
    if (write_err)
 
4921
      goto err;
 
4922
  }
 
4923
  /* copy row that filled HEAP table */
 
4924
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
 
4925
  {
 
4926
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
4927
        !ignore_last_dupp_key_error)
 
4928
      goto err;
 
4929
  }
 
4930
 
 
4931
  /* remove heap table and change to use myisam table */
 
4932
  (void) table->file->ha_rnd_end();
 
4933
  (void) table->file->close();                  // This deletes the table !
 
4934
  delete table->file;
 
4935
  table->file=0;
 
4936
  plugin_unlock(0, table->s->db_plugin);
 
4937
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
 
4938
  new_table.s= table->s;                       // Keep old share
 
4939
  *table= new_table;
 
4940
  *table->s= share;
 
4941
 
 
4942
  table->file->change_table_ptr(table, table->s);
 
4943
  table->use_all_columns();
 
4944
  if (save_proc_info)
 
4945
  {
 
4946
    const char *new_proc_info=
 
4947
      (!strcmp(save_proc_info,"Copying to tmp table") ?
 
4948
      "Copying to tmp table on disk" : save_proc_info);
 
4949
    session->set_proc_info(new_proc_info);
 
4950
  }
 
4951
  return(0);
 
4952
 
 
4953
 err:
 
4954
  table->file->print_error(write_err, MYF(0));
 
4955
  (void) table->file->ha_rnd_end();
 
4956
  (void) new_table.file->close();
 
4957
 err1:
 
4958
  new_table.file->ha_delete_table(new_table.s->table_name.str);
 
4959
 err2:
 
4960
  delete new_table.file;
 
4961
  session->set_proc_info(save_proc_info);
 
4962
  table->mem_root= new_table.mem_root;
 
4963
  return(1);
 
4964
}
 
4965
 
 
4966
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
 
4967
{
 
4968
  my_bitmap_map *old= bitmap->bitmap;
 
4969
  bitmap->bitmap= s->all_set.bitmap;
1418
4970
  return old;
1419
4971
}
1420
4972
 
1421
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
4973
void Table::restore_column_map(my_bitmap_map *old)
1422
4974
{
1423
 
  for (boost::dynamic_bitset<>::size_type i= 0; i < old.size(); i++)
1424
 
  {
1425
 
    if (old.test(i))
1426
 
    {
1427
 
      read_set->set(i);
1428
 
    }
1429
 
    else
1430
 
    {
1431
 
      read_set->reset(i);
1432
 
    }
1433
 
  }
 
4975
  read_set->bitmap= old;
1434
4976
}
1435
4977
 
1436
4978
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1437
4979
{
1438
4980
  uint32_t min_length= UINT32_MAX;
1439
4981
  uint32_t best= MAX_KEY;
1440
 
  if (usable_keys->any())
 
4982
  if (!usable_keys->is_clear_all())
1441
4983
  {
1442
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
4984
    for (uint32_t nr=0; nr < s->keys ; nr++)
1443
4985
    {
1444
 
      if (usable_keys->test(nr))
 
4986
      if (usable_keys->is_set(nr))
1445
4987
      {
1446
4988
        if (key_info[nr].key_length < min_length)
1447
4989
        {
1466
5008
{
1467
5009
  for (; *ptr ; ptr++)
1468
5010
  {
1469
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
5011
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1470
5012
      return true;
1471
5013
  }
1472
5014
  return false;
1473
5015
}
1474
5016
 
1475
 
/**
1476
 
   True if the table's input and output record buffers are comparable using
1477
 
   compare_records(TABLE*).
1478
 
 */
1479
 
bool Table::records_are_comparable()
1480
 
{
1481
 
  return ((getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) == 0) ||
1482
 
          write_set->is_subset_of(*read_set));
1483
 
}
1484
 
 
1485
 
/**
1486
 
   Compares the input and outbut record buffers of the table to see if a row
1487
 
   has changed. The algorithm iterates over updated columns and if they are
1488
 
   nullable compares NULL bits in the buffer before comparing actual
1489
 
   data. Special care must be taken to compare only the relevant NULL bits and
1490
 
   mask out all others as they may be undefined. The storage engine will not
1491
 
   and should not touch them.
1492
 
 
1493
 
   @param table The table to evaluate.
1494
 
 
1495
 
   @return true if row has changed.
1496
 
   @return false otherwise.
1497
 
*/
1498
 
bool Table::compare_records()
1499
 
{
1500
 
  if (getEngine()->check_flag(HTON_BIT_PARTIAL_COLUMN_READ) != 0)
1501
 
  {
1502
 
    /*
1503
 
      Storage engine may not have read all columns of the record.  Fields
1504
 
      (including NULL bits) not in the write_set may not have been read and
1505
 
      can therefore not be compared.
1506
 
    */
1507
 
    for (Field **ptr= this->field ; *ptr != NULL; ptr++)
1508
 
    {
1509
 
      Field *f= *ptr;
1510
 
      if (write_set->test(f->position()))
1511
 
      {
1512
 
        if (f->real_maybe_null())
1513
 
        {
1514
 
          unsigned char null_byte_index= f->null_ptr - record[0];
1515
 
 
1516
 
          if (((record[0][null_byte_index]) & f->null_bit) !=
1517
 
              ((record[1][null_byte_index]) & f->null_bit))
1518
 
            return true;
1519
 
        }
1520
 
        if (f->cmp_binary_offset(getShare()->rec_buff_length))
1521
 
          return true;
1522
 
      }
1523
 
    }
1524
 
    return false;
1525
 
  }
1526
 
 
1527
 
  /*
1528
 
    The storage engine has read all columns, so it's safe to compare all bits
1529
 
    including those not in the write_set. This is cheaper than the
1530
 
    field-by-field comparison done above.
1531
 
  */
1532
 
  if (not getShare()->blob_fields + getShare()->hasVariableWidth())
1533
 
    // Fixed-size record: do bitwise comparison of the records
1534
 
    return memcmp(this->getInsertRecord(), this->getUpdateRecord(), (size_t) getShare()->getRecordLength());
1535
 
 
 
5017
/* Return false if row hasn't changed */
 
5018
 
 
5019
bool Table::compare_record()
 
5020
{
 
5021
  if (s->blob_fields + s->varchar_fields == 0)
 
5022
    return cmp_record(this, record[1]);
1536
5023
  /* Compare null bits */
1537
 
  if (memcmp(null_flags, null_flags + getShare()->rec_buff_length, getShare()->null_bytes))
1538
 
    return true; /* Diff in NULL value */
1539
 
 
 
5024
  if (memcmp(null_flags,
 
5025
             null_flags + s->rec_buff_length,
 
5026
             s->null_bytes))
 
5027
    return true;                                // Diff in NULL value
1540
5028
  /* Compare updated fields */
1541
5029
  for (Field **ptr= field ; *ptr ; ptr++)
1542
5030
  {
1543
 
    if (isWriteSet((*ptr)->position()) &&
1544
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
5031
    if (bitmap_is_set(write_set, (*ptr)->field_index) &&
 
5032
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1545
5033
      return true;
1546
5034
  }
1547
5035
  return false;
1548
5036
}
1549
5037
 
1550
 
/*
1551
 
 * Store a record from previous record into next
1552
 
 *
1553
 
 */
1554
 
void Table::storeRecord()
1555
 
{
1556
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
1557
 
}
1558
 
 
1559
 
/*
1560
 
 * Store a record as an insert
1561
 
 *
1562
 
 */
1563
 
void Table::storeRecordAsInsert()
1564
 
{
1565
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1566
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
1567
 
}
1568
 
 
1569
 
/*
1570
 
 * Store a record with default values
1571
 
 *
1572
 
 */
1573
 
void Table::storeRecordAsDefault()
1574
 
{
1575
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
1576
 
}
1577
 
 
1578
 
/*
1579
 
 * Restore a record from previous record into next
1580
 
 *
1581
 
 */
1582
 
void Table::restoreRecord()
1583
 
{
1584
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
1585
 
}
1586
 
 
1587
 
/*
1588
 
 * Restore a record with default values
1589
 
 *
1590
 
 */
1591
 
void Table::restoreRecordAsDefault()
1592
 
{
1593
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
1594
 
}
1595
 
 
1596
 
/*
1597
 
 * Empty a record
1598
 
 *
1599
 
 */
1600
 
void Table::emptyRecord()
1601
 
{
1602
 
  restoreRecordAsDefault();
1603
 
  memset(null_flags, 255, getShare()->null_bytes);
1604
 
}
1605
 
 
1606
 
Table::Table() : 
1607
 
  field(NULL),
1608
 
  cursor(NULL),
1609
 
  next(NULL),
1610
 
  prev(NULL),
1611
 
  read_set(NULL),
1612
 
  write_set(NULL),
1613
 
  tablenr(0),
1614
 
  db_stat(0),
1615
 
  def_read_set(),
1616
 
  def_write_set(),
1617
 
  tmp_set(),
1618
 
  in_use(NULL),
1619
 
  key_info(NULL),
1620
 
  next_number_field(NULL),
1621
 
  found_next_number_field(NULL),
1622
 
  timestamp_field(NULL),
1623
 
  pos_in_table_list(NULL),
1624
 
  group(NULL),
1625
 
  null_flags(NULL),
1626
 
  lock_position(0),
1627
 
  lock_data_start(0),
1628
 
  lock_count(0),
1629
 
  used_fields(0),
1630
 
  status(0),
1631
 
  derived_select_number(0),
1632
 
  current_lock(F_UNLCK),
1633
 
  copy_blobs(false),
1634
 
  maybe_null(false),
1635
 
  null_row(false),
1636
 
  force_index(false),
1637
 
  distinct(false),
1638
 
  const_table(false),
1639
 
  no_rows(false),
1640
 
  key_read(false),
1641
 
  no_keyread(false),
1642
 
  open_placeholder(false),
1643
 
  locked_by_name(false),
1644
 
  no_cache(false),
1645
 
  auto_increment_field_not_null(false),
1646
 
  alias_name_used(false),
1647
 
  query_id(0),
1648
 
  quick_condition_rows(0),
1649
 
  timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
1650
 
  map(0)
1651
 
{
1652
 
  record[0]= (unsigned char *) 0;
1653
 
  record[1]= (unsigned char *) 0;
1654
 
 
1655
 
  reginfo.reset();
1656
 
  covering_keys.reset();
1657
 
  quick_keys.reset();
1658
 
  merge_keys.reset();
1659
 
 
1660
 
  keys_in_use_for_query.reset();
1661
 
  keys_in_use_for_group_by.reset();
1662
 
  keys_in_use_for_order_by.reset();
1663
 
 
1664
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
1665
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
1666
 
 
1667
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
1668
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1669
 
}
 
5038
 
 
5039
 
 
5040
 
1670
5041
 
1671
5042
/*****************************************************************************
1672
5043
  The different ways to read a record
1673
5044
  Returns -1 if row was not found, 0 if row was found and 1 on errors
1674
5045
*****************************************************************************/
1675
5046
 
1676
 
/** Help function when we get some an error from the table Cursor. */
 
5047
/** Help function when we get some an error from the table handler. */
1677
5048
 
1678
5049
int Table::report_error(int error)
1679
5050
{
1688
5059
  */
1689
5060
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1690
5061
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
1691
 
                  error, getShare()->getPath());
1692
 
  print_error(error, MYF(0));
 
5062
                    error, s->path.str);
 
5063
  file->print_error(error,MYF(0));
1693
5064
 
1694
5065
  return 1;
1695
5066
}
1696
5067
 
1697
5068
 
1698
 
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
1699
 
{
1700
 
  used_fields= 0;
1701
 
  const_table= 0;
1702
 
  null_row= 0;
1703
 
  status= STATUS_NO_RECORD;
1704
 
  maybe_null= table_list->outer_join;
1705
 
  TableList *embedding= table_list->getEmbedding();
1706
 
  while (!maybe_null && embedding)
1707
 
  {
1708
 
    maybe_null= embedding->outer_join;
1709
 
    embedding= embedding->getEmbedding();
1710
 
  }
1711
 
  tablenr= table_number;
1712
 
  map= (table_map) 1 << table_number;
1713
 
  force_index= table_list->force_index;
1714
 
  covering_keys= getShare()->keys_for_keyread;
1715
 
  merge_keys.reset();
1716
 
}
1717
 
 
1718
 
 
1719
 
bool Table::fill_item_list(List<Item> *item_list) const
1720
 
{
1721
 
  /*
1722
 
    All Item_field's created using a direct pointer to a field
1723
 
    are fixed in Item_field constructor.
1724
 
  */
1725
 
  for (Field **ptr= field; *ptr; ptr++)
1726
 
  {
1727
 
    Item_field *item= new Item_field(*ptr);
1728
 
    if (!item || item_list->push_back(item))
1729
 
      return true;
1730
 
  }
1731
 
  return false;
1732
 
}
1733
 
 
1734
 
 
1735
 
void Table::filesort_free_buffers(bool full)
1736
 
{
1737
 
  if (sort.record_pointers)
1738
 
  {
1739
 
    free((unsigned char*) sort.record_pointers);
1740
 
    sort.record_pointers=0;
1741
 
  }
1742
 
  if (full)
1743
 
  {
1744
 
    if (sort.sort_keys )
1745
 
    {
1746
 
      if ((unsigned char*) sort.sort_keys)
1747
 
        free((unsigned char*) sort.sort_keys);
1748
 
      sort.sort_keys= 0;
1749
 
    }
1750
 
    if (sort.buffpek)
1751
 
    {
1752
 
      if ((unsigned char*) sort.buffpek)
1753
 
        free((unsigned char*) sort.buffpek);
1754
 
      sort.buffpek= 0;
1755
 
      sort.buffpek_len= 0;
1756
 
    }
1757
 
  }
1758
 
 
1759
 
  if (sort.addon_buf)
1760
 
  {
1761
 
    free((char *) sort.addon_buf);
1762
 
    free((char *) sort.addon_field);
1763
 
    sort.addon_buf=0;
1764
 
    sort.addon_field=0;
1765
 
  }
1766
 
}
1767
 
 
1768
 
} /* namespace drizzled */
 
5069
/*
 
5070
  Calculate data for each virtual field marked for write in the
 
5071
  corresponding column map.
 
5072
 
 
5073
  SYNOPSIS
 
5074
    update_virtual_fields_marked_for_write()
 
5075
    table                  The Table object
 
5076
    ignore_stored          Indication whether physically stored virtual
 
5077
                           fields do not need updating.
 
5078
                           This value is false when during INSERT and UPDATE
 
5079
                           and true in all other cases.
 
5080
 
 
5081
  RETURN
 
5082
    0  - Success
 
5083
    >0 - Error occurred during the generation/calculation of a virtual field value
 
5084
 
 
5085
*/
 
5086
 
 
5087
int update_virtual_fields_marked_for_write(Table *table,
 
5088
                                           bool ignore_stored)
 
5089
{
 
5090
  Field **vfield_ptr, *vfield;
 
5091
  int error= 0;
 
5092
  if ((not table) or (not table->vfield))
 
5093
    return(0);
 
5094
 
 
5095
  /* Iterate over virtual fields in the table */
 
5096
  for (vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
 
5097
  {
 
5098
    vfield= (*vfield_ptr);
 
5099
    assert(vfield->vcol_info && vfield->vcol_info->expr_item);
 
5100
    /*
 
5101
      Only update those fields that are marked in the write_set bitmap
 
5102
      and not _already_ physically stored in the database.
 
5103
    */
 
5104
    if (bitmap_is_set(table->write_set, vfield->field_index) &&
 
5105
        (not (ignore_stored && vfield->is_stored))
 
5106
       )
 
5107
    {
 
5108
      /* Generate the actual value of the virtual fields */
 
5109
      error= vfield->vcol_info->expr_item->save_in_field(vfield, 0);
 
5110
    }
 
5111
  }
 
5112
  return(0);
 
5113
}
 
5114
 
 
5115
 
 
5116
void setup_table_map(Table *table, TableList *table_list, uint32_t tablenr)
 
5117
{
 
5118
  table->used_fields= 0;
 
5119
  table->const_table= 0;
 
5120
  table->null_row= 0;
 
5121
  table->status= STATUS_NO_RECORD;
 
5122
  table->maybe_null= table_list->outer_join;
 
5123
  TableList *embedding= table_list->embedding;
 
5124
  while (!table->maybe_null && embedding)
 
5125
  {
 
5126
    table->maybe_null= embedding->outer_join;
 
5127
    embedding= embedding->embedding;
 
5128
  }
 
5129
  table->tablenr= tablenr;
 
5130
  table->map= (table_map) 1 << tablenr;
 
5131
  table->force_index= table_list->force_index;
 
5132
  table->covering_keys= table->s->keys_for_keyread;
 
5133
  table->merge_keys.clear_all();
 
5134
}
 
5135
 
 
5136
 
 
5137
/*****************************************************************************
 
5138
** Instansiate templates
 
5139
*****************************************************************************/
 
5140
 
 
5141
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
5142
template class List<String>;
 
5143
template class List_iterator<String>;
 
5144
#endif