~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Monty Taylor
  • Date: 2009-03-02 23:14:32 UTC
  • mto: This revision was merged to the branch mainline in revision 910.
  • Revision ID: mordred@inaugust.com-20090302231432-i35xehp7uzo6hjjw
Updated build system to use new version numbering. Just remember to run ./config/autorun.sh before running make distcheck for release and all should be peachy.

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