~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Monty Taylor
  • Date: 2009-03-20 06:30:59 UTC
  • mfrom: (942.1.17 plugin-registration)
  • mto: This revision was merged to the branch mainline in revision 958.
  • Revision ID: mordred@inaugust.com-20090320063059-lr9hqvw15stxxgn3
Merged plugin registration branch.

Show diffs side-by-side

added added

removed removed

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