~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Stewart Smith
  • Date: 2009-05-15 06:57:12 UTC
  • mto: (991.1.5 for-brian)
  • mto: This revision was merged to the branch mainline in revision 1022.
  • Revision ID: stewart@flamingspork.com-20090515065712-bmionylacjmexmmm
Make sql_mode=NO_AUTO_VALUE_ON_ZERO default for Drizzle.

Also fix DEFAULT keyword handling for auto-increment so that it defaults to
NULL and not 0 so that the following is valid and generates two auto-inc
values:

create table t1 (a int auto_increment primary key)
insert into t1 (a) values (default);
insert into t1 (a) values (default);

Important to note that 0 is no longer magic. So this gives you duplicate
primary key error:

insert into t1 (a) values(0);
insert into t1 (a) values(0);

as you've inserted the explicit value of 0 twice.

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>
36
28
#include <drizzled/table_list.h>
37
29
#include <drizzled/session.h>
38
30
#include <drizzled/sql_base.h>
39
 
#include <drizzled/sql_select.h>
40
31
#include <drizzled/field/blob.h>
41
32
#include <drizzled/field/varstring.h>
42
33
#include <drizzled/field/double.h>
 
34
#include <string>
 
35
#include <bitset>
 
36
 
43
37
#include <drizzled/unireg.h>
44
38
#include <drizzled/message/table.pb.h>
45
 
#include "drizzled/sql_table.h"
46
 
#include "drizzled/charset.h"
47
 
#include "drizzled/internal/m_string.h"
48
 
#include "plugin/myisam/myisam.h"
49
 
#include "drizzled/plugin/storage_engine.h"
50
39
 
51
40
#include <drizzled/item/string.h>
52
41
#include <drizzled/item/int.h>
53
42
#include <drizzled/item/decimal.h>
54
43
#include <drizzled/item/float.h>
55
44
#include <drizzled/item/null.h>
56
 
#include <drizzled/temporal.h>
57
 
 
58
 
#include <drizzled/refresh_version.h>
59
 
 
60
 
#include "drizzled/table/singular.h"
61
 
 
62
 
#include "drizzled/table_proto.h"
 
45
 
63
46
 
64
47
using namespace std;
65
48
 
66
 
namespace drizzled
67
 
{
68
 
 
69
 
extern plugin::StorageEngine *heap_engine;
70
 
extern plugin::StorageEngine *myisam_engine;
71
 
 
72
 
/* Functions defined in this cursor */
 
49
/* Keyword for parsing virtual column functions */
 
50
LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
 
51
 
 
52
/* Functions defined in this file */
 
53
 
 
54
void open_table_error(TableShare *share, int error, int db_errno,
 
55
                      myf errortype, int errarg);
 
56
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
 
57
                              uint32_t types, char **names);
73
58
 
74
59
/*************************************************************************/
75
60
 
76
 
// @note this should all be the destructor
77
 
int Table::delete_table(bool free_share)
78
 
{
79
 
  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 TableShare 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
TableShare *alloc_table_share(TableList *table_list, char *key,
 
131
                               uint32_t key_length)
 
132
{
 
133
  MEM_ROOT mem_root;
 
134
  TableShare *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
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
 
162
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
 
163
    pthread_cond_init(&share->cond, NULL);
 
164
  }
 
165
  return(share);
 
166
}
 
167
 
 
168
 
 
169
enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
 
170
{
 
171
  enum_field_types field_type;
 
172
 
 
173
  switch(proto_field_type)
 
174
  {
 
175
  case drizzled::message::Table::Field::TINYINT:
 
176
    field_type= DRIZZLE_TYPE_TINY;
 
177
    break;
 
178
  case drizzled::message::Table::Field::INTEGER:
 
179
    field_type= DRIZZLE_TYPE_LONG;
 
180
    break;
 
181
  case drizzled::message::Table::Field::DOUBLE:
 
182
    field_type= DRIZZLE_TYPE_DOUBLE;
 
183
    break;
 
184
  case drizzled::message::Table::Field::TIMESTAMP:
 
185
    field_type= DRIZZLE_TYPE_TIMESTAMP;
 
186
    break;
 
187
  case drizzled::message::Table::Field::BIGINT:
 
188
    field_type= DRIZZLE_TYPE_LONGLONG;
 
189
    break;
 
190
  case drizzled::message::Table::Field::DATETIME:
 
191
    field_type= DRIZZLE_TYPE_DATETIME;
 
192
    break;
 
193
  case drizzled::message::Table::Field::DATE:
 
194
    field_type= DRIZZLE_TYPE_DATE;
 
195
    break;
 
196
  case drizzled::message::Table::Field::VARCHAR:
 
197
    field_type= DRIZZLE_TYPE_VARCHAR;
 
198
    break;
 
199
  case drizzled::message::Table::Field::DECIMAL:
 
200
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
 
201
    break;
 
202
  case drizzled::message::Table::Field::ENUM:
 
203
    field_type= DRIZZLE_TYPE_ENUM;
 
204
    break;
 
205
  case drizzled::message::Table::Field::BLOB:
 
206
    field_type= DRIZZLE_TYPE_BLOB;
 
207
    break;
 
208
  default:
 
209
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
 
210
    assert(1);
 
211
  }
 
212
 
 
213
  return field_type;
 
214
}
 
215
 
 
216
Item * default_value_item(enum_field_types field_type,
 
217
                          const CHARSET_INFO *charset,
 
218
                          bool default_null, const string *default_value,
 
219
                          const string *default_bin_value)
 
220
{
 
221
  Item *default_item= NULL;
 
222
  int error= 0;
 
223
 
 
224
  if(default_null)
 
225
  {
 
226
    return new Item_null();
 
227
  }
 
228
 
 
229
  switch(field_type)
 
230
  {
 
231
  case DRIZZLE_TYPE_TINY:
 
232
  case DRIZZLE_TYPE_LONG:
 
233
  case DRIZZLE_TYPE_LONGLONG:
 
234
    default_item= new Item_int(default_value->c_str(),
 
235
                               (int64_t) my_strtoll10(default_value->c_str(),
 
236
                                                      NULL,
 
237
                                                      &error),
 
238
                               default_value->length());
 
239
    break;
 
240
  case DRIZZLE_TYPE_DOUBLE:
 
241
    default_item= new Item_float(default_value->c_str(),
 
242
                                 default_value->length());
 
243
    break;
 
244
  case DRIZZLE_TYPE_NULL:
 
245
    assert(false);
 
246
  case DRIZZLE_TYPE_TIMESTAMP:
 
247
  case DRIZZLE_TYPE_DATETIME:
 
248
  case DRIZZLE_TYPE_DATE:
 
249
    if (default_value->compare("NOW()") == 0)
 
250
      break;
 
251
  case DRIZZLE_TYPE_ENUM:
 
252
    default_item= new Item_string(default_value->c_str(),
 
253
                                  default_value->length(),
 
254
                                  system_charset_info);
 
255
    break;
 
256
  case DRIZZLE_TYPE_VARCHAR:
 
257
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
 
258
    if(charset==&my_charset_bin)
 
259
    {
 
260
      default_item= new Item_string(default_bin_value->c_str(),
 
261
                                    default_bin_value->length(),
 
262
                                    &my_charset_bin);
 
263
    }
 
264
    else
 
265
    {
 
266
      default_item= new Item_string(default_value->c_str(),
 
267
                                    default_value->length(),
 
268
                                    system_charset_info);
 
269
    }
 
270
    break;
 
271
  case DRIZZLE_TYPE_NEWDECIMAL:
 
272
    default_item= new Item_decimal(default_value->c_str(),
 
273
                                   default_value->length(),
 
274
                                   system_charset_info);
 
275
    break;
 
276
  }
 
277
 
 
278
  return default_item;
 
279
}
 
280
 
 
281
int parse_table_proto(Session *session, drizzled::message::Table &table, TableShare *share)
 
282
{
 
283
  int error= 0;
 
284
  handler *handler_file= NULL;
 
285
 
 
286
  {
 
287
    LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
 
288
                              strlen(table.engine().name().c_str()) };
 
289
    share->storage_engine= ha_resolve_by_name(session, &engine_name);
 
290
  }
 
291
 
 
292
  share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
 
293
 
 
294
  drizzled::message::Table::TableOptions table_options;
 
295
 
 
296
  if(table.has_options())
 
297
    table_options= table.options();
 
298
 
 
299
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
 
300
 
 
301
  if(table_options.has_pack_keys())
 
302
  {
 
303
    if(table_options.pack_keys())
 
304
      db_create_options|= HA_OPTION_PACK_KEYS;
 
305
    else
 
306
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
 
307
  }
 
308
 
 
309
  if(table_options.pack_record())
 
310
    db_create_options|= HA_OPTION_PACK_RECORD;
 
311
 
 
312
  if(table_options.has_checksum())
 
313
  {
 
314
    if(table_options.checksum())
 
315
      db_create_options|= HA_OPTION_CHECKSUM;
 
316
    else
 
317
      db_create_options|= HA_OPTION_NO_CHECKSUM;
 
318
  }
 
319
 
 
320
  if(table_options.has_delay_key_write())
 
321
  {
 
322
    if(table_options.delay_key_write())
 
323
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
 
324
    else
 
325
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
 
326
  }
 
327
 
 
328
  /* db_create_options was stored as 2 bytes in FRM
 
329
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
 
330
   */
 
331
  share->db_create_options= (db_create_options & 0x0000FFFF);
 
332
  share->db_options_in_use= share->db_create_options;
 
333
 
 
334
 
 
335
  share->avg_row_length= table_options.has_avg_row_length() ?
 
336
    table_options.avg_row_length() : 0;
 
337
 
 
338
  share->page_checksum= table_options.has_page_checksum() ?
 
339
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
 
340
    : HA_CHOICE_UNDEF;
 
341
 
 
342
  share->row_type= table_options.has_row_type() ?
 
343
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
 
344
 
 
345
  share->block_size= table_options.has_block_size() ?
 
346
    table_options.block_size() : 0;
 
347
 
 
348
  share->table_charset= get_charset(table_options.has_collation_id()?
 
349
                                    table_options.collation_id() : 0);
 
350
 
 
351
  if (!share->table_charset)
 
352
  {
 
353
    /* unknown charset in head[38] or pre-3.23 frm */
 
354
    if (use_mb(default_charset_info))
 
355
    {
 
356
      /* Warn that we may be changing the size of character columns */
 
357
      errmsg_printf(ERRMSG_LVL_WARN,
 
358
                    _("'%s' had no or invalid character set, "
 
359
                      "and default character set is multi-byte, "
 
360
                      "so character column sizes may have changed"),
 
361
                    share->path.str);
 
362
    }
 
363
    share->table_charset= default_charset_info;
 
364
  }
 
365
 
 
366
  share->db_record_offset= 1;
 
367
 
 
368
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
 
369
 
 
370
  share->db_low_byte_first= true;
 
371
 
 
372
  share->max_rows= table_options.has_max_rows() ?
 
373
    table_options.max_rows() : 0;
 
374
 
 
375
  share->min_rows= table_options.has_min_rows() ?
 
376
    table_options.min_rows() : 0;
 
377
 
 
378
  share->keys= table.indexes_size();
 
379
 
 
380
  share->key_parts= 0;
 
381
  for(int indx= 0; indx < table.indexes_size(); indx++)
 
382
    share->key_parts+= table.indexes(indx).index_part_size();
 
383
 
 
384
  share->key_info= (KEY*) alloc_root(&share->mem_root,
 
385
                                     table.indexes_size() * sizeof(KEY)
 
386
                                     +share->key_parts*sizeof(KEY_PART_INFO));
 
387
 
 
388
  KEY_PART_INFO *key_part;
 
389
 
 
390
  key_part= reinterpret_cast<KEY_PART_INFO*>
 
391
    (share->key_info+table.indexes_size());
 
392
 
 
393
 
 
394
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
395
                                            sizeof(ulong*)*share->key_parts);
 
396
 
 
397
  share->keynames.count= table.indexes_size();
 
398
  share->keynames.name= NULL;
 
399
  share->keynames.type_names= (const char**)
 
400
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
 
401
 
 
402
  share->keynames.type_lengths= (unsigned int*)
 
403
    alloc_root(&share->mem_root,
 
404
               sizeof(unsigned int) * (table.indexes_size()+1));
 
405
 
 
406
  share->keynames.type_names[share->keynames.count]= NULL;
 
407
  share->keynames.type_lengths[share->keynames.count]= 0;
 
408
 
 
409
  KEY* keyinfo= share->key_info;
 
410
  for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
 
411
  {
 
412
    drizzled::message::Table::Index indx= table.indexes(keynr);
 
413
 
 
414
    keyinfo->table= 0;
 
415
    keyinfo->flags= 0;
 
416
 
 
417
    if(indx.is_unique())
 
418
      keyinfo->flags|= HA_NOSAME;
 
419
 
 
420
    if(indx.has_options())
 
421
    {
 
422
      drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
 
423
      if(indx_options.pack_key())
 
424
        keyinfo->flags|= HA_PACK_KEY;
 
425
 
 
426
      if(indx_options.var_length_key())
 
427
        keyinfo->flags|= HA_VAR_LENGTH_PART;
 
428
 
 
429
      if(indx_options.null_part_key())
 
430
        keyinfo->flags|= HA_NULL_PART_KEY;
 
431
 
 
432
      if(indx_options.binary_pack_key())
 
433
        keyinfo->flags|= HA_BINARY_PACK_KEY;
 
434
 
 
435
      if(indx_options.has_partial_segments())
 
436
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
 
437
 
 
438
      if(indx_options.auto_generated_key())
 
439
        keyinfo->flags|= HA_GENERATED_KEY;
 
440
 
 
441
      if(indx_options.has_key_block_size())
 
442
      {
 
443
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
 
444
        keyinfo->block_size= indx_options.key_block_size();
 
445
      }
 
446
      else
 
447
      {
 
448
        keyinfo->block_size= 0;
 
449
      }
 
450
 
 
451
    }
 
452
 
 
453
    switch(indx.type())
 
454
    {
 
455
    case drizzled::message::Table::Index::UNKNOWN_INDEX:
 
456
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
457
      break;
 
458
    case drizzled::message::Table::Index::BTREE:
 
459
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
 
460
      break;
 
461
    case drizzled::message::Table::Index::RTREE:
 
462
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
 
463
      break;
 
464
    case drizzled::message::Table::Index::HASH:
 
465
      keyinfo->algorithm= HA_KEY_ALG_HASH;
 
466
      break;
 
467
    case drizzled::message::Table::Index::FULLTEXT:
 
468
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
 
469
 
 
470
    default:
 
471
      /* TODO: suitable warning ? */
 
472
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
 
473
      break;
 
474
    }
 
475
 
 
476
    keyinfo->key_length= indx.key_length();
 
477
 
 
478
    keyinfo->key_parts= indx.index_part_size();
 
479
 
 
480
    keyinfo->key_part= key_part;
 
481
    keyinfo->rec_per_key= rec_per_key;
 
482
 
 
483
    for(unsigned int partnr= 0;
 
484
        partnr < keyinfo->key_parts;
 
485
        partnr++, key_part++)
 
486
    {
 
487
      drizzled::message::Table::Index::IndexPart part;
 
488
      part= indx.index_part(partnr);
 
489
 
 
490
      *rec_per_key++=0;
 
491
 
 
492
      key_part->field= NULL;
 
493
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
 
494
      key_part->null_bit= 0;
 
495
      /* key_part->null_offset is only set if null_bit (see later) */
 
496
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
 
497
      /* key_part->type ???? */
 
498
      key_part->key_part_flag= 0;
 
499
      if(part.has_in_reverse_order())
 
500
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
 
501
 
 
502
      key_part->length= part.compare_length();
 
503
 
 
504
      key_part->store_length= key_part->length;
 
505
 
 
506
      /* key_part->offset is set later */
 
507
      key_part->key_type= part.key_type();
 
508
 
 
509
    }
 
510
 
 
511
    if(!indx.has_comment())
 
512
    {
 
513
      keyinfo->comment.length= 0;
 
514
      keyinfo->comment.str= NULL;
 
515
    }
 
516
    else
 
517
    {
 
518
      keyinfo->flags|= HA_USES_COMMENT;
 
519
      keyinfo->comment.length= indx.comment().length();
 
520
      keyinfo->comment.str= strmake_root(&share->mem_root,
 
521
                                         indx.comment().c_str(),
 
522
                                         keyinfo->comment.length);
 
523
    }
 
524
 
 
525
    keyinfo->name= strmake_root(&share->mem_root,
 
526
                                indx.name().c_str(),
 
527
                                indx.name().length());
 
528
 
 
529
    share->keynames.type_names[keynr]= keyinfo->name;
 
530
    share->keynames.type_lengths[keynr]= indx.name().length();
 
531
  }
 
532
 
 
533
  share->keys_for_keyread.reset();
 
534
  set_prefix(share->keys_in_use, share->keys);
 
535
 
 
536
  if(table_options.has_connect_string())
 
537
  {
 
538
    size_t len= table_options.connect_string().length();
 
539
    const char* str= table_options.connect_string().c_str();
 
540
 
 
541
    share->connect_string.length= len;
 
542
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
 
543
  }
 
544
 
 
545
  if(table_options.has_comment())
 
546
  {
 
547
    size_t len= table_options.comment().length();
 
548
    const char* str= table_options.comment().c_str();
 
549
 
 
550
    share->comment.length= len;
 
551
    share->comment.str= strmake_root(&share->mem_root, str, len);
 
552
  }
 
553
 
 
554
  share->key_block_size= table_options.has_key_block_size() ?
 
555
    table_options.key_block_size() : 0;
 
556
 
 
557
  share->fields= table.field_size();
 
558
  share->vfields= 0;
 
559
 
 
560
  share->field= (Field**) alloc_root(&share->mem_root,
 
561
                                     ((share->fields+1) * sizeof(Field*)));
 
562
  share->field[share->fields]= NULL;
 
563
 
 
564
  uint32_t null_fields= 0;
 
565
  share->reclength= 0;
 
566
 
 
567
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
 
568
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
 
569
 
 
570
  assert(field_offsets && field_pack_length); // TODO: fixme
 
571
 
 
572
  uint32_t interval_count= 0;
 
573
  uint32_t interval_parts= 0;
 
574
 
 
575
  uint32_t stored_columns_reclength= 0;
 
576
 
 
577
  for (unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
578
  {
 
579
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
580
    if(pfield.has_constraints() && pfield.constraints().is_nullable())
 
581
      null_fields++;
 
582
 
 
583
    bool field_is_stored= true;
 
584
 
 
585
    enum_field_types drizzle_field_type=
 
586
      proto_field_type_to_drizzle_type(pfield.type());
 
587
 
 
588
    field_offsets[fieldnr]= stored_columns_reclength;
 
589
 
 
590
    /* the below switch is very similar to
 
591
       Create_field::create_length_to_internal_length in field.cc
 
592
       (which should one day be replace by just this code)
 
593
    */
 
594
    switch(drizzle_field_type)
 
595
    {
 
596
    case DRIZZLE_TYPE_BLOB:
 
597
    case DRIZZLE_TYPE_VARCHAR:
 
598
      {
 
599
        drizzled::message::Table::Field::StringFieldOptions field_options=
 
600
          pfield.string_options();
 
601
 
 
602
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
 
603
                                            field_options.collation_id() : 0);
 
604
 
 
605
        if (!cs)
 
606
          cs= default_charset_info;
 
607
 
 
608
        field_pack_length[fieldnr]=
 
609
          calc_pack_length(drizzle_field_type,
 
610
                           field_options.length() * cs->mbmaxlen);
 
611
 
 
612
      }
 
613
      break;
 
614
    case DRIZZLE_TYPE_ENUM:
 
615
      {
 
616
        drizzled::message::Table::Field::SetFieldOptions field_options=
 
617
          pfield.set_options();
 
618
 
 
619
        field_pack_length[fieldnr]=
 
620
          get_enum_pack_length(field_options.field_value_size());
 
621
 
 
622
        interval_count++;
 
623
        interval_parts+= field_options.field_value_size();
 
624
      }
 
625
      break;
 
626
    case DRIZZLE_TYPE_NEWDECIMAL:
 
627
      {
 
628
        drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
 
629
 
 
630
        field_pack_length[fieldnr]=
 
631
          my_decimal_get_binary_size(fo.precision(), fo.scale());
 
632
      }
 
633
      break;
 
634
    default:
 
635
      /* Zero is okay here as length is fixed for other types. */
 
636
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
 
637
    }
 
638
 
 
639
    share->reclength+= field_pack_length[fieldnr];
 
640
 
 
641
    if(field_is_stored)
 
642
      stored_columns_reclength+= field_pack_length[fieldnr];
 
643
  }
 
644
 
 
645
  /* data_offset added to stored_rec_length later */
 
646
  share->stored_rec_length= stored_columns_reclength;
 
647
 
 
648
  /* fix up offsets for non-stored fields (at end of record) */
 
649
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
650
  {
 
651
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
652
 
 
653
    bool field_is_stored= true;
 
654
 
 
655
    if(!field_is_stored)
 
656
    {
 
657
      field_offsets[fieldnr]= stored_columns_reclength;
 
658
      stored_columns_reclength+= field_pack_length[fieldnr];
 
659
    }
 
660
  }
 
661
  share->null_fields= null_fields;
 
662
 
 
663
  ulong null_bits= null_fields;
 
664
  if(!table_options.pack_record())
 
665
    null_bits++;
 
666
  ulong data_offset= (null_bits + 7)/8;
 
667
 
 
668
 
 
669
  share->reclength+= data_offset;
 
670
  share->stored_rec_length+= data_offset;
 
671
 
 
672
  ulong rec_buff_length;
 
673
 
 
674
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
675
  share->rec_buff_length= rec_buff_length;
 
676
 
 
677
  unsigned char* record= NULL;
 
678
 
 
679
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
 
680
                                     rec_buff_length)))
 
681
    abort();
 
682
 
 
683
  memset(record, 0, rec_buff_length);
 
684
 
 
685
  int null_count= 0;
 
686
 
 
687
  if(!table_options.pack_record())
 
688
  {
 
689
    null_count++; // one bit for delete mark.
 
690
    *record|= 1;
 
691
  }
 
692
 
 
693
  share->default_values= record;
 
694
 
 
695
  if(interval_count)
 
696
  {
 
697
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
 
698
                                           interval_count*sizeof(TYPELIB));
 
699
  }
 
700
  else
 
701
    share->intervals= NULL;
 
702
 
 
703
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
 
704
                                  (share->fields+1)*sizeof(char*));
 
705
 
 
706
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
707
                                  (share->fields+1)*sizeof(unsigned int));
 
708
 
 
709
  share->fieldnames.type_names[share->fields]= NULL;
 
710
  share->fieldnames.type_lengths[share->fields]= 0;
 
711
  share->fieldnames.count= share->fields;
 
712
 
 
713
 
 
714
  /* Now fix the TYPELIBs for the intervals (enum values)
 
715
     and field names.
 
716
   */
 
717
 
 
718
  uint32_t interval_nr= 0;
 
719
 
 
720
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
721
  {
 
722
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
723
 
 
724
    /* field names */
 
725
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
 
726
                                                        pfield.name().c_str(),
 
727
                                                        pfield.name().length());
 
728
 
 
729
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
 
730
 
 
731
    /* enum typelibs */
 
732
    if(pfield.type() != drizzled::message::Table::Field::ENUM)
 
733
      continue;
 
734
 
 
735
    drizzled::message::Table::Field::SetFieldOptions field_options=
 
736
      pfield.set_options();
 
737
 
 
738
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
 
739
                                             field_options.collation_id() : 0);
 
740
 
 
741
    if (!charset)
 
742
      charset= default_charset_info;
 
743
 
 
744
    TYPELIB *t= &(share->intervals[interval_nr]);
 
745
 
 
746
    t->type_names= (const char**)alloc_root(&share->mem_root,
 
747
                           (field_options.field_value_size()+1)*sizeof(char*));
 
748
 
 
749
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
 
750
                     (field_options.field_value_size()+1)*sizeof(unsigned int));
 
751
 
 
752
    t->type_names[field_options.field_value_size()]= NULL;
 
753
    t->type_lengths[field_options.field_value_size()]= 0;
 
754
 
 
755
    t->count= field_options.field_value_size();
 
756
    t->name= NULL;
 
757
 
 
758
    for(int n=0; n < field_options.field_value_size(); n++)
 
759
    {
 
760
      t->type_names[n]= strmake_root(&share->mem_root,
 
761
                                     field_options.field_value(n).c_str(),
 
762
                                     field_options.field_value(n).length());
 
763
 
 
764
      /* Go ask the charset what the length is as for "" length=1
 
765
         and there's stripping spaces or some other crack going on.
 
766
       */
 
767
      uint32_t lengthsp;
 
768
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
 
769
                                        field_options.field_value(n).length());
 
770
      t->type_lengths[n]= lengthsp;
 
771
    }
 
772
    interval_nr++;
 
773
  }
 
774
 
 
775
 
 
776
  /* and read the fields */
 
777
  interval_nr= 0;
 
778
 
 
779
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
 
780
 
 
781
  if(use_hash)
 
782
    use_hash= !hash_init(&share->name_hash,
 
783
                         system_charset_info,
 
784
                         share->fields, 0, 0,
 
785
                         (hash_get_key) get_field_name, 0, 0);
 
786
 
 
787
  unsigned char* null_pos= record;;
 
788
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
 
789
 
 
790
  for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
 
791
  {
 
792
    drizzled::message::Table::Field pfield= table.field(fieldnr);
 
793
 
 
794
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
795
 
 
796
    switch(pfield.format())
 
797
    {
 
798
    case drizzled::message::Table::Field::DefaultFormat:
 
799
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
 
800
      break;
 
801
    case drizzled::message::Table::Field::FixedFormat:
 
802
      column_format= COLUMN_FORMAT_TYPE_FIXED;
 
803
      break;
 
804
    case drizzled::message::Table::Field::DynamicFormat:
 
805
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
 
806
      break;
 
807
    default:
 
808
      assert(1);
 
809
    }
 
810
 
 
811
    Field::utype unireg_type= Field::NONE;
 
812
 
 
813
    if(pfield.has_numeric_options()
 
814
       && pfield.numeric_options().is_autoincrement())
 
815
    {
 
816
      unireg_type= Field::NEXT_NUMBER;
 
817
    }
 
818
 
 
819
    if(pfield.has_options()
 
820
       && pfield.options().has_default_value()
 
821
       && pfield.options().default_value().compare("NOW()")==0)
 
822
    {
 
823
      if(pfield.options().has_update_value()
 
824
         && pfield.options().update_value().compare("NOW()")==0)
 
825
      {
 
826
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
 
827
      }
 
828
      else if (!pfield.options().has_update_value())
 
829
      {
 
830
        unireg_type= Field::TIMESTAMP_DN_FIELD;
 
831
      }
 
832
      else
 
833
        assert(1); // Invalid update value.
 
834
    }
 
835
    else if (pfield.has_options()
 
836
             && pfield.options().has_update_value()
 
837
             && pfield.options().update_value().compare("NOW()")==0)
 
838
    {
 
839
      unireg_type= Field::TIMESTAMP_UN_FIELD;
 
840
    }
 
841
 
 
842
    LEX_STRING comment;
 
843
    if(!pfield.has_comment())
 
844
    {
 
845
      comment.str= (char*)"";
 
846
      comment.length= 0;
 
847
    }
 
848
    else
 
849
    {
 
850
      size_t len= pfield.comment().length();
 
851
      const char* str= pfield.comment().c_str();
 
852
 
 
853
      comment.str= strmake_root(&share->mem_root, str, len);
 
854
      comment.length= len;
 
855
    }
 
856
 
 
857
    enum_field_types field_type;
 
858
 
 
859
    field_type= proto_field_type_to_drizzle_type(pfield.type());
 
860
 
 
861
    const CHARSET_INFO *charset= &my_charset_bin;
 
862
 
 
863
    if(field_type==DRIZZLE_TYPE_BLOB
 
864
       || field_type==DRIZZLE_TYPE_VARCHAR)
 
865
    {
 
866
      drizzled::message::Table::Field::StringFieldOptions field_options=
 
867
        pfield.string_options();
 
868
 
 
869
      charset= get_charset(field_options.has_collation_id()?
 
870
                           field_options.collation_id() : 0);
 
871
 
 
872
      if (!charset)
 
873
        charset= default_charset_info;
 
874
 
 
875
    }
 
876
 
 
877
    if(field_type==DRIZZLE_TYPE_ENUM)
 
878
    {
 
879
      drizzled::message::Table::Field::SetFieldOptions field_options=
 
880
        pfield.set_options();
 
881
 
 
882
      charset= get_charset(field_options.has_collation_id()?
 
883
                           field_options.collation_id() : 0);
 
884
 
 
885
      if (!charset)
 
886
        charset= default_charset_info;
 
887
 
 
888
    }
 
889
 
 
890
    Item *default_value= NULL;
 
891
 
 
892
    if(pfield.options().has_default_value()
 
893
       || pfield.options().has_default_null()
 
894
       || pfield.options().has_default_bin_value())
 
895
    {
 
896
      default_value= default_value_item(field_type,
 
897
                                        charset,
 
898
                                        pfield.options().default_null(),
 
899
                                        &pfield.options().default_value(),
 
900
                                        &pfield.options().default_bin_value());
 
901
    }
 
902
 
 
903
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
 
904
 
 
905
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
 
906
    memset(&temp_table, 0, sizeof(temp_table));
 
907
    temp_table.s= share;
 
908
    temp_table.in_use= session;
 
909
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
 
910
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
 
911
 
 
912
    Field* f= make_field(share, &share->mem_root,
 
913
                         record+field_offsets[fieldnr]+data_offset,
 
914
                         pfield.options().length(),
 
915
                         null_pos,
 
916
                         null_bit_pos,
 
917
                         pack_flag,
 
918
                         field_type,
 
919
                         charset,
 
920
                         (Field::utype) MTYP_TYPENR(unireg_type),
 
921
                         ((field_type==DRIZZLE_TYPE_ENUM)?
 
922
                         share->intervals+(interval_nr++)
 
923
                         : (TYPELIB*) 0),
 
924
                        share->fieldnames.type_names[fieldnr]);
 
925
 
 
926
    share->field[fieldnr]= f;
 
927
 
 
928
    f->init(&temp_table); /* blob default values need table obj */
 
929
 
 
930
    if(!(f->flags & NOT_NULL_FLAG))
 
931
    {
 
932
      *f->null_ptr|= f->null_bit;
 
933
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
 
934
        null_pos++;
 
935
      null_count++;
 
936
    }
 
937
 
 
938
    if(default_value)
 
939
    {
 
940
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
 
941
      session->count_cuted_fields= CHECK_FIELD_WARN;
 
942
      int res= default_value->save_in_field(f, 1);
 
943
      session->count_cuted_fields= old_count_cuted_fields;
 
944
      if (res != 0 && res != 3)
 
945
      {
 
946
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
 
947
        error= 1;
 
948
        goto err;
 
949
      }
 
950
    }
 
951
    else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
 
952
            (f->flags & NOT_NULL_FLAG))
 
953
    {
 
954
      f->set_notnull();
 
955
      f->store((int64_t) 1, true);
 
956
    }
 
957
    else
 
958
      f->reset();
 
959
 
 
960
    /* hack to undo f->init() */
 
961
    f->table= NULL;
 
962
    f->orig_table= NULL;
 
963
 
 
964
    f->field_index= fieldnr;
 
965
    f->comment= comment;
 
966
    if(!default_value
 
967
       && !(f->unireg_check==Field::NEXT_NUMBER)
 
968
       && (f->flags & NOT_NULL_FLAG)
 
969
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
 
970
      f->flags|= NO_DEFAULT_VALUE_FLAG;
 
971
 
 
972
    if(f->unireg_check == Field::NEXT_NUMBER)
 
973
      share->found_next_number_field= &(share->field[fieldnr]);
 
974
 
 
975
    if(share->timestamp_field == f)
 
976
      share->timestamp_field_offset= fieldnr;
 
977
 
 
978
    if (use_hash) /* supposedly this never fails... but comments lie */
 
979
      (void) my_hash_insert(&share->name_hash,
 
980
                            (unsigned char*)&(share->field[fieldnr]));
 
981
  }
 
982
 
 
983
  keyinfo= share->key_info;
 
984
  for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
 
985
  {
 
986
    key_part= keyinfo->key_part;
 
987
 
 
988
    for(unsigned int partnr= 0;
 
989
        partnr < keyinfo->key_parts;
 
990
        partnr++, key_part++)
 
991
    {
 
992
      /* Fix up key_part->offset by adding data_offset.
 
993
         We really should compute offset as well.
 
994
         But at least this way we are a little better. */
 
995
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
 
996
    }
 
997
  }
 
998
 
 
999
  /*
 
1000
    We need to set the unused bits to 1. If the number of bits is a multiple
 
1001
    of 8 there are no unused bits.
 
1002
  */
 
1003
 
 
1004
  if (null_count & 7)
 
1005
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
 
1006
 
 
1007
  share->null_bytes= (null_pos - (unsigned char*) record +
 
1008
                      (null_bit_pos + 7) / 8);
 
1009
 
 
1010
  share->last_null_bit_pos= null_bit_pos;
 
1011
 
 
1012
  free(field_offsets);
 
1013
  free(field_pack_length);
 
1014
 
 
1015
  if(!(handler_file= get_new_handler(share, session->mem_root,
 
1016
                                     share->db_type())))
 
1017
    abort(); // FIXME
 
1018
 
 
1019
  /* Fix key stuff */
 
1020
  if (share->key_parts)
 
1021
  {
 
1022
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
 
1023
                                       &share->keynames, 3) - 1);
 
1024
 
 
1025
    int64_t ha_option= handler_file->ha_table_flags();
 
1026
 
 
1027
    keyinfo= share->key_info;
 
1028
    key_part= keyinfo->key_part;
 
1029
 
 
1030
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
 
1031
    {
 
1032
      uint32_t usable_parts= 0;
 
1033
 
 
1034
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
 
1035
      {
 
1036
        /*
 
1037
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
1038
          declare this as a primary key.
 
1039
        */
 
1040
        primary_key=key;
 
1041
        for (uint32_t i=0 ; i < keyinfo->key_parts ;i++)
 
1042
        {
 
1043
          uint32_t fieldnr= key_part[i].fieldnr;
 
1044
          if (!fieldnr ||
 
1045
              share->field[fieldnr-1]->null_ptr ||
 
1046
              share->field[fieldnr-1]->key_length() !=
 
1047
              key_part[i].length)
 
1048
          {
 
1049
            primary_key=MAX_KEY;                // Can't be used
 
1050
            break;
 
1051
          }
 
1052
        }
 
1053
      }
 
1054
 
 
1055
      for (uint32_t i=0 ; i < keyinfo->key_parts ; key_part++,i++)
 
1056
      {
 
1057
        Field *field;
 
1058
        if (!key_part->fieldnr)
 
1059
        {
 
1060
//          error= 4;                             // Wrong file
 
1061
          abort(); // goto err;
 
1062
        }
 
1063
        field= key_part->field= share->field[key_part->fieldnr-1];
 
1064
        key_part->type= field->key_type();
 
1065
        if (field->null_ptr)
 
1066
        {
 
1067
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
 
1068
                                        share->default_values);
 
1069
          key_part->null_bit= field->null_bit;
 
1070
          key_part->store_length+=HA_KEY_NULL_LENGTH;
 
1071
          keyinfo->flags|=HA_NULL_PART_KEY;
 
1072
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
 
1073
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
 
1074
        }
 
1075
        if (field->type() == DRIZZLE_TYPE_BLOB ||
 
1076
            field->real_type() == DRIZZLE_TYPE_VARCHAR)
 
1077
        {
 
1078
          if (field->type() == DRIZZLE_TYPE_BLOB)
 
1079
            key_part->key_part_flag|= HA_BLOB_PART;
 
1080
          else
 
1081
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
 
1082
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
 
1083
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
 
1084
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
 
1085
        }
 
1086
        if (i == 0 && key != primary_key)
 
1087
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
 
1088
                           (keyinfo->key_parts == 1)) ?
 
1089
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
 
1090
        if (i == 0)
 
1091
          field->key_start.set(key);
 
1092
        if (field->key_length() == key_part->length &&
 
1093
            !(field->flags & BLOB_FLAG))
 
1094
        {
 
1095
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
 
1096
          {
 
1097
            share->keys_for_keyread.set(key);
 
1098
            field->part_of_key.set(key);
 
1099
            field->part_of_key_not_clustered.set(key);
 
1100
          }
 
1101
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
 
1102
            field->part_of_sortkey.set(key);
 
1103
        }
 
1104
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
 
1105
            usable_parts == i)
 
1106
          usable_parts++;                       // For FILESORT
 
1107
        field->flags|= PART_KEY_FLAG;
 
1108
        if (key == primary_key)
 
1109
        {
 
1110
          field->flags|= PRI_KEY_FLAG;
 
1111
          /*
 
1112
            If this field is part of the primary key and all keys contains
 
1113
            the primary key, then we can use any key to find this column
 
1114
          */
 
1115
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
 
1116
          {
 
1117
            field->part_of_key= share->keys_in_use;
 
1118
            if (field->part_of_sortkey.test(key))
 
1119
              field->part_of_sortkey= share->keys_in_use;
 
1120
          }
 
1121
        }
 
1122
        if (field->key_length() != key_part->length)
 
1123
        {
 
1124
          key_part->key_part_flag|= HA_PART_KEY_SEG;
 
1125
        }
 
1126
      }
 
1127
      keyinfo->usable_key_parts= usable_parts; // Filesort
 
1128
 
 
1129
      set_if_bigger(share->max_key_length,keyinfo->key_length+
 
1130
                    keyinfo->key_parts);
 
1131
      share->total_key_length+= keyinfo->key_length;
 
1132
      /*
 
1133
        MERGE tables do not have unique indexes. But every key could be
 
1134
        an unique index on the underlying MyISAM table. (Bug #10400)
 
1135
      */
 
1136
      if ((keyinfo->flags & HA_NOSAME) ||
 
1137
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
 
1138
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
 
1139
    }
 
1140
    if (primary_key < MAX_KEY &&
 
1141
        (share->keys_in_use.test(primary_key)))
 
1142
    {
 
1143
      share->primary_key= primary_key;
 
1144
      /*
 
1145
        If we are using an integer as the primary key then allow the user to
 
1146
        refer to it as '_rowid'
 
1147
      */
 
1148
      if (share->key_info[primary_key].key_parts == 1)
 
1149
      {
 
1150
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1151
        if (field && field->result_type() == INT_RESULT)
 
1152
        {
 
1153
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
 
1154
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1155
                                      fieldnr);
 
1156
        }
 
1157
      }
 
1158
 
 
1159
    }
 
1160
    else
 
1161
      share->primary_key = MAX_KEY; // we do not have a primary key
 
1162
  }
 
1163
  else
 
1164
    share->primary_key= MAX_KEY;
 
1165
 
 
1166
  if (share->found_next_number_field)
 
1167
  {
 
1168
    Field *reg_field= *share->found_next_number_field;
 
1169
    if ((int) (share->next_number_index= (uint32_t)
 
1170
               find_ref_key(share->key_info, share->keys,
 
1171
                            share->default_values, reg_field,
 
1172
                            &share->next_number_key_offset,
 
1173
                            &share->next_number_keypart)) < 0)
 
1174
    {
 
1175
      /* Wrong field definition */
 
1176
      error= 4;
 
1177
      goto err;
 
1178
    }
 
1179
    else
 
1180
      reg_field->flags |= AUTO_INCREMENT_FLAG;
 
1181
  }
 
1182
 
 
1183
  if (share->blob_fields)
 
1184
  {
 
1185
    Field **ptr;
 
1186
    uint32_t k, *save;
 
1187
 
 
1188
    /* Store offsets to blob fields to find them fast */
 
1189
    if (!(share->blob_field= save=
 
1190
          (uint*) alloc_root(&share->mem_root,
 
1191
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
 
1192
      goto err;
 
1193
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
 
1194
    {
 
1195
      if ((*ptr)->flags & BLOB_FLAG)
 
1196
        (*save++)= k;
 
1197
    }
 
1198
  }
 
1199
 
 
1200
  share->db_low_byte_first= handler_file->low_byte_first();
 
1201
  share->all_set.set();
 
1202
 
 
1203
  if(handler_file)
 
1204
    delete handler_file;
 
1205
  return (0);
 
1206
 
 
1207
err:
 
1208
  share->error= error;
 
1209
  share->open_errno= my_errno;
 
1210
  share->errarg= 0;
 
1211
  hash_free(&share->name_hash);
 
1212
  if(handler_file)
 
1213
    delete handler_file;
 
1214
  open_table_error(share, error, share->open_errno, 0);
 
1215
  return error;
 
1216
}
 
1217
 
 
1218
/*
 
1219
  Read table definition from a binary / text based .frm file
 
1220
 
 
1221
  SYNOPSIS
 
1222
  open_table_def()
 
1223
  session               Thread handler
 
1224
  share         Fill this with table definition
 
1225
 
 
1226
  NOTES
 
1227
    This function is called when the table definition is not cached in
 
1228
    table_def_cache
 
1229
    The data is returned in 'share', which is alloced by
 
1230
    alloc_table_share().. The code assumes that share is initialized.
 
1231
 
 
1232
  RETURN VALUES
 
1233
   0    ok
 
1234
   1    Error (see open_table_error)
 
1235
   2    Error (see open_table_error)
 
1236
   3    Wrong data in .frm file
 
1237
   4    Error (see open_table_error)
 
1238
   5    Error (see open_table_error: charset unavailable)
 
1239
   6    Unknown .frm version
 
1240
*/
 
1241
 
 
1242
int open_table_def(Session *session, TableShare *share)
 
1243
{
 
1244
  int error;
 
1245
  bool error_given;
 
1246
  string proto_path("");
 
1247
 
 
1248
  error= 1;
 
1249
  error_given= 0;
 
1250
 
 
1251
  proto_path.reserve(FN_REFLEN);
 
1252
  proto_path.append(share->normalized_path.str);
 
1253
 
 
1254
  proto_path.append(".dfe");
 
1255
 
 
1256
  drizzled::message::Table table;
 
1257
 
 
1258
  if((error= drizzle_read_table_proto(proto_path.c_str(), &table)))
 
1259
  {
 
1260
    if(error>0)
 
1261
    {
 
1262
      my_errno= error;
 
1263
      error= 1;
 
1264
    }
 
1265
    else
 
1266
    {
 
1267
      if(!table.IsInitialized())
 
1268
      {
 
1269
        error= 4;
 
1270
      }
 
1271
    }
 
1272
    goto err_not_open;
 
1273
  }
 
1274
 
 
1275
  error= parse_table_proto(session, table, share);
 
1276
 
 
1277
  share->table_category= get_table_category(& share->db, & share->table_name);
 
1278
 
 
1279
  if (!error)
 
1280
    session->status_var.opened_shares++;
 
1281
 
 
1282
err_not_open:
 
1283
  if (error && !error_given)
 
1284
  {
 
1285
    share->error= error;
 
1286
    open_table_error(share, error, (share->open_errno= my_errno), 0);
 
1287
  }
 
1288
 
 
1289
  return(error);
 
1290
}
 
1291
 
 
1292
 
 
1293
/*
 
1294
  Open a table based on a TableShare
 
1295
 
 
1296
  SYNOPSIS
 
1297
    open_table_from_share()
 
1298
    session                     Thread handler
 
1299
    share               Table definition
 
1300
    alias               Alias for table
 
1301
    db_stat             open flags (for example HA_OPEN_KEYFILE|
 
1302
                        HA_OPEN_RNDFILE..) can be 0 (example in
 
1303
                        ha_example_table)
 
1304
    prgflag             READ_ALL etc..
 
1305
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
 
1306
    outparam            result table
 
1307
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
 
1308
                        if OTM_CREATE some errors are ignore
 
1309
                        if OTM_ALTER HA_OPEN is not called
 
1310
 
 
1311
  RETURN VALUES
 
1312
   0    ok
 
1313
   1    Error (see open_table_error)
 
1314
   2    Error (see open_table_error)
 
1315
   3    Wrong data in .frm file
 
1316
   4    Error (see open_table_error)
 
1317
   5    Error (see open_table_error: charset unavailable)
 
1318
   7    Table definition has changed in engine
 
1319
*/
 
1320
 
 
1321
int open_table_from_share(Session *session, TableShare *share, const char *alias,
 
1322
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
 
1323
                          Table *outparam, open_table_mode open_mode)
 
1324
{
 
1325
  int error;
 
1326
  uint32_t records, i;
 
1327
  bool error_reported= false;
 
1328
  unsigned char *record;
 
1329
  Field **field_ptr;
 
1330
 
 
1331
  /* Parsing of partitioning information from .frm needs session->lex set up. */
 
1332
  assert(session->lex->is_lex_started);
 
1333
 
 
1334
  error= 1;
 
1335
  memset(outparam, 0, sizeof(*outparam));
 
1336
  outparam->in_use= session;
 
1337
  outparam->s= share;
 
1338
  outparam->db_stat= db_stat;
 
1339
  outparam->write_row_record= NULL;
 
1340
 
 
1341
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
1342
 
 
1343
  if (!(outparam->alias= strdup(alias)))
 
1344
    goto err;
 
1345
  outparam->quick_keys.reset();
 
1346
  outparam->covering_keys.reset();
 
1347
  outparam->keys_in_use_for_query.reset();
 
1348
 
 
1349
  /* Allocate handler */
 
1350
  outparam->file= 0;
 
1351
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
 
1352
  {
 
1353
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
 
1354
                                          share->db_type())))
 
1355
      goto err;
 
1356
  }
 
1357
  else
 
1358
  {
 
1359
    assert(!db_stat);
 
1360
  }
 
1361
 
 
1362
  error= 4;
 
1363
  outparam->reginfo.lock_type= TL_UNLOCK;
 
1364
  outparam->current_lock= F_UNLCK;
 
1365
  records=0;
 
1366
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
 
1367
    records=1;
 
1368
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
1369
    records++;
 
1370
 
 
1371
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
 
1372
                                   share->rec_buff_length * records)))
 
1373
    goto err;                                   /* purecov: inspected */
 
1374
 
 
1375
  if (records == 0)
 
1376
  {
 
1377
    /* We are probably in hard repair, and the buffers should not be used */
 
1378
    outparam->record[0]= outparam->record[1]= share->default_values;
 
1379
  }
 
1380
  else
 
1381
  {
 
1382
    outparam->record[0]= record;
 
1383
    if (records > 1)
 
1384
      outparam->record[1]= record+ share->rec_buff_length;
 
1385
    else
 
1386
      outparam->record[1]= outparam->record[0];   // Safety
 
1387
  }
 
1388
 
 
1389
#ifdef HAVE_purify
 
1390
  /*
 
1391
    We need this because when we read var-length rows, we are not updating
 
1392
    bytes after end of varchar
 
1393
  */
 
1394
  if (records > 1)
 
1395
  {
 
1396
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
 
1397
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
 
1398
    if (records > 2)
 
1399
      memcpy(outparam->record[1], share->default_values,
 
1400
             share->rec_buff_length);
 
1401
  }
 
1402
#endif
 
1403
 
 
1404
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
 
1405
                                          (uint32_t) ((share->fields+1)*
 
1406
                                                  sizeof(Field*)))))
 
1407
    goto err;                                   /* purecov: inspected */
 
1408
 
 
1409
  outparam->field= field_ptr;
 
1410
 
 
1411
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
 
1412
 
 
1413
  outparam->null_flags= (unsigned char*) record+1;
 
1414
 
 
1415
  /* Setup copy of fields from share, but use the right alias and record */
 
1416
  for (i=0 ; i < share->fields; i++, field_ptr++)
 
1417
  {
 
1418
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
 
1419
      goto err;
 
1420
  }
 
1421
  (*field_ptr)= 0;                              // End marker
 
1422
 
 
1423
  if (share->found_next_number_field)
 
1424
    outparam->found_next_number_field=
 
1425
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
 
1426
  if (share->timestamp_field)
 
1427
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
 
1428
 
 
1429
 
 
1430
  /* Fix key->name and key_part->field */
 
1431
  if (share->key_parts)
 
1432
  {
 
1433
    KEY *key_info, *key_info_end;
 
1434
    KEY_PART_INFO *key_part;
 
1435
    uint32_t n_length;
 
1436
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
 
1437
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
 
1438
      goto err;
 
1439
    outparam->key_info= key_info;
 
1440
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
 
1441
 
 
1442
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
 
1443
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
 
1444
                                                   share->key_parts));
 
1445
 
 
1446
    for (key_info_end= key_info + share->keys ;
 
1447
         key_info < key_info_end ;
 
1448
         key_info++)
 
1449
    {
 
1450
      KEY_PART_INFO *key_part_end;
 
1451
 
 
1452
      key_info->table= outparam;
 
1453
      key_info->key_part= key_part;
 
1454
 
 
1455
      for (key_part_end= key_part+ key_info->key_parts ;
 
1456
           key_part < key_part_end ;
 
1457
           key_part++)
 
1458
      {
 
1459
        Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
 
1460
 
 
1461
        if (field->key_length() != key_part->length &&
 
1462
            !(field->flags & BLOB_FLAG))
 
1463
        {
 
1464
          /*
 
1465
            We are using only a prefix of the column as a key:
 
1466
            Create a new field for the key part that matches the index
 
1467
          */
 
1468
          field= key_part->field=field->new_field(&outparam->mem_root,
 
1469
                                                  outparam, 0);
 
1470
          field->field_length= key_part->length;
 
1471
        }
 
1472
      }
 
1473
    }
 
1474
  }
 
1475
 
 
1476
  /* Allocate bitmaps */
 
1477
  outparam->default_column_bitmaps();
 
1478
 
 
1479
  /* The table struct is now initialized;  Open the table */
 
1480
  error= 2;
 
1481
  if (db_stat && open_mode != OTM_ALTER)
 
1482
  {
 
1483
    int ha_err;
 
1484
    if ((ha_err= (outparam->file->
 
1485
                  ha_open(outparam, share->normalized_path.str,
 
1486
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
 
1487
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
 
1488
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
 
1489
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
 
1490
                          HA_OPEN_ABORT_IF_LOCKED :
 
1491
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
 
1492
    {
 
1493
      /* Set a flag if the table is crashed and it can be auto. repaired */
 
1494
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
 
1495
                       outparam->file->auto_repair() &&
 
1496
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
 
1497
 
 
1498
      switch (ha_err)
 
1499
      {
 
1500
        case HA_ERR_NO_SUCH_TABLE:
 
1501
          /*
 
1502
            The table did not exists in storage engine, use same error message
 
1503
            as if the .frm file didn't exist
 
1504
          */
 
1505
          error= 1;
 
1506
          my_errno= ENOENT;
 
1507
          break;
 
1508
        case EMFILE:
 
1509
          /*
 
1510
            Too many files opened, use same error message as if the .frm
 
1511
            file can't open
 
1512
           */
 
1513
          error= 1;
 
1514
          my_errno= EMFILE;
 
1515
          break;
 
1516
        default:
 
1517
          outparam->file->print_error(ha_err, MYF(0));
 
1518
          error_reported= true;
 
1519
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
 
1520
            error= 7;
 
1521
          break;
 
1522
      }
 
1523
      goto err;                                 /* purecov: inspected */
 
1524
    }
 
1525
  }
 
1526
 
 
1527
#if defined(HAVE_purify)
 
1528
  memset(bitmaps, 0, bitmap_size*3);
 
1529
#endif
 
1530
 
 
1531
  session->status_var.opened_tables++;
 
1532
 
 
1533
  return (0);
 
1534
 
 
1535
 err:
 
1536
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
 
1537
    open_table_error(share, error, my_errno, 0);
 
1538
  delete outparam->file;
 
1539
  outparam->file= 0;                            // For easier error checking
 
1540
  outparam->db_stat=0;
 
1541
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
 
1542
  free((char*) outparam->alias);
 
1543
  return (error);
 
1544
}
 
1545
 
 
1546
/* close_temporary_tables' internal, 4 is due to uint4korr definition */
 
1547
uint32_t  Table::tmpkeyval()
 
1548
{
 
1549
  return uint4korr(s->table_cache_key.str + s->table_cache_key.length - 4);
 
1550
}
 
1551
 
 
1552
/*
 
1553
  Free information allocated by openfrm
 
1554
 
 
1555
  SYNOPSIS
 
1556
    closefrm()
 
1557
    table               Table object to free
 
1558
    free_share          Is 1 if we also want to free table_share
 
1559
*/
 
1560
 
 
1561
int Table::closefrm(bool free_share)
 
1562
{
 
1563
  int error=0;
80
1564
 
81
1565
  if (db_stat)
82
 
    error= cursor->close();
83
 
  _alias.clear();
84
 
 
 
1566
    error= file->close();
 
1567
  free((char*) alias);
 
1568
  alias= NULL;
85
1569
  if (field)
86
1570
  {
87
1571
    for (Field **ptr=field ; *ptr ; ptr++)
88
 
    {
89
1572
      delete *ptr;
90
 
    }
91
1573
    field= 0;
92
1574
  }
93
 
  delete cursor;
94
 
  cursor= 0;                            /* For easier errorchecking */
95
 
 
 
1575
  delete file;
 
1576
  file= 0;                              /* For easier errorchecking */
96
1577
  if (free_share)
97
1578
  {
98
 
    release();
 
1579
    if (s->tmp_table == NO_TMP_TABLE)
 
1580
      release_table_share(s, RELEASE_NORMAL);
 
1581
    else
 
1582
      s->free_table_share();
99
1583
  }
 
1584
  free_root(&mem_root, MYF(0));
100
1585
 
101
1586
  return error;
102
1587
}
103
1588
 
104
 
Table::~Table()
105
 
{
106
 
  mem_root.free_root(MYF(0));
107
 
}
108
 
 
109
 
 
110
 
void Table::resetTable(Session *session,
111
 
                       TableShare *share,
112
 
                       uint32_t db_stat_arg)
113
 
{
114
 
  setShare(share);
115
 
  in_use= session;
116
 
 
117
 
  field= NULL;
118
 
 
119
 
  cursor= NULL;
120
 
  next= NULL;
121
 
  prev= NULL;
122
 
 
123
 
  read_set= NULL;
124
 
  write_set= NULL;
125
 
 
126
 
  tablenr= 0;
127
 
  db_stat= db_stat_arg;
128
 
 
129
 
  record[0]= (unsigned char *) NULL;
130
 
  record[1]= (unsigned char *) NULL;
131
 
 
132
 
  insert_values.clear();
133
 
  key_info= NULL;
134
 
  next_number_field= NULL;
135
 
  found_next_number_field= NULL;
136
 
  timestamp_field= NULL;
137
 
 
138
 
  pos_in_table_list= NULL;
139
 
  group= NULL;
140
 
  _alias.clear();
141
 
  null_flags= NULL;
142
 
 
143
 
  lock_position= 0;
144
 
  lock_data_start= 0;
145
 
  lock_count= 0;
146
 
  used_fields= 0;
147
 
  status= 0;
148
 
  derived_select_number= 0;
149
 
  current_lock= F_UNLCK;
150
 
  copy_blobs= false;
151
 
 
152
 
  maybe_null= false;
153
 
 
154
 
  null_row= false;
155
 
 
156
 
  force_index= false;
157
 
  distinct= false;
158
 
  const_table= false;
159
 
  no_rows= false;
160
 
  key_read= false;
161
 
  no_keyread= false;
162
 
 
163
 
  open_placeholder= false;
164
 
  locked_by_name= false;
165
 
  no_cache= false;
166
 
 
167
 
  auto_increment_field_not_null= false;
168
 
  alias_name_used= false;
169
 
 
170
 
  query_id= 0;
171
 
  quick_condition_rows= 0;
172
 
 
173
 
  timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
174
 
  map= 0;
175
 
 
176
 
  reginfo.reset();
177
 
 
178
 
  covering_keys.reset();
179
 
 
180
 
  quick_keys.reset();
181
 
  merge_keys.reset();
182
 
 
183
 
  keys_in_use_for_query.reset();
184
 
  keys_in_use_for_group_by.reset();
185
 
  keys_in_use_for_order_by.reset();
186
 
 
187
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
188
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
189
 
 
190
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
191
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
192
 
 
193
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
194
 
}
195
 
 
196
 
 
197
1589
 
198
1590
/* Deallocate temporary blob storage */
199
1591
 
203
1595
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
204
1596
       ptr != end ;
205
1597
       ptr++)
206
 
  {
207
 
    ((Field_blob*) table->getField(*ptr))->free();
208
 
  }
209
 
}
210
 
 
211
 
 
212
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
213
 
{
214
 
  TYPELIB *result= (TYPELIB*) mem_root->alloc_root(sizeof(TYPELIB));
 
1598
    ((Field_blob*) table->field[*ptr])->free();
 
1599
}
 
1600
 
 
1601
 
 
1602
        /* Find where a form starts */
 
1603
        /* if formname is NULL then only formnames is read */
 
1604
 
 
1605
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
 
1606
{
 
1607
  uint32_t a_length,names,length;
 
1608
  unsigned char *pos,*buf;
 
1609
  ulong ret_value=0;
 
1610
 
 
1611
  names=uint2korr(head+8);
 
1612
  a_length=(names+2)*sizeof(char *);            /* Room for two extra */
 
1613
 
 
1614
  if (!save_names)
 
1615
    a_length=0;
 
1616
  else
 
1617
    save_names->type_names=0;                   /* Clear if error */
 
1618
 
 
1619
  if (names)
 
1620
  {
 
1621
    length=uint2korr(head+4);
 
1622
    lseek(file,64,SEEK_SET);
 
1623
    if (!(buf= (unsigned char*) malloc(length+a_length+names*4)) ||
 
1624
        my_read(file, buf+a_length, (size_t) (length+names*4),
 
1625
                MYF(MY_NABP)))
 
1626
    {                                           /* purecov: inspected */
 
1627
      if (buf)
 
1628
        free(buf);
 
1629
      return(0L);                               /* purecov: inspected */
 
1630
    }
 
1631
    pos= buf+a_length+length;
 
1632
    ret_value=uint4korr(pos);
 
1633
  }
 
1634
  if (! save_names)
 
1635
  {
 
1636
    if (names)
 
1637
      free((unsigned char*) buf);
 
1638
  }
 
1639
  else if (!names)
 
1640
    memset(save_names, 0, sizeof(save_names));
 
1641
  else
 
1642
  {
 
1643
    char *str;
 
1644
    str=(char *) (buf+a_length);
 
1645
    fix_type_pointers((const char ***) &buf,save_names,1,&str);
 
1646
  }
 
1647
  return(ret_value);
 
1648
}
 
1649
 
 
1650
 
 
1651
/*
 
1652
  Read string from a file with malloc
 
1653
 
 
1654
  NOTES:
 
1655
    We add an \0 at end of the read string to make reading of C strings easier
 
1656
*/
 
1657
 
 
1658
int read_string(File file, unsigned char**to, size_t length)
 
1659
{
 
1660
 
 
1661
  if (*to)
 
1662
    free(*to);
 
1663
  if (!(*to= (unsigned char*) malloc(length+1)) ||
 
1664
      my_read(file, *to, length,MYF(MY_NABP)))
 
1665
  {
 
1666
    if (*to)
 
1667
      free(*to);
 
1668
    *to= NULL;
 
1669
    return(1);                           /* purecov: inspected */
 
1670
  }
 
1671
  *((char*) *to+length)= '\0';
 
1672
  return (0);
 
1673
} /* read_string */
 
1674
 
 
1675
 
 
1676
        /* Add a new form to a form file */
 
1677
 
 
1678
off_t make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
 
1679
                     const char *newname)
 
1680
{
 
1681
  uint32_t i,bufflength,maxlength,n_length,length,names;
 
1682
  off_t endpos,newpos;
 
1683
  unsigned char buff[IO_SIZE];
 
1684
  unsigned char *pos;
 
1685
 
 
1686
  length=(uint32_t) strlen(newname)+1;
 
1687
  n_length=uint2korr(fileinfo+4);
 
1688
  maxlength=uint2korr(fileinfo+6);
 
1689
  names=uint2korr(fileinfo+8);
 
1690
  newpos=uint4korr(fileinfo+10);
 
1691
 
 
1692
  if (64+length+n_length+(names+1)*4 > maxlength)
 
1693
  {                                             /* Expand file */
 
1694
    newpos+=IO_SIZE;
 
1695
    int4store(fileinfo+10,newpos);
 
1696
    endpos= lseek(file,0,SEEK_END);/* Copy from file-end */
 
1697
    bufflength= (uint32_t) (endpos & (IO_SIZE-1));      /* IO_SIZE is a power of 2 */
 
1698
 
 
1699
    while (endpos > maxlength)
 
1700
    {
 
1701
      lseek(file,(off_t) (endpos-bufflength),SEEK_SET);
 
1702
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
 
1703
        return(0L);
 
1704
      lseek(file,(off_t) (endpos-bufflength+IO_SIZE),SEEK_SET);
 
1705
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
 
1706
        return(0);
 
1707
      endpos-=bufflength; bufflength=IO_SIZE;
 
1708
    }
 
1709
    memset(buff, 0, IO_SIZE);                   /* Null new block */
 
1710
    lseek(file,(ulong) maxlength,SEEK_SET);
 
1711
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
 
1712
      return(0L);
 
1713
    maxlength+=IO_SIZE;                         /* Fix old ref */
 
1714
    int2store(fileinfo+6,maxlength);
 
1715
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i--;
 
1716
         pos+=4)
 
1717
    {
 
1718
      endpos=uint4korr(pos)+IO_SIZE;
 
1719
      int4store(pos,endpos);
 
1720
    }
 
1721
  }
 
1722
 
 
1723
  if (n_length == 1 )
 
1724
  {                                             /* First name */
 
1725
    length++;
 
1726
    sprintf((char*)buff,"/%s/",newname);
 
1727
  }
 
1728
  else
 
1729
    sprintf((char*)buff,"%s/",newname); /* purecov: inspected */
 
1730
  lseek(file, 63 + n_length,SEEK_SET);
 
1731
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
 
1732
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
 
1733
                         names*4, MYF(MY_NABP+MY_WME))) ||
 
1734
      my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
 
1735
    return(0L); /* purecov: inspected */
 
1736
 
 
1737
  int2store(fileinfo+8,names+1);
 
1738
  int2store(fileinfo+4,n_length+length);
 
1739
  assert(ftruncate(file, newpos)==0);/* Append file with '\0' */
 
1740
  return(newpos);
 
1741
} /* make_new_entry */
 
1742
 
 
1743
 
 
1744
        /* error message when opening a form file */
 
1745
 
 
1746
void open_table_error(TableShare *share, int error, int db_errno, int errarg)
 
1747
{
 
1748
  int err_no;
 
1749
  char buff[FN_REFLEN];
 
1750
  myf errortype= ME_ERROR+ME_WAITTANG;
 
1751
 
 
1752
  switch (error) {
 
1753
  case 7:
 
1754
  case 1:
 
1755
    if (db_errno == ENOENT)
 
1756
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
 
1757
    else
 
1758
    {
 
1759
      sprintf(buff,"%s",share->normalized_path.str);
 
1760
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
 
1761
               errortype, buff, db_errno);
 
1762
    }
 
1763
    break;
 
1764
  case 2:
 
1765
  {
 
1766
    handler *file= 0;
 
1767
    const char *datext= "";
 
1768
 
 
1769
    if (share->db_type() != NULL)
 
1770
    {
 
1771
      if ((file= get_new_handler(share, current_session->mem_root,
 
1772
                                 share->db_type())))
 
1773
      {
 
1774
        if (!(datext= *file->bas_ext()))
 
1775
          datext= "";
 
1776
      }
 
1777
    }
 
1778
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
 
1779
      ER_FILE_USED : ER_CANT_OPEN_FILE;
 
1780
    sprintf(buff,"%s%s", share->normalized_path.str,datext);
 
1781
    my_error(err_no,errortype, buff, db_errno);
 
1782
    delete file;
 
1783
    break;
 
1784
  }
 
1785
  case 5:
 
1786
  {
 
1787
    const char *csname= get_charset_name((uint32_t) errarg);
 
1788
    char tmp[10];
 
1789
    if (!csname || csname[0] =='?')
 
1790
    {
 
1791
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
 
1792
      csname= tmp;
 
1793
    }
 
1794
    my_printf_error(ER_UNKNOWN_COLLATION,
 
1795
                    _("Unknown collation '%s' in table '%-.64s' definition"),
 
1796
                    MYF(0), csname, share->table_name.str);
 
1797
    break;
 
1798
  }
 
1799
  case 6:
 
1800
    sprintf(buff,"%s",share->normalized_path.str);
 
1801
    my_printf_error(ER_NOT_FORM_FILE,
 
1802
                    _("Table '%-.64s' was created with a different version "
 
1803
                    "of Drizzle and cannot be read"),
 
1804
                    MYF(0), buff);
 
1805
    break;
 
1806
  case 8:
 
1807
    break;
 
1808
  default:                              /* Better wrong error than none */
 
1809
  case 4:
 
1810
    sprintf(buff,"%s",share->normalized_path.str);
 
1811
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
 
1812
    break;
 
1813
  }
 
1814
  return;
 
1815
} /* open_table_error */
 
1816
 
 
1817
 
 
1818
        /*
 
1819
        ** fix a str_type to a array type
 
1820
        ** typeparts separated with some char. differents types are separated
 
1821
        ** with a '\0'
 
1822
        */
 
1823
 
 
1824
static void
 
1825
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
 
1826
                  char **names)
 
1827
{
 
1828
  char *type_name, *ptr;
 
1829
  char chr;
 
1830
 
 
1831
  ptr= *names;
 
1832
  while (types--)
 
1833
  {
 
1834
    point_to_type->name=0;
 
1835
    point_to_type->type_names= *array;
 
1836
 
 
1837
    if ((chr= *ptr))                    /* Test if empty type */
 
1838
    {
 
1839
      while ((type_name=strchr(ptr+1,chr)) != NULL)
 
1840
      {
 
1841
        *((*array)++) = ptr+1;
 
1842
        *type_name= '\0';               /* End string */
 
1843
        ptr=type_name;
 
1844
      }
 
1845
      ptr+=2;                           /* Skip end mark and last 0 */
 
1846
    }
 
1847
    else
 
1848
      ptr++;
 
1849
    point_to_type->count= (uint32_t) (*array - point_to_type->type_names);
 
1850
    point_to_type++;
 
1851
    *((*array)++)= NULL;                /* End of type */
 
1852
  }
 
1853
  *names=ptr;                           /* Update end */
 
1854
  return;
 
1855
} /* fix_type_pointers */
 
1856
 
 
1857
 
 
1858
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
 
1859
{
 
1860
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
215
1861
  if (!result)
216
1862
    return 0;
217
 
  result->count= strings.elements;
218
 
  result->name= "";
 
1863
  result->count=strings.elements;
 
1864
  result->name="";
219
1865
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
220
 
  
221
 
  if (!(result->type_names= (const char**) mem_root->alloc_root(nbytes)))
 
1866
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
222
1867
    return 0;
223
 
    
224
1868
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
225
 
 
226
1869
  List_iterator<String> it(strings);
227
1870
  String *tmp;
228
 
  for (uint32_t i= 0; (tmp= it++); i++)
 
1871
  for (uint32_t i=0; (tmp=it++) ; i++)
229
1872
  {
230
1873
    result->type_names[i]= tmp->ptr();
231
1874
    result->type_lengths[i]= tmp->length();
232
1875
  }
233
 
 
234
 
  result->type_names[result->count]= 0;   // End marker
 
1876
  result->type_names[result->count]= 0;         // End marker
235
1877
  result->type_lengths[result->count]= 0;
236
 
 
237
1878
  return result;
238
1879
}
239
1880
 
248
1889
  return (nr);
249
1890
} /* set_zone */
250
1891
 
 
1892
        /* Adjust number to next larger disk buffer */
 
1893
 
 
1894
ulong next_io_size(register ulong pos)
 
1895
{
 
1896
  register ulong offset;
 
1897
  if ((offset= pos & (IO_SIZE-1)))
 
1898
    return pos-offset+IO_SIZE;
 
1899
  return pos;
 
1900
} /* next_io_size */
 
1901
 
251
1902
 
252
1903
/*
253
1904
  Store an SQL quoted string.
270
1921
 
271
1922
  for (; pos != end ; pos++)
272
1923
  {
 
1924
#if defined(USE_MB)
273
1925
    uint32_t mblen;
274
1926
    if (use_mb(default_charset_info) &&
275
1927
        (mblen= my_ismbchar(default_charset_info, pos, end)))
276
1928
    {
277
1929
      res->append(pos, mblen);
278
 
      pos+= mblen - 1;
 
1930
      pos+= mblen;
279
1931
      if (pos >= end)
280
1932
        break;
281
1933
      continue;
282
1934
    }
 
1935
#endif
283
1936
 
284
1937
    switch (*pos) {
285
1938
    case 0:                             /* Must be escaped for 'mysql' */
311
1964
}
312
1965
 
313
1966
 
 
1967
/*
 
1968
  Set up column usage bitmaps for a temporary table
 
1969
 
 
1970
  IMPLEMENTATION
 
1971
    For temporary tables, we need one bitmap with all columns set and
 
1972
    a tmp_set bitmap to be used by things like filesort.
 
1973
*/
 
1974
 
 
1975
void Table::setup_tmp_table_column_bitmaps()
 
1976
{
 
1977
  /* write_set and all_set are copies of read_set */
 
1978
  def_write_set= def_read_set;
 
1979
  s->all_set= def_read_set;
 
1980
  this->s->all_set.set();
 
1981
  default_column_bitmaps();
 
1982
  read_set->set();
 
1983
}
 
1984
 
 
1985
 
 
1986
 
 
1987
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
 
1988
{
 
1989
  create_info->max_rows= s->max_rows;
 
1990
  create_info->min_rows= s->min_rows;
 
1991
  create_info->table_options= s->db_create_options;
 
1992
  create_info->avg_row_length= s->avg_row_length;
 
1993
  create_info->block_size= s->block_size;
 
1994
  create_info->row_type= s->row_type;
 
1995
  create_info->default_table_charset= s->table_charset;
 
1996
  create_info->table_charset= 0;
 
1997
  create_info->comment= s->comment;
 
1998
 
 
1999
  return;
 
2000
}
 
2001
 
314
2002
int rename_file_ext(const char * from,const char * to,const char * ext)
315
2003
{
316
2004
  string from_s, to_s;
319
2007
  from_s.append(ext);
320
2008
  to_s.append(to);
321
2009
  to_s.append(ext);
322
 
  return (internal::my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
2010
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
2011
}
 
2012
 
 
2013
 
 
2014
/*
 
2015
  Allocate string field in MEM_ROOT and return it as String
 
2016
 
 
2017
  SYNOPSIS
 
2018
    get_field()
 
2019
    mem         MEM_ROOT for allocating
 
2020
    field       Field for retrieving of string
 
2021
    res         result String
 
2022
 
 
2023
  RETURN VALUES
 
2024
    1   string is empty
 
2025
    0   all ok
 
2026
*/
 
2027
 
 
2028
bool get_field(MEM_ROOT *mem, Field *field, String *res)
 
2029
{
 
2030
  char buff[MAX_FIELD_WIDTH], *to;
 
2031
  String str(buff,sizeof(buff),&my_charset_bin);
 
2032
  uint32_t length;
 
2033
 
 
2034
  field->val_str(&str);
 
2035
  if (!(length= str.length()))
 
2036
  {
 
2037
    res->length(0);
 
2038
    return 1;
 
2039
  }
 
2040
  if (!(to= strmake_root(mem, str.ptr(), length)))
 
2041
    length= 0;                                  // Safety fix
 
2042
  res->set(to, length, ((Field_str*)field)->charset());
 
2043
  return 0;
 
2044
}
 
2045
 
 
2046
 
 
2047
/*
 
2048
  Allocate string field in MEM_ROOT and return it as NULL-terminated string
 
2049
 
 
2050
  SYNOPSIS
 
2051
    get_field()
 
2052
    mem         MEM_ROOT for allocating
 
2053
    field       Field for retrieving of string
 
2054
 
 
2055
  RETURN VALUES
 
2056
    NULL  string is empty
 
2057
    #      pointer to NULL-terminated string value of field
 
2058
*/
 
2059
 
 
2060
char *get_field(MEM_ROOT *mem, Field *field)
 
2061
{
 
2062
  char buff[MAX_FIELD_WIDTH], *to;
 
2063
  String str(buff,sizeof(buff),&my_charset_bin);
 
2064
  uint32_t length;
 
2065
 
 
2066
  field->val_str(&str);
 
2067
  length= str.length();
 
2068
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
 
2069
    return NULL;
 
2070
  memcpy(to,str.ptr(),(uint32_t) length);
 
2071
  to[length]=0;
 
2072
  return to;
 
2073
}
 
2074
 
 
2075
/*
 
2076
  DESCRIPTION
 
2077
    given a buffer with a key value, and a map of keyparts
 
2078
    that are present in this value, returns the length of the value
 
2079
*/
 
2080
uint32_t calculate_key_len(Table *table, uint32_t key,
 
2081
                       const unsigned char *,
 
2082
                       key_part_map keypart_map)
 
2083
{
 
2084
  /* works only with key prefixes */
 
2085
  assert(((keypart_map + 1) & keypart_map) == 0);
 
2086
 
 
2087
  KEY *key_info= table->s->key_info+key;
 
2088
  KEY_PART_INFO *key_part= key_info->key_part;
 
2089
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
 
2090
  uint32_t length= 0;
 
2091
 
 
2092
  while (key_part < end_key_part && keypart_map)
 
2093
  {
 
2094
    length+= key_part->store_length;
 
2095
    keypart_map >>= 1;
 
2096
    key_part++;
 
2097
  }
 
2098
  return length;
323
2099
}
324
2100
 
325
2101
/*
329
2105
    check_db_name()
330
2106
    org_name            Name of database and length
331
2107
 
 
2108
  NOTES
 
2109
    If lower_case_table_names is set then database is converted to lower case
 
2110
 
332
2111
  RETURN
333
 
    false error
334
 
    true ok
 
2112
    0   ok
 
2113
    1   error
335
2114
*/
336
2115
 
337
 
bool check_db_name(Session *session, identifier::Schema &schema_identifier)
 
2116
bool check_db_name(LEX_STRING *org_name)
338
2117
{
339
 
  if (not plugin::Authorization::isAuthorized(session->user(), schema_identifier))
340
 
  {
341
 
    return false;
342
 
  }
343
 
 
344
 
  return schema_identifier.isValid();
 
2118
  char *name= org_name->str;
 
2119
  uint32_t name_length= org_name->length;
 
2120
 
 
2121
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
 
2122
    return 1;
 
2123
 
 
2124
  if (lower_case_table_names && name != any_db)
 
2125
    my_casedn_str(files_charset_info, name);
 
2126
 
 
2127
  return check_identifier_name(org_name);
345
2128
}
346
2129
 
 
2130
 
347
2131
/*
348
2132
  Allow anything as a table name, as long as it doesn't contain an
349
2133
  ' ' at the end
350
2134
  returns 1 on error
351
2135
*/
 
2136
 
 
2137
 
352
2138
bool check_table_name(const char *name, uint32_t length)
353
2139
{
354
2140
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
372
2158
 
373
2159
  while (*name)
374
2160
  {
 
2161
#if defined(USE_MB) && defined(USE_MB_IDENT)
375
2162
    last_char_is_space= my_isspace(system_charset_info, *name);
376
2163
    if (use_mb(system_charset_info))
377
2164
    {
386
2173
        continue;
387
2174
      }
388
2175
    }
 
2176
#else
 
2177
    last_char_is_space= *name==' ';
 
2178
#endif
389
2179
    /*
390
2180
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
391
2181
      It is defined as 0xFF, which is a not valid byte in utf8.
401
2191
}
402
2192
 
403
2193
 
 
2194
/**
 
2195
  Checks whether a table is intact. Should be done *just* after the table has
 
2196
  been opened.
 
2197
 
 
2198
  @param[in] table             The table to check
 
2199
  @param[in] table_f_count     Expected number of columns in the table
 
2200
  @param[in] table_def         Expected structure of the table (column name
 
2201
                               and type)
 
2202
 
 
2203
  @retval  false  OK
 
2204
  @retval  TRUE   There was an error. An error message is output
 
2205
                  to the error log.  We do not push an error
 
2206
                  message into the error stack because this
 
2207
                  function is currently only called at start up,
 
2208
                  and such errors never reach the user.
 
2209
*/
 
2210
 
 
2211
bool
 
2212
Table::table_check_intact(const uint32_t table_f_count,
 
2213
                          const TABLE_FIELD_W_TYPE *table_def)
 
2214
{
 
2215
  uint32_t i;
 
2216
  bool error= false;
 
2217
  bool fields_diff_count;
 
2218
 
 
2219
  fields_diff_count= (s->fields != table_f_count);
 
2220
  if (fields_diff_count)
 
2221
  {
 
2222
 
 
2223
    /* previous MySQL version */
 
2224
    if (DRIZZLE_VERSION_ID > s->mysql_version)
 
2225
    {
 
2226
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
 
2227
                      alias, table_f_count, s->fields,
 
2228
                      s->mysql_version, DRIZZLE_VERSION_ID);
 
2229
      return(true);
 
2230
    }
 
2231
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
 
2232
    {
 
2233
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
 
2234
                      table_f_count, s->fields);
 
2235
      return(true);
 
2236
    }
 
2237
    /*
 
2238
      Something has definitely changed, but we're running an older
 
2239
      version of MySQL with new system tables.
 
2240
      Let's check column definitions. If a column was added at
 
2241
      the end of the table, then we don't care much since such change
 
2242
      is backward compatible.
 
2243
    */
 
2244
  }
 
2245
  char buffer[STRING_BUFFER_USUAL_SIZE];
 
2246
  for (i=0 ; i < table_f_count; i++, table_def++)
 
2247
  {
 
2248
    String sql_type(buffer, sizeof(buffer), system_charset_info);
 
2249
    sql_type.length(0);
 
2250
    if (i < s->fields)
 
2251
    {
 
2252
      Field *cur_field= this->field[i];
 
2253
 
 
2254
      if (strncmp(cur_field->field_name, table_def->name.str,
 
2255
                  table_def->name.length))
 
2256
      {
 
2257
        /*
 
2258
          Name changes are not fatal, we use ordinal numbers to access columns.
 
2259
          Still this can be a sign of a tampered table, output an error
 
2260
          to the error log.
 
2261
        */
 
2262
        errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
 
2263
                        "expected column '%s' at position %d, found '%s'."),
 
2264
                        s->db.str, alias, table_def->name.str, i,
 
2265
                        cur_field->field_name);
 
2266
      }
 
2267
      cur_field->sql_type(sql_type);
 
2268
      /*
 
2269
        Generally, if column types don't match, then something is
 
2270
        wrong.
 
2271
 
 
2272
        However, we only compare column definitions up to the
 
2273
        length of the original definition, since we consider the
 
2274
        following definitions compatible:
 
2275
 
 
2276
        1. DATETIME and DATETIM
 
2277
        2. INT(11) and INT(11
 
2278
        3. SET('one', 'two') and SET('one', 'two', 'more')
 
2279
 
 
2280
        For SETs or ENUMs, if the same prefix is there it's OK to
 
2281
        add more elements - they will get higher ordinal numbers and
 
2282
        the new table definition is backward compatible with the
 
2283
        original one.
 
2284
       */
 
2285
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
 
2286
                  table_def->type.length - 1))
 
2287
      {
 
2288
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2289
                      _("Incorrect definition of table %s.%s: "
 
2290
                        "expected column '%s' at position %d to have type "
 
2291
                        "%s, found type %s."),
 
2292
                      s->db.str, alias,
 
2293
                      table_def->name.str, i, table_def->type.str,
 
2294
                      sql_type.c_ptr_safe());
 
2295
        error= true;
 
2296
      }
 
2297
      else if (table_def->cset.str && !cur_field->has_charset())
 
2298
      {
 
2299
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2300
                      _("Incorrect definition of table %s.%s: "
 
2301
                        "expected the type of column '%s' at position %d "
 
2302
                        "to have character set '%s' but the type has no "
 
2303
                        "character set."),
 
2304
                      s->db.str, alias,
 
2305
                      table_def->name.str, i, table_def->cset.str);
 
2306
        error= true;
 
2307
      }
 
2308
      else if (table_def->cset.str &&
 
2309
               strcmp(cur_field->charset()->csname, table_def->cset.str))
 
2310
      {
 
2311
        errmsg_printf(ERRMSG_LVL_ERROR,
 
2312
                      _("Incorrect definition of table %s.%s: "
 
2313
                        "expected the type of column '%s' at position %d "
 
2314
                        "to have character set '%s' but found "
 
2315
                        "character set '%s'."),
 
2316
                      s->db.str, alias,
 
2317
                      table_def->name.str, i, table_def->cset.str,
 
2318
                      cur_field->charset()->csname);
 
2319
        error= true;
 
2320
      }
 
2321
    }
 
2322
    else
 
2323
    {
 
2324
      errmsg_printf(ERRMSG_LVL_ERROR,
 
2325
                    _("Incorrect definition of table %s.%s: "
 
2326
                      "expected column '%s' at position %d to have type %s "
 
2327
                      " but the column is not found."),
 
2328
                    s->db.str, alias,
 
2329
                    table_def->name.str, i, table_def->type.str);
 
2330
      error= true;
 
2331
    }
 
2332
  }
 
2333
  return(error);
 
2334
}
 
2335
 
 
2336
 
 
2337
/*
 
2338
  Create Item_field for each column in the table.
 
2339
 
 
2340
  SYNPOSIS
 
2341
    Table::fill_item_list()
 
2342
      item_list          a pointer to an empty list used to store items
 
2343
 
 
2344
  DESCRIPTION
 
2345
    Create Item_field object for each column in the table and
 
2346
    initialize it with the corresponding Field. New items are
 
2347
    created in the current Session memory root.
 
2348
 
 
2349
  RETURN VALUE
 
2350
    0                    success
 
2351
    1                    out of memory
 
2352
*/
 
2353
 
 
2354
bool Table::fill_item_list(List<Item> *item_list) const
 
2355
{
 
2356
  /*
 
2357
    All Item_field's created using a direct pointer to a field
 
2358
    are fixed in Item_field constructor.
 
2359
  */
 
2360
  for (Field **ptr= field; *ptr; ptr++)
 
2361
  {
 
2362
    Item_field *item= new Item_field(*ptr);
 
2363
    if (!item || item_list->push_back(item))
 
2364
      return true;
 
2365
  }
 
2366
  return false;
 
2367
}
 
2368
 
 
2369
/*
 
2370
  Reset an existing list of Item_field items to point to the
 
2371
  Fields of this table.
 
2372
 
 
2373
  SYNPOSIS
 
2374
    Table::fill_item_list()
 
2375
      item_list          a non-empty list with Item_fields
 
2376
 
 
2377
  DESCRIPTION
 
2378
    This is a counterpart of fill_item_list used to redirect
 
2379
    Item_fields to the fields of a newly created table.
 
2380
    The caller must ensure that number of items in the item_list
 
2381
    is the same as the number of columns in the table.
 
2382
*/
 
2383
 
 
2384
void Table::reset_item_list(List<Item> *item_list) const
 
2385
{
 
2386
  List_iterator_fast<Item> it(*item_list);
 
2387
  for (Field **ptr= field; *ptr; ptr++)
 
2388
  {
 
2389
    Item_field *item_field= (Item_field*) it++;
 
2390
    assert(item_field != 0);
 
2391
    item_field->reset_field(*ptr);
 
2392
  }
 
2393
}
 
2394
 
 
2395
 
 
2396
/*
 
2397
  Find underlying base tables (TableList) which represent given
 
2398
  table_to_find (Table)
 
2399
 
 
2400
  SYNOPSIS
 
2401
    TableList::find_underlying_table()
 
2402
    table_to_find table to find
 
2403
 
 
2404
  RETURN
 
2405
    0  table is not found
 
2406
    found table reference
 
2407
*/
 
2408
 
 
2409
TableList *TableList::find_underlying_table(Table *table_to_find)
 
2410
{
 
2411
  /* is this real table and table which we are looking for? */
 
2412
  if (table == table_to_find && merge_underlying_list == 0)
 
2413
    return this;
 
2414
 
 
2415
  for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
 
2416
  {
 
2417
    TableList *result;
 
2418
    if ((result= tbl->find_underlying_table(table_to_find)))
 
2419
      return result;
 
2420
  }
 
2421
  return 0;
 
2422
}
 
2423
 
 
2424
/*
 
2425
  cleunup items belonged to view fields translation table
 
2426
 
 
2427
  SYNOPSIS
 
2428
    TableList::cleanup_items()
 
2429
*/
 
2430
 
 
2431
void TableList::cleanup_items()
 
2432
{
 
2433
}
 
2434
 
 
2435
 
 
2436
bool TableList::placeholder()
 
2437
{
 
2438
  return derived || schema_table || (create && !table->getDBStat()) || !table;
 
2439
}
 
2440
 
 
2441
 
 
2442
/*
 
2443
  Set insert_values buffer
 
2444
 
 
2445
  SYNOPSIS
 
2446
    set_insert_values()
 
2447
    mem_root   memory pool for allocating
 
2448
 
 
2449
  RETURN
 
2450
    false - OK
 
2451
    TRUE  - out of memory
 
2452
*/
 
2453
 
 
2454
bool TableList::set_insert_values(MEM_ROOT *mem_root)
 
2455
{
 
2456
  if (table)
 
2457
  {
 
2458
    if (!table->insert_values &&
 
2459
        !(table->insert_values= (unsigned char *)alloc_root(mem_root,
 
2460
                                                   table->s->rec_buff_length)))
 
2461
      return true;
 
2462
  }
 
2463
 
 
2464
  return false;
 
2465
}
 
2466
 
 
2467
 
 
2468
/*
 
2469
  Test if this is a leaf with respect to name resolution.
 
2470
 
 
2471
  SYNOPSIS
 
2472
    TableList::is_leaf_for_name_resolution()
 
2473
 
 
2474
  DESCRIPTION
 
2475
    A table reference is a leaf with respect to name resolution if
 
2476
    it is either a leaf node in a nested join tree (table, view,
 
2477
    schema table, subquery), or an inner node that represents a
 
2478
    NATURAL/USING join, or a nested join with materialized join
 
2479
    columns.
 
2480
 
 
2481
  RETURN
 
2482
    TRUE if a leaf, false otherwise.
 
2483
*/
 
2484
bool TableList::is_leaf_for_name_resolution()
 
2485
{
 
2486
  return (is_natural_join || is_join_columns_complete || !nested_join);
 
2487
}
 
2488
 
 
2489
 
 
2490
/*
 
2491
  Retrieve the first (left-most) leaf in a nested join tree with
 
2492
  respect to name resolution.
 
2493
 
 
2494
  SYNOPSIS
 
2495
    TableList::first_leaf_for_name_resolution()
 
2496
 
 
2497
  DESCRIPTION
 
2498
    Given that 'this' is a nested table reference, recursively walk
 
2499
    down the left-most children of 'this' until we reach a leaf
 
2500
    table reference with respect to name resolution.
 
2501
 
 
2502
  IMPLEMENTATION
 
2503
    The left-most child of a nested table reference is the last element
 
2504
    in the list of children because the children are inserted in
 
2505
    reverse order.
 
2506
 
 
2507
  RETURN
 
2508
    If 'this' is a nested table reference - the left-most child of
 
2509
      the tree rooted in 'this',
 
2510
    else return 'this'
 
2511
*/
 
2512
 
 
2513
TableList *TableList::first_leaf_for_name_resolution()
 
2514
{
 
2515
  TableList *cur_table_ref= NULL;
 
2516
  nested_join_st *cur_nested_join;
 
2517
 
 
2518
  if (is_leaf_for_name_resolution())
 
2519
    return this;
 
2520
  assert(nested_join);
 
2521
 
 
2522
  for (cur_nested_join= nested_join;
 
2523
       cur_nested_join;
 
2524
       cur_nested_join= cur_table_ref->nested_join)
 
2525
  {
 
2526
    List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
2527
    cur_table_ref= it++;
 
2528
    /*
 
2529
      If the current nested join is a RIGHT JOIN, the operands in
 
2530
      'join_list' are in reverse order, thus the first operand is
 
2531
      already at the front of the list. Otherwise the first operand
 
2532
      is in the end of the list of join operands.
 
2533
    */
 
2534
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
2535
    {
 
2536
      TableList *next;
 
2537
      while ((next= it++))
 
2538
        cur_table_ref= next;
 
2539
    }
 
2540
    if (cur_table_ref->is_leaf_for_name_resolution())
 
2541
      break;
 
2542
  }
 
2543
  return cur_table_ref;
 
2544
}
 
2545
 
 
2546
 
 
2547
/*
 
2548
  Retrieve the last (right-most) leaf in a nested join tree with
 
2549
  respect to name resolution.
 
2550
 
 
2551
  SYNOPSIS
 
2552
    TableList::last_leaf_for_name_resolution()
 
2553
 
 
2554
  DESCRIPTION
 
2555
    Given that 'this' is a nested table reference, recursively walk
 
2556
    down the right-most children of 'this' until we reach a leaf
 
2557
    table reference with respect to name resolution.
 
2558
 
 
2559
  IMPLEMENTATION
 
2560
    The right-most child of a nested table reference is the first
 
2561
    element in the list of children because the children are inserted
 
2562
    in reverse order.
 
2563
 
 
2564
  RETURN
 
2565
    - If 'this' is a nested table reference - the right-most child of
 
2566
      the tree rooted in 'this',
 
2567
    - else - 'this'
 
2568
*/
 
2569
 
 
2570
TableList *TableList::last_leaf_for_name_resolution()
 
2571
{
 
2572
  TableList *cur_table_ref= this;
 
2573
  nested_join_st *cur_nested_join;
 
2574
 
 
2575
  if (is_leaf_for_name_resolution())
 
2576
    return this;
 
2577
  assert(nested_join);
 
2578
 
 
2579
  for (cur_nested_join= nested_join;
 
2580
       cur_nested_join;
 
2581
       cur_nested_join= cur_table_ref->nested_join)
 
2582
  {
 
2583
    cur_table_ref= cur_nested_join->join_list.head();
 
2584
    /*
 
2585
      If the current nested is a RIGHT JOIN, the operands in
 
2586
      'join_list' are in reverse order, thus the last operand is in the
 
2587
      end of the list.
 
2588
    */
 
2589
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
2590
    {
 
2591
      List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
2592
      TableList *next;
 
2593
      cur_table_ref= it++;
 
2594
      while ((next= it++))
 
2595
        cur_table_ref= next;
 
2596
    }
 
2597
    if (cur_table_ref->is_leaf_for_name_resolution())
 
2598
      break;
 
2599
  }
 
2600
  return cur_table_ref;
 
2601
}
 
2602
 
 
2603
 
404
2604
/*****************************************************************************
405
2605
  Functions to handle column usage bitmaps (read_set, write_set etc...)
406
2606
*****************************************************************************/
410
2610
void Table::clear_column_bitmaps()
411
2611
{
412
2612
  /*
413
 
    Reset column read/write usage. It's identical to:
414
 
    bitmap_clear_all(&table->def_read_set);
415
 
    bitmap_clear_all(&table->def_write_set);
 
2613
    Reset column read/write usage.
416
2614
  */
417
2615
  def_read_set.reset();
418
 
  def_write_set.reset();
419
 
  column_bitmaps_set(def_read_set, def_write_set);
 
2616
  def_write_set.reset(); /* TODO: is this needed here? */
 
2617
  column_bitmaps_set(&def_read_set, &def_write_set);
420
2618
}
421
2619
 
422
2620
 
423
2621
/*
424
 
  Tell Cursor we are going to call position() and rnd_pos() later.
 
2622
  Tell handler we are going to call position() and rnd_pos() later.
425
2623
 
426
2624
  NOTES:
427
2625
  This is needed for handlers that uses the primary key to find the
431
2629
 
432
2630
void Table::prepare_for_position()
433
2631
{
434
 
 
435
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
436
 
      getShare()->hasPrimaryKey())
 
2632
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
 
2633
      s->primary_key < MAX_KEY)
437
2634
  {
438
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
2635
    mark_columns_used_by_index_no_reset(s->primary_key);
439
2636
  }
440
2637
  return;
441
2638
}
453
2650
 
454
2651
void Table::mark_columns_used_by_index(uint32_t index)
455
2652
{
456
 
  boost::dynamic_bitset<> *bitmap= &tmp_set;
 
2653
  bitset<MAX_FIELDS> *bitmap= &tmp_set;
457
2654
 
458
 
  (void) cursor->extra(HA_EXTRA_KEYREAD);
 
2655
  (void) file->extra(HA_EXTRA_KEYREAD);
459
2656
  bitmap->reset();
460
 
  mark_columns_used_by_index_no_reset(index, *bitmap);
461
 
  column_bitmaps_set(*bitmap, *bitmap);
 
2657
  mark_columns_used_by_index_no_reset(index, bitmap);
 
2658
  column_bitmaps_set(bitmap, bitmap);
462
2659
  return;
463
2660
}
464
2661
 
478
2675
{
479
2676
 
480
2677
  key_read= 0;
481
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
2678
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
482
2679
  default_column_bitmaps();
483
 
  return;
484
2680
}
485
2681
 
486
2682
 
490
2686
 
491
2687
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
492
2688
{
493
 
    mark_columns_used_by_index_no_reset(index, *read_set);
 
2689
    mark_columns_used_by_index_no_reset(index, read_set);
494
2690
}
495
2691
 
496
 
 
497
2692
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
498
 
                                                boost::dynamic_bitset<>& bitmap)
 
2693
                                                bitset<MAX_FIELDS> *bitmap)
499
2694
{
500
 
  KeyPartInfo *key_part= key_info[index].key_part;
501
 
  KeyPartInfo *key_part_end= (key_part + key_info[index].key_parts);
502
 
  for (; key_part != key_part_end; key_part++)
503
 
  {
504
 
    if (! bitmap.empty())
505
 
      bitmap.set(key_part->fieldnr-1);
506
 
  }
 
2695
  KEY_PART_INFO *key_part= key_info[index].key_part;
 
2696
  KEY_PART_INFO *key_part_end= (key_part +
 
2697
                                key_info[index].key_parts);
 
2698
  for (;key_part != key_part_end; key_part++)
 
2699
    bitmap->set(key_part->fieldnr-1);
507
2700
}
508
2701
 
509
2702
 
522
2715
    We must set bit in read set as update_auto_increment() is using the
523
2716
    store() to check overflow of auto_increment values
524
2717
  */
525
 
  setReadSet(found_next_number_field->position());
526
 
  setWriteSet(found_next_number_field->position());
527
 
  if (getShare()->next_number_keypart)
528
 
    mark_columns_used_by_index_no_reset(getShare()->next_number_index);
 
2718
  read_set->set(found_next_number_field->field_index);
 
2719
  write_set->set(found_next_number_field->field_index);
 
2720
  if (s->next_number_keypart)
 
2721
    mark_columns_used_by_index_no_reset(s->next_number_index);
529
2722
}
530
2723
 
531
2724
 
550
2743
void Table::mark_columns_needed_for_delete()
551
2744
{
552
2745
  /*
553
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2746
    If the handler has no cursor capabilites, or we have row-based
554
2747
    replication active for the current statement, we have to read
555
2748
    either the primary key, the hidden primary key or all columns to
556
2749
    be able to do an delete
557
2750
 
558
2751
  */
559
 
  if (not getShare()->hasPrimaryKey())
 
2752
  if (s->primary_key == MAX_KEY)
560
2753
  {
561
2754
    /* fallback to use all columns in the table to identify row */
562
2755
    use_all_columns();
563
2756
    return;
564
2757
  }
565
2758
  else
566
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
2759
    mark_columns_used_by_index_no_reset(s->primary_key);
567
2760
 
568
2761
  /* If we the engine wants all predicates we mark all keys */
569
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2762
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
570
2763
  {
571
2764
    Field **reg_field;
572
2765
    for (reg_field= field ; *reg_field ; reg_field++)
573
2766
    {
574
2767
      if ((*reg_field)->flags & PART_KEY_FLAG)
575
 
        setReadSet((*reg_field)->position());
 
2768
        read_set->set((*reg_field)->field_index);
576
2769
    }
577
2770
  }
578
2771
}
590
2783
    if neeed, either the primary key column or all columns to be read.
591
2784
    (see mark_columns_needed_for_delete() for details)
592
2785
 
593
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
2786
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
594
2787
    mark all USED key columns as 'to-be-read'. This allows the engine to
595
2788
    loop over the given record to find all changed keys and doesn't have to
596
2789
    retrieve the row again.
599
2792
void Table::mark_columns_needed_for_update()
600
2793
{
601
2794
  /*
602
 
    If the Cursor has no cursor capabilites, or we have row-based
 
2795
    If the handler has no cursor capabilites, or we have row-based
603
2796
    logging active for the current statement, we have to read either
604
2797
    the primary key, the hidden primary key or all columns to be
605
2798
    able to do an update
606
2799
  */
607
 
  if (not getShare()->hasPrimaryKey())
 
2800
  if (s->primary_key == MAX_KEY)
608
2801
  {
609
2802
    /* fallback to use all columns in the table to identify row */
610
2803
    use_all_columns();
611
2804
    return;
612
2805
  }
613
2806
  else
614
 
    mark_columns_used_by_index_no_reset(getShare()->getPrimaryKey());
 
2807
    mark_columns_used_by_index_no_reset(s->primary_key);
615
2808
 
616
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2809
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
617
2810
  {
618
2811
    /* Mark all used key columns for read */
619
2812
    Field **reg_field;
621
2814
    {
622
2815
      /* Merge keys is all keys that had a column refered to in the query */
623
2816
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
624
 
        setReadSet((*reg_field)->position());
 
2817
        read_set->set((*reg_field)->field_index);
625
2818
    }
626
2819
  }
627
2820
 
629
2822
 
630
2823
 
631
2824
/*
632
 
  Mark columns the Cursor needs for doing an insert
 
2825
  Mark columns the handler needs for doing an insert
633
2826
 
634
2827
  For now, this is used to mark fields used by the trigger
635
2828
  as changed.
642
2835
}
643
2836
 
644
2837
 
 
2838
/*
 
2839
  Cleanup this table for re-execution.
 
2840
 
 
2841
  SYNOPSIS
 
2842
    TableList::reinit_before_use()
 
2843
*/
 
2844
 
 
2845
void TableList::reinit_before_use(Session *session)
 
2846
{
 
2847
  /*
 
2848
    Reset old pointers to TABLEs: they are not valid since the tables
 
2849
    were closed in the end of previous prepare or execute call.
 
2850
  */
 
2851
  table= 0;
 
2852
  /* Reset is_schema_table_processed value(needed for I_S tables */
 
2853
  schema_table_state= NOT_PROCESSED;
 
2854
 
 
2855
  TableList *embedded; /* The table at the current level of nesting. */
 
2856
  TableList *parent_embedding= this; /* The parent nested table reference. */
 
2857
  do
 
2858
  {
 
2859
    embedded= parent_embedding;
 
2860
    if (embedded->prep_on_expr)
 
2861
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
 
2862
    parent_embedding= embedded->embedding;
 
2863
  }
 
2864
  while (parent_embedding &&
 
2865
         parent_embedding->nested_join->join_list.head() == embedded);
 
2866
}
 
2867
 
 
2868
/*
 
2869
  Return subselect that contains the FROM list this table is taken from
 
2870
 
 
2871
  SYNOPSIS
 
2872
    TableList::containing_subselect()
 
2873
 
 
2874
  RETURN
 
2875
    Subselect item for the subquery that contains the FROM list
 
2876
    this table is taken from if there is any
 
2877
    0 - otherwise
 
2878
 
 
2879
*/
 
2880
 
 
2881
Item_subselect *TableList::containing_subselect()
 
2882
{
 
2883
  return (select_lex ? select_lex->master_unit()->item : 0);
 
2884
}
 
2885
 
 
2886
/*
 
2887
  Compiles the tagged hints list and fills up the bitmasks.
 
2888
 
 
2889
  SYNOPSIS
 
2890
    process_index_hints()
 
2891
      table         the Table to operate on.
 
2892
 
 
2893
  DESCRIPTION
 
2894
    The parser collects the index hints for each table in a "tagged list"
 
2895
    (TableList::index_hints). Using the information in this tagged list
 
2896
    this function sets the members Table::keys_in_use_for_query,
 
2897
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
 
2898
    Table::force_index and Table::covering_keys.
 
2899
 
 
2900
    Current implementation of the runtime does not allow mixing FORCE INDEX
 
2901
    and USE INDEX, so this is checked here. Then the FORCE INDEX list
 
2902
    (if non-empty) is appended to the USE INDEX list and a flag is set.
 
2903
 
 
2904
    Multiple hints of the same kind are processed so that each clause
 
2905
    is applied to what is computed in the previous clause.
 
2906
    For example:
 
2907
        USE INDEX (i1) USE INDEX (i2)
 
2908
    is equivalent to
 
2909
        USE INDEX (i1,i2)
 
2910
    and means "consider only i1 and i2".
 
2911
 
 
2912
    Similarly
 
2913
        USE INDEX () USE INDEX (i1)
 
2914
    is equivalent to
 
2915
        USE INDEX (i1)
 
2916
    and means "consider only the index i1"
 
2917
 
 
2918
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
 
2919
    not an error.
 
2920
 
 
2921
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
 
2922
    order:
 
2923
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
 
2924
      2. All IGNORE INDEX
 
2925
 
 
2926
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
 
2927
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
 
2928
 
 
2929
    As an optimization if there is a covering index, and we have
 
2930
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part,
 
2931
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
 
2932
 
 
2933
  RETURN VALUE
 
2934
    false                no errors found
 
2935
    TRUE                 found and reported an error.
 
2936
*/
 
2937
bool TableList::process_index_hints(Table *tbl)
 
2938
{
 
2939
  /* initialize the result variables */
 
2940
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by=
 
2941
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
 
2942
 
 
2943
  /* index hint list processing */
 
2944
  if (index_hints)
 
2945
  {
 
2946
    key_map index_join[INDEX_HINT_FORCE + 1];
 
2947
    key_map index_order[INDEX_HINT_FORCE + 1];
 
2948
    key_map index_group[INDEX_HINT_FORCE + 1];
 
2949
    Index_hint *hint;
 
2950
    int type;
 
2951
    bool have_empty_use_join= false, have_empty_use_order= false,
 
2952
         have_empty_use_group= false;
 
2953
    List_iterator <Index_hint> iter(*index_hints);
 
2954
 
 
2955
    /* initialize temporary variables used to collect hints of each kind */
 
2956
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
 
2957
    {
 
2958
      index_join[type].reset();
 
2959
      index_order[type].reset();
 
2960
      index_group[type].reset();
 
2961
    }
 
2962
 
 
2963
    /* iterate over the hints list */
 
2964
    while ((hint= iter++))
 
2965
    {
 
2966
      uint32_t pos;
 
2967
 
 
2968
      /* process empty USE INDEX () */
 
2969
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
 
2970
      {
 
2971
        if (hint->clause & INDEX_HINT_MASK_JOIN)
 
2972
        {
 
2973
          index_join[hint->type].reset();
 
2974
          have_empty_use_join= true;
 
2975
        }
 
2976
        if (hint->clause & INDEX_HINT_MASK_ORDER)
 
2977
        {
 
2978
          index_order[hint->type].reset();
 
2979
          have_empty_use_order= true;
 
2980
        }
 
2981
        if (hint->clause & INDEX_HINT_MASK_GROUP)
 
2982
        {
 
2983
          index_group[hint->type].reset();
 
2984
          have_empty_use_group= true;
 
2985
        }
 
2986
        continue;
 
2987
      }
 
2988
 
 
2989
      /*
 
2990
        Check if an index with the given name exists and get his offset in
 
2991
        the keys bitmask for the table
 
2992
      */
 
2993
      if (tbl->s->keynames.type_names == 0 ||
 
2994
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
 
2995
                          hint->key_name.length, 1)) <= 0)
 
2996
      {
 
2997
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
 
2998
        return 1;
 
2999
      }
 
3000
 
 
3001
      pos--;
 
3002
 
 
3003
      /* add to the appropriate clause mask */
 
3004
      if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3005
        index_join[hint->type].set(pos);
 
3006
      if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3007
        index_order[hint->type].set(pos);
 
3008
      if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3009
        index_group[hint->type].set(pos);
 
3010
    }
 
3011
 
 
3012
    /* cannot mix USE INDEX and FORCE INDEX */
 
3013
    if ((index_join[INDEX_HINT_FORCE].any() ||
 
3014
         index_order[INDEX_HINT_FORCE].any() ||
 
3015
         index_group[INDEX_HINT_FORCE].any()) &&
 
3016
        (index_join[INDEX_HINT_USE].any() ||  have_empty_use_join ||
 
3017
         index_order[INDEX_HINT_USE].any() || have_empty_use_order ||
 
3018
         index_group[INDEX_HINT_USE].any() || have_empty_use_group))
 
3019
    {
 
3020
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
 
3021
               index_hint_type_name[INDEX_HINT_FORCE]);
 
3022
      return 1;
 
3023
    }
 
3024
 
 
3025
    /* process FORCE INDEX as USE INDEX with a flag */
 
3026
    if (index_join[INDEX_HINT_FORCE].any() ||
 
3027
        index_order[INDEX_HINT_FORCE].any() ||
 
3028
        index_group[INDEX_HINT_FORCE].any())
 
3029
    {
 
3030
      tbl->force_index= true;
 
3031
      index_join[INDEX_HINT_USE]|= index_join[INDEX_HINT_FORCE];
 
3032
      index_order[INDEX_HINT_USE]|= index_order[INDEX_HINT_FORCE];
 
3033
      index_group[INDEX_HINT_USE]|= index_group[INDEX_HINT_FORCE];
 
3034
    }
 
3035
 
 
3036
    /* apply USE INDEX */
 
3037
    if (index_join[INDEX_HINT_USE].any() || have_empty_use_join)
 
3038
      tbl->keys_in_use_for_query&= index_join[INDEX_HINT_USE];
 
3039
    if (index_order[INDEX_HINT_USE].any() || have_empty_use_order)
 
3040
      tbl->keys_in_use_for_order_by&= index_order[INDEX_HINT_USE];
 
3041
    if (index_group[INDEX_HINT_USE].any() || have_empty_use_group)
 
3042
      tbl->keys_in_use_for_group_by&= index_group[INDEX_HINT_USE];
 
3043
 
 
3044
    /* apply IGNORE INDEX */
 
3045
    key_map_subtract(tbl->keys_in_use_for_query, index_join[INDEX_HINT_IGNORE]);
 
3046
    key_map_subtract(tbl->keys_in_use_for_order_by, index_order[INDEX_HINT_IGNORE]);
 
3047
    key_map_subtract(tbl->keys_in_use_for_group_by, index_group[INDEX_HINT_IGNORE]);
 
3048
  }
 
3049
 
 
3050
  /* make sure covering_keys don't include indexes disabled with a hint */
 
3051
  tbl->covering_keys&= tbl->keys_in_use_for_query;
 
3052
  return 0;
 
3053
}
 
3054
 
645
3055
 
646
3056
size_t Table::max_row_length(const unsigned char *data)
647
3057
{
653
3063
  {
654
3064
    Field_blob* const blob= (Field_blob*) field[*ptr];
655
3065
    length+= blob->get_length((const unsigned char*)
656
 
                              (data + blob->offset(getInsertRecord()))) +
 
3066
                              (data + blob->offset(record[0]))) +
657
3067
      HA_KEY_BLOB_LENGTH;
658
3068
  }
659
3069
  return length;
660
3070
}
661
3071
 
662
 
void Table::setVariableWidth(void)
663
 
{
664
 
  assert(in_use);
665
 
  if (in_use && in_use->lex->sql_command == SQLCOM_CREATE_TABLE)
666
 
  {
667
 
    getMutableShare()->setVariableWidth();
668
 
    return;
669
 
  }
670
 
 
671
 
  assert(0); // Programming error, you can't set this on a plain old Table.
672
 
}
673
 
 
674
3072
/****************************************************************************
675
3073
 Functions for creating temporary tables.
676
3074
****************************************************************************/
 
3075
 
 
3076
 
 
3077
/* Prototypes */
 
3078
void free_tmp_table(Session *session, Table *entry);
 
3079
 
677
3080
/**
678
3081
  Create field for temporary table from given field.
679
3082
 
680
 
  @param session               Thread Cursor
 
3083
  @param session               Thread handler
681
3084
  @param org_field    field from which new field will be created
682
3085
  @param name         New field name
683
3086
  @param table         Temporary table
708
3111
  */
709
3112
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
710
3113
      (org_field->flags & BLOB_FLAG))
711
 
  {
712
 
    table->setVariableWidth();
713
3114
    new_field= new Field_varstring(convert_blob_length,
714
3115
                                   org_field->maybe_null(),
715
 
                                   org_field->field_name,
 
3116
                                   org_field->field_name, table->s,
716
3117
                                   org_field->charset());
717
 
  }
718
3118
  else
719
 
  {
720
3119
    new_field= org_field->new_field(session->mem_root, table,
721
 
                                    table == org_field->getTable());
722
 
  }
 
3120
                                    table == org_field->table);
723
3121
  if (new_field)
724
3122
  {
725
3123
    new_field->init(table);
732
3130
    if (org_field->maybe_null() || (item && item->maybe_null))
733
3131
      new_field->flags&= ~NOT_NULL_FLAG;        // Because of outer join
734
3132
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
735
 
      table->getMutableShare()->db_create_options|= HA_OPTION_PACK_RECORD;
 
3133
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
736
3134
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
737
3135
      ((Field_double *) new_field)->not_fixed= true;
738
3136
  }
741
3139
 
742
3140
 
743
3141
/**
 
3142
  Create field for information schema table.
 
3143
 
 
3144
  @param session                Thread handler
 
3145
  @param table          Temporary table
 
3146
  @param item           Item to create a field for
 
3147
 
 
3148
  @retval
 
3149
    0                   on error
 
3150
  @retval
 
3151
    new_created field
 
3152
*/
 
3153
 
 
3154
Field *create_tmp_field_for_schema(Session *, Item *item, Table *table)
 
3155
{
 
3156
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
3157
  {
 
3158
    Field *field;
 
3159
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
3160
      field= new Field_blob(item->max_length, item->maybe_null,
 
3161
                            item->name, item->collation.collation);
 
3162
    else
 
3163
      field= new Field_varstring(item->max_length, item->maybe_null,
 
3164
                                 item->name,
 
3165
                                 table->s, item->collation.collation);
 
3166
    if (field)
 
3167
      field->init(table);
 
3168
    return field;
 
3169
  }
 
3170
  return item->tmp_table_field_from_field_type(table, 0);
 
3171
}
 
3172
 
 
3173
 
 
3174
/**
744
3175
  Create a temp table according to a field list.
745
3176
 
746
3177
  Given field pointers are changed to point at tmp_table for
772
3203
 
773
3204
Table *
774
3205
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
775
 
                 Order *group, bool distinct, bool save_sum_fields,
 
3206
                 order_st *group, bool distinct, bool save_sum_fields,
776
3207
                 uint64_t select_options, ha_rows rows_limit,
777
 
                 const char *table_alias)
 
3208
                 char *table_alias)
778
3209
{
779
 
  memory::Root *mem_root_save;
 
3210
  MEM_ROOT *mem_root_save, own_root;
 
3211
  Table *table;
 
3212
  TableShare *share;
780
3213
  uint  i,field_count,null_count,null_pack_length;
781
3214
  uint32_t  copy_func_count= param->func_count;
782
3215
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
783
3216
  uint32_t  blob_count,group_null_items, string_count;
 
3217
  uint32_t  temp_pool_slot= BIT_NONE;
784
3218
  uint32_t fieldnr= 0;
785
3219
  ulong reclength, string_total_length;
786
 
  bool  using_unique_constraint= false;
787
 
  bool  use_packed_rows= true;
 
3220
  bool  using_unique_constraint= 0;
 
3221
  bool  use_packed_rows= 0;
788
3222
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
 
3223
  char  *tmpname,path[FN_REFLEN];
789
3224
  unsigned char *pos, *group_buff;
790
3225
  unsigned char *null_flags;
791
3226
  Field **reg_field, **from_field, **default_field;
792
 
  CopyField *copy= 0;
793
 
  KeyInfo *keyinfo;
794
 
  KeyPartInfo *key_part_info;
 
3227
  uint32_t *blob_field;
 
3228
  Copy_field *copy=0;
 
3229
  KEY *keyinfo;
 
3230
  KEY_PART_INFO *key_part_info;
795
3231
  Item **copy_func;
796
3232
  MI_COLUMNDEF *recinfo;
797
3233
  uint32_t total_uneven_bit_length= 0;
798
3234
  bool force_copy_fields= param->force_copy_fields;
799
 
  uint64_t max_rows= 0;
800
 
 
801
 
  session->status_var.created_tmp_tables++;
 
3235
 
 
3236
  status_var_increment(session->status_var.created_tmp_tables);
 
3237
 
 
3238
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
 
3239
    setNextBit(temp_pool);
 
3240
 
 
3241
  if (temp_pool_slot != BIT_NONE) // we got a slot
 
3242
    sprintf(path, "%s_%lx_%i", TMP_FILE_PREFIX,
 
3243
            (unsigned long)current_pid, temp_pool_slot);
 
3244
  else
 
3245
  {
 
3246
    /* if we run out of slots or we are not using tempool */
 
3247
    sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
 
3248
            session->thread_id, session->tmp_table++);
 
3249
  }
 
3250
 
 
3251
  /*
 
3252
    No need to change table name to lower case as we are only creating
 
3253
    MyISAM or HEAP tables here
 
3254
  */
 
3255
  fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3256
 
802
3257
 
803
3258
  if (group)
804
3259
  {
805
 
    if (! param->quick_group)
806
 
    {
807
 
      group= 0;                                 // Can't use group key
808
 
    }
809
 
    else for (Order *tmp=group ; tmp ; tmp=tmp->next)
 
3260
    if (!param->quick_group)
 
3261
      group=0;                                  // Can't use group key
 
3262
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
810
3263
    {
811
3264
      /*
812
3265
        marker == 4 means two things:
816
3269
      */
817
3270
      (*tmp->item)->marker= 4;
818
3271
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
819
 
        using_unique_constraint= true;
 
3272
        using_unique_constraint=1;
820
3273
    }
821
3274
    if (param->group_length >= MAX_BLOB_WIDTH)
822
 
      using_unique_constraint= true;
 
3275
      using_unique_constraint=1;
823
3276
    if (group)
824
 
      distinct= 0;                              // Can't use distinct
 
3277
      distinct=0;                               // Can't use distinct
825
3278
  }
826
3279
 
827
3280
  field_count=param->field_count+param->func_count+param->sum_func_count;
835
3288
    these items are stored in the temporary table.
836
3289
  */
837
3290
  if (param->precomputed_group_by)
838
 
  {
839
3291
    copy_func_count+= param->sum_func_count;
840
 
  }
841
 
 
842
 
  table::Singular *table;
843
 
  table= session->getInstanceTable(); // This will not go into the tableshare cache, so no key is used.
844
 
 
845
 
  if (not table->getMemRoot()->multi_alloc_root(0,
846
 
                                                &default_field, sizeof(Field*) * (field_count),
847
 
                                                &from_field, sizeof(Field*)*field_count,
848
 
                                                &copy_func, sizeof(*copy_func)*(copy_func_count+1),
849
 
                                                &param->keyinfo, sizeof(*param->keyinfo),
850
 
                                                &key_part_info, sizeof(*key_part_info)*(param->group_parts+1),
851
 
                                                &param->start_recinfo, sizeof(*param->recinfo)*(field_count*2+4),
852
 
                                                &group_buff, (group && ! using_unique_constraint ?
853
 
                                                              param->group_length : 0),
854
 
                                                NULL))
855
 
  {
856
 
    return NULL;
857
 
  }
858
 
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
859
 
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
860
 
  {
861
 
    return NULL;
 
3292
 
 
3293
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
3294
 
 
3295
  if (!multi_alloc_root(&own_root,
 
3296
                        &table, sizeof(*table),
 
3297
                        &share, sizeof(*share),
 
3298
                        &reg_field, sizeof(Field*) * (field_count+1),
 
3299
                        &default_field, sizeof(Field*) * (field_count),
 
3300
                        &blob_field, sizeof(uint32_t)*(field_count+1),
 
3301
                        &from_field, sizeof(Field*)*field_count,
 
3302
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
 
3303
                        &param->keyinfo, sizeof(*param->keyinfo),
 
3304
                        &key_part_info,
 
3305
                        sizeof(*key_part_info)*(param->group_parts+1),
 
3306
                        &param->start_recinfo,
 
3307
                        sizeof(*param->recinfo)*(field_count*2+4),
 
3308
                        &tmpname, (uint32_t) strlen(path)+1,
 
3309
                        &group_buff, (group && ! using_unique_constraint ?
 
3310
                                      param->group_length : 0),
 
3311
                        NULL))
 
3312
  {
 
3313
    if (temp_pool_slot != BIT_NONE)
 
3314
      temp_pool.reset(temp_pool_slot);
 
3315
    return(NULL);                               /* purecov: inspected */
 
3316
  }
 
3317
  /* Copy_field belongs to Tmp_Table_Param, allocate it in Session mem_root */
 
3318
  if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
 
3319
  {
 
3320
    if (temp_pool_slot != BIT_NONE)
 
3321
      temp_pool.reset(temp_pool_slot);
 
3322
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
3323
    return(NULL);                               /* purecov: inspected */
862
3324
  }
863
3325
  param->items_to_copy= copy_func;
 
3326
  strcpy(tmpname,path);
864
3327
  /* make table according to fields */
865
3328
 
 
3329
  memset(table, 0, sizeof(*table));
 
3330
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
866
3331
  memset(default_field, 0, sizeof(Field*) * (field_count));
867
3332
  memset(from_field, 0, sizeof(Field*)*field_count);
868
3333
 
 
3334
  table->mem_root= own_root;
869
3335
  mem_root_save= session->mem_root;
870
 
  session->mem_root= table->getMemRoot();
 
3336
  session->mem_root= &table->mem_root;
871
3337
 
872
 
  table->getMutableShare()->setFields(field_count+1);
873
 
  table->setFields(table->getMutableShare()->getFields(true));
874
 
  reg_field= table->getMutableShare()->getFields(true);
875
 
  table->setAlias(table_alias);
 
3338
  table->field=reg_field;
 
3339
  table->alias= table_alias;
876
3340
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
877
3341
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
878
3342
  table->map=1;
 
3343
  table->temp_pool_slot= temp_pool_slot;
879
3344
  table->copy_blobs= 1;
880
 
  assert(session);
881
3345
  table->in_use= session;
882
3346
  table->quick_keys.reset();
883
3347
  table->covering_keys.reset();
884
3348
  table->keys_in_use_for_query.reset();
885
3349
 
886
 
  table->getMutableShare()->blob_field.resize(field_count+1);
887
 
  uint32_t *blob_field= &table->getMutableShare()->blob_field[0];
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();
 
3350
  table->setShare(share);
 
3351
  share->init(tmpname, tmpname);
 
3352
  share->blob_field= blob_field;
 
3353
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
3354
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
 
3355
  share->table_charset= param->table_charset;
 
3356
  share->primary_key= MAX_KEY;               // Indicate no primary key
 
3357
  share->keys_for_keyread.reset();
 
3358
  share->keys_in_use.reset();
892
3359
 
893
3360
  /* Calculate which type of fields we will store in the temporary table */
894
3361
 
895
3362
  reclength= string_total_length= 0;
896
3363
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
897
 
  param->using_indirect_summary_function= 0;
 
3364
  param->using_indirect_summary_function=0;
898
3365
 
899
3366
  List_iterator_fast<Item> li(fields);
900
3367
  Item *item;
925
3392
    }
926
3393
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
927
3394
    {                                           /* Can't calc group yet */
928
 
      ((Item_sum*) item)->result_field= 0;
929
 
      for (i= 0 ; i < ((Item_sum*) item)->arg_count ; i++)
 
3395
      ((Item_sum*) item)->result_field=0;
 
3396
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
930
3397
      {
931
3398
        Item **argp= ((Item_sum*) item)->args + i;
932
3399
        Item *arg= *argp;
936
3403
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
937
3404
                             tmp_from_field, &default_field[fieldnr],
938
3405
                             group != 0,not_all_columns,
939
 
                             false,
 
3406
                             distinct, 0,
940
3407
                             param->convert_blob_length);
941
3408
          if (!new_field)
942
3409
            goto err;                                   // Should be OOM
955
3422
          }
956
3423
          session->mem_root= mem_root_save;
957
3424
          session->change_item_tree(argp, new Item_field(new_field));
958
 
          session->mem_root= table->getMemRoot();
 
3425
          session->mem_root= &table->mem_root;
959
3426
          if (!(new_field->flags & NOT_NULL_FLAG))
960
3427
          {
961
3428
            null_count++;
965
3432
            */
966
3433
            (*argp)->maybe_null=1;
967
3434
          }
968
 
          new_field->setPosition(fieldnr++);
 
3435
          new_field->field_index= fieldnr++;
969
3436
        }
970
3437
      }
971
3438
    }
981
3448
        We here distinguish between UNION and multi-table-updates by the fact
982
3449
        that in the later case group is set to the row pointer.
983
3450
      */
984
 
      Field *new_field=
 
3451
      Field *new_field= (param->schema_table) ?
 
3452
        create_tmp_field_for_schema(session, item, table) :
985
3453
        create_tmp_field(session, table, item, type, &copy_func,
986
3454
                         tmp_from_field, &default_field[fieldnr],
987
3455
                         group != 0,
988
3456
                         !force_copy_fields &&
989
 
                           (not_all_columns || group != 0),
 
3457
                           (not_all_columns || group !=0),
 
3458
                         /*
 
3459
                           If item->marker == 4 then we force create_tmp_field
 
3460
                           to create a 64-bit longs for BIT fields because HEAP
 
3461
                           tables can't index BIT fields directly. We do the same
 
3462
                           for distinct, as we want the distinct index to be
 
3463
                           usable in this case too.
 
3464
                         */
 
3465
                         item->marker == 4 || param->bit_fields_as_long,
990
3466
                         force_copy_fields,
991
3467
                         param->convert_blob_length);
992
3468
 
1012
3488
        group_null_items++;
1013
3489
        new_field->flags|= GROUP_FLAG;
1014
3490
      }
1015
 
      new_field->setPosition(fieldnr++);
 
3491
      new_field->field_index= fieldnr++;
1016
3492
      *(reg_field++)= new_field;
1017
3493
    }
1018
3494
    if (!--hidden_field_count)
1030
3506
      null_count= 0;
1031
3507
    }
1032
3508
  }
1033
 
  assert(fieldnr == (uint32_t) (reg_field - table->getFields()));
1034
 
  assert(field_count >= (uint32_t) (reg_field - table->getFields()));
 
3509
  assert(fieldnr == (uint32_t) (reg_field - table->field));
 
3510
  assert(field_count >= (uint32_t) (reg_field - table->field));
1035
3511
  field_count= fieldnr;
1036
3512
  *reg_field= 0;
1037
3513
  *blob_field= 0;                               // End marker
1038
 
  table->getMutableShare()->setFieldSize(field_count);
 
3514
  share->fields= field_count;
1039
3515
 
1040
3516
  /* If result table is small; use a heap */
1041
3517
  /* 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)
 
3518
  if (blob_count || using_unique_constraint ||
 
3519
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
3520
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
1046
3521
  {
1047
 
    table->getMutableShare()->storage_engine= myisam_engine;
1048
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
3522
    share->storage_engine= myisam_engine;
 
3523
    table->file= get_new_handler(share, &table->mem_root,
 
3524
                                 share->db_type());
1049
3525
    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
 
    }
 
3526
        (param->group_parts > table->file->max_key_parts() ||
 
3527
         param->group_length > table->file->max_key_length()))
 
3528
      using_unique_constraint=1;
1055
3529
  }
1056
3530
  else
1057
3531
  {
1058
 
    table->getMutableShare()->storage_engine= heap_engine;
1059
 
    table->cursor= table->getMutableShare()->db_type()->getCursor(*table);
 
3532
    share->storage_engine= heap_engine;
 
3533
    table->file= get_new_handler(share, &table->mem_root,
 
3534
                                 share->db_type());
1060
3535
  }
1061
 
  if (! table->cursor)
 
3536
  if (!table->file)
1062
3537
    goto err;
1063
3538
 
1064
3539
 
1065
 
  if (! using_unique_constraint)
 
3540
  if (!using_unique_constraint)
1066
3541
    reclength+= group_null_items;       // null flag is stored separately
1067
3542
 
1068
 
  table->getMutableShare()->blob_fields= blob_count;
 
3543
  share->blob_fields= blob_count;
1069
3544
  if (blob_count == 0)
1070
3545
  {
1071
3546
    /* We need to ensure that first byte is not 0 for the delete link */
1084
3559
  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
3560
    use_packed_rows= 1;
1086
3561
 
1087
 
  table->getMutableShare()->setRecordLength(reclength);
 
3562
  share->reclength= reclength;
1088
3563
  {
1089
3564
    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
 
    {
 
3565
    share->rec_buff_length= alloc_length;
 
3566
    if (!(table->record[0]= (unsigned char*)
 
3567
                            alloc_root(&table->mem_root, alloc_length*3)))
1093
3568
      goto err;
1094
 
    }
1095
 
    table->record[1]= table->getInsertRecord()+alloc_length;
1096
 
    table->getMutableShare()->resizeDefaultValues(alloc_length);
 
3569
    table->record[1]= table->record[0]+alloc_length;
 
3570
    share->default_values= table->record[1]+alloc_length;
1097
3571
  }
1098
 
  copy_func[0]= 0;                              // End marker
 
3572
  copy_func[0]=0;                               // End marker
1099
3573
  param->func_count= copy_func - param->items_to_copy;
1100
3574
 
1101
3575
  table->setup_tmp_table_column_bitmaps();
1102
3576
 
1103
3577
  recinfo=param->start_recinfo;
1104
 
  null_flags=(unsigned char*) table->getInsertRecord();
1105
 
  pos=table->getInsertRecord()+ null_pack_length;
 
3578
  null_flags=(unsigned char*) table->record[0];
 
3579
  pos=table->record[0]+ null_pack_length;
1106
3580
  if (null_pack_length)
1107
3581
  {
1108
3582
    memset(recinfo, 0, sizeof(*recinfo));
1111
3585
    recinfo++;
1112
3586
    memset(null_flags, 255, null_pack_length);  // Set null fields
1113
3587
 
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;
 
3588
    table->null_flags= (unsigned char*) table->record[0];
 
3589
    share->null_fields= null_count+ hidden_null_count;
 
3590
    share->null_bytes= null_pack_length;
1117
3591
  }
1118
3592
  null_count= (blob_count == 0) ? 1 : 0;
1119
3593
  hidden_field_count=param->hidden_field_count;
1120
 
  for (i= 0,reg_field= table->getFields(); i < field_count; i++,reg_field++,recinfo++)
 
3594
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
1121
3595
  {
1122
3596
    Field *field= *reg_field;
1123
3597
    uint32_t length;
1131
3605
          We have to reserve one byte here for NULL bits,
1132
3606
          as this is updated by 'end_update()'
1133
3607
        */
1134
 
        *pos++= '\0';                           // Null is stored here
1135
 
        recinfo->length= 1;
 
3608
        *pos++=0;                               // Null is stored here
 
3609
        recinfo->length=1;
1136
3610
        recinfo->type=FIELD_NORMAL;
1137
3611
        recinfo++;
1138
3612
        memset(recinfo, 0, sizeof(*recinfo));
1161
3635
         inherit the default value that is defined for the field referred
1162
3636
         by the Item_field object from which 'field' has been created.
1163
3637
      */
1164
 
      ptrdiff_t diff;
 
3638
      my_ptrdiff_t diff;
1165
3639
      Field *orig_field= default_field[i];
1166
3640
      /* Get the value from default_values */
1167
 
      diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
 
3641
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
 
3642
                            orig_field->table->record[0]);
1168
3643
      orig_field->move_field_offset(diff);      // Points now at default_values
1169
3644
      if (orig_field->is_real_null())
1170
3645
        field->set_null();
1173
3648
        field->set_notnull();
1174
3649
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
1175
3650
      }
1176
 
      orig_field->move_field_offset(-diff);     // Back to getInsertRecord()
 
3651
      orig_field->move_field_offset(-diff);     // Back to record[0]
1177
3652
    }
1178
3653
 
1179
3654
    if (from_field[i])
1192
3667
      recinfo->type=FIELD_NORMAL;
1193
3668
    if (!--hidden_field_count)
1194
3669
      null_count=(null_count+7) & ~7;           // move to next byte
 
3670
 
 
3671
    // fix table name in field entry
 
3672
    field->table_name= &table->alias;
1195
3673
  }
1196
3674
 
1197
3675
  param->copy_field_end=copy;
1199
3677
  table->storeRecordAsDefault();        // Make empty default record
1200
3678
 
1201
3679
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
1202
 
  {
1203
 
    max_rows= ~(uint64_t) 0;
1204
 
  }
 
3680
    share->max_rows= ~(ha_rows) 0;
1205
3681
  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
 
3682
    share->max_rows= (ha_rows) (((share->db_type() == heap_engine) ?
 
3683
                                 cmin(session->variables.tmp_table_size,
 
3684
                                     session->variables.max_heap_table_size) :
 
3685
                                 session->variables.tmp_table_size) /
 
3686
                                 share->reclength);
 
3687
  set_if_bigger(share->max_rows,(ha_rows)1);    // For dummy start options
1215
3688
  /*
1216
3689
    Push the LIMIT clause to the temporary table creation, so that we
1217
3690
    materialize only up to 'rows_limit' records instead of all result records.
1218
3691
  */
1219
 
  set_if_smaller(max_rows, rows_limit);
1220
 
 
1221
 
  table->getMutableShare()->setMaxRows(max_rows);
1222
 
 
 
3692
  set_if_smaller(share->max_rows, rows_limit);
1223
3693
  param->end_write_records= rows_limit;
1224
3694
 
1225
3695
  keyinfo= param->keyinfo;
1228
3698
  {
1229
3699
    table->group=group;                         /* Table is grouped by key */
1230
3700
    param->group_buff=group_buff;
1231
 
    table->getMutableShare()->keys=1;
1232
 
    table->getMutableShare()->uniques= test(using_unique_constraint);
 
3701
    share->keys=1;
 
3702
    share->uniques= test(using_unique_constraint);
1233
3703
    table->key_info=keyinfo;
1234
3704
    keyinfo->key_part=key_part_info;
1235
3705
    keyinfo->flags=HA_NOSAME;
1236
3706
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
1237
 
    keyinfo->key_length= 0;
1238
 
    keyinfo->rec_per_key= 0;
 
3707
    keyinfo->key_length=0;
 
3708
    keyinfo->rec_per_key=0;
1239
3709
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1240
3710
    keyinfo->name= (char*) "group_key";
1241
 
    Order *cur_group= group;
 
3711
    order_st *cur_group= group;
1242
3712
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
1243
3713
    {
1244
3714
      Field *field=(*cur_group->item)->get_tmp_table_field();
1245
3715
      bool maybe_null=(*cur_group->item)->maybe_null;
1246
 
      key_part_info->null_bit= 0;
 
3716
      key_part_info->null_bit=0;
1247
3717
      key_part_info->field=  field;
1248
 
      key_part_info->offset= field->offset(table->getInsertRecord());
 
3718
      key_part_info->offset= field->offset(table->record[0]);
1249
3719
      key_part_info->length= (uint16_t) field->key_length();
1250
3720
      key_part_info->type=   (uint8_t) field->key_type();
1251
 
      key_part_info->key_type= 
 
3721
      key_part_info->key_type =
1252
3722
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1253
3723
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1254
3724
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1255
 
        0 : 1;
 
3725
        0 : FIELDFLAG_BINARY;
1256
3726
      if (!using_unique_constraint)
1257
3727
      {
1258
3728
        cur_group->buff=(char*) group_buff;
1261
3731
                                                     test(maybe_null),
1262
3732
                                                     field->null_ptr,
1263
3733
                                                     field->null_bit)))
1264
 
          goto err;
 
3734
          goto err; /* purecov: inspected */
1265
3735
        if (maybe_null)
1266
3736
        {
1267
3737
          /*
1273
3743
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
1274
3744
          key_part_info->null_bit=field->null_bit;
1275
3745
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
1276
 
                                              (unsigned char*) table->getInsertRecord());
 
3746
                                              (unsigned char*) table->record[0]);
1277
3747
          cur_group->buff++;                        // Pointer to field data
1278
3748
          group_buff++;                         // Skipp null flag
1279
3749
        }
1300
3770
        indexes on blobs with arbitrary length. Such indexes cannot be
1301
3771
        used for lookups.
1302
3772
      */
1303
 
      table->getMutableShare()->uniques= 1;
 
3773
      share->uniques= 1;
1304
3774
    }
1305
3775
    null_pack_length-=hidden_null_pack_length;
1306
3776
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
1307
 
                         (table->getMutableShare()->uniques ? test(null_pack_length) : 0));
 
3777
                         (share->uniques ? test(null_pack_length) : 0));
1308
3778
    table->distinct= 1;
1309
 
    table->getMutableShare()->keys= 1;
1310
 
    if (!(key_part_info= (KeyPartInfo*)
1311
 
         table->alloc_root(keyinfo->key_parts * sizeof(KeyPartInfo))))
 
3779
    share->keys= 1;
 
3780
    if (!(key_part_info= (KEY_PART_INFO*)
 
3781
          alloc_root(&table->mem_root,
 
3782
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
1312
3783
      goto err;
1313
 
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KeyPartInfo));
 
3784
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
1314
3785
    table->key_info=keyinfo;
1315
3786
    keyinfo->key_part=key_part_info;
1316
3787
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
1317
3788
    keyinfo->key_length=(uint16_t) reclength;
1318
3789
    keyinfo->name= (char*) "distinct_key";
1319
3790
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1320
 
    keyinfo->rec_per_key= 0;
 
3791
    keyinfo->rec_per_key=0;
1321
3792
 
1322
3793
    /*
1323
3794
      Create an extra field to hold NULL bits so that unique indexes on
1324
3795
      blobs can distinguish NULL from 0. This extra field is not needed
1325
3796
      when we do not use UNIQUE indexes for blobs.
1326
3797
    */
1327
 
    if (null_pack_length && table->getMutableShare()->uniques)
 
3798
    if (null_pack_length && share->uniques)
1328
3799
    {
1329
 
      key_part_info->null_bit= 0;
 
3800
      key_part_info->null_bit=0;
1330
3801
      key_part_info->offset=hidden_null_pack_length;
1331
3802
      key_part_info->length=null_pack_length;
1332
 
      table->setVariableWidth();
1333
 
      key_part_info->field= new Field_varstring(table->getInsertRecord(),
 
3803
      key_part_info->field= new Field_varstring(table->record[0],
1334
3804
                                                (uint32_t) key_part_info->length,
1335
3805
                                                0,
1336
3806
                                                (unsigned char*) 0,
1337
3807
                                                (uint32_t) 0,
 
3808
                                                Field::NONE,
1338
3809
                                                NULL,
 
3810
                                                table->s,
1339
3811
                                                &my_charset_bin);
1340
3812
      if (!key_part_info->field)
1341
3813
        goto err;
1342
3814
      key_part_info->field->init(table);
1343
 
      key_part_info->key_type= 1; /* binary comparison */
 
3815
      key_part_info->key_type=FIELDFLAG_BINARY;
1344
3816
      key_part_info->type=    HA_KEYTYPE_BINARY;
1345
3817
      key_part_info++;
1346
3818
    }
1347
3819
    /* Create a distinct key over the columns we are going to return */
1348
 
    for (i=param->hidden_field_count, reg_field=table->getFields() + i ;
 
3820
    for (i=param->hidden_field_count, reg_field=table->field + i ;
1349
3821
         i < field_count;
1350
3822
         i++, reg_field++, key_part_info++)
1351
3823
    {
1352
 
      key_part_info->null_bit= 0;
 
3824
      key_part_info->null_bit=0;
1353
3825
      key_part_info->field=    *reg_field;
1354
 
      key_part_info->offset=   (*reg_field)->offset(table->getInsertRecord());
 
3826
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
1355
3827
      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.
 
3828
      /* TODO:
 
3829
        The below method of computing the key format length of the
 
3830
        key part is a copy/paste from opt_range.cc, and table.cc.
1358
3831
        This should be factored out, e.g. as a method of Field.
1359
3832
        In addition it is not clear if any of the Field::*_length
1360
3833
        methods is supposed to compute the same length. If so, it
1373
3846
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
1374
3847
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
1375
3848
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
1376
 
        0 : 1;
 
3849
        0 : FIELDFLAG_BINARY;
1377
3850
    }
1378
3851
  }
1379
3852
 
1380
3853
  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)
 
3854
    goto err;                                    /* purecov: inspected */
 
3855
  share->db_record_offset= 1;
 
3856
  if (share->db_type() == myisam_engine)
1384
3857
  {
1385
3858
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
1386
3859
                                       &param->recinfo, select_options))
1387
3860
      goto err;
1388
3861
  }
1389
 
  assert(table->in_use);
1390
3862
  if (table->open_tmp_table())
1391
3863
    goto err;
1392
3864
 
1396
3868
 
1397
3869
err:
1398
3870
  session->mem_root= mem_root_save;
1399
 
  table= NULL;
1400
 
 
1401
 
  return NULL;
 
3871
  table->free_tmp_table(session);                    /* purecov: inspected */
 
3872
  if (temp_pool_slot != BIT_NONE)
 
3873
    temp_pool.reset(temp_pool_slot);
 
3874
  return(NULL);                         /* purecov: inspected */
1402
3875
}
1403
3876
 
1404
3877
/****************************************************************************/
1405
3878
 
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;
 
3879
/**
 
3880
  Create a reduced Table object with properly set up Field list from a
 
3881
  list of field definitions.
 
3882
 
 
3883
    The created table doesn't have a table handler associated with
 
3884
    it, has no keys, no group/distinct, no copy_funcs array.
 
3885
    The sole purpose of this Table object is to use the power of Field
 
3886
    class to read/write data to/from table->record[0]. Then one can store
 
3887
    the record in any container (RB tree, hash, etc).
 
3888
    The table is created in Session mem_root, so are the table's fields.
 
3889
    Consequently, if you don't BLOB fields, you don't need to free it.
 
3890
 
 
3891
  @param session         connection handle
 
3892
  @param field_list  list of column definitions
 
3893
 
 
3894
  @return
 
3895
    0 if out of memory, Table object in case of success
 
3896
*/
 
3897
 
 
3898
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
 
3899
{
 
3900
  uint32_t field_count= field_list.elements;
 
3901
  uint32_t blob_count= 0;
 
3902
  Field **field;
 
3903
  Create_field *cdef;                           /* column definition */
 
3904
  uint32_t record_length= 0;
 
3905
  uint32_t null_count= 0;                 /* number of columns which may be null */
 
3906
  uint32_t null_pack_length;              /* NULL representation array length */
 
3907
  uint32_t *blob_field;
 
3908
  Table *table;
 
3909
  TableShare *share;
 
3910
 
 
3911
  if (!multi_alloc_root(session->mem_root,
 
3912
                        &table, sizeof(*table),
 
3913
                        &share, sizeof(*share),
 
3914
                        &field, (field_count + 1) * sizeof(Field*),
 
3915
                        &blob_field, (field_count+1) *sizeof(uint32_t),
 
3916
                        NULL))
 
3917
    return 0;
 
3918
 
 
3919
  memset(table, 0, sizeof(*table));
 
3920
  memset(share, 0, sizeof(*share));
 
3921
  table->field= field;
 
3922
  table->s= share;
 
3923
  share->blob_field= blob_field;
 
3924
  share->fields= field_count;
 
3925
  share->blob_ptr_size= portable_sizeof_char_ptr;
 
3926
  table->setup_tmp_table_column_bitmaps();
 
3927
 
 
3928
  /* Create all fields and calculate the total length of record */
 
3929
  List_iterator_fast<Create_field> it(field_list);
 
3930
  while ((cdef= it++))
 
3931
  {
 
3932
    *field= make_field(share, NULL, 0, cdef->length,
 
3933
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
3934
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
3935
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
 
3936
                       cdef->unireg_check,
 
3937
                       cdef->interval, cdef->field_name);
 
3938
    if (!*field)
 
3939
      goto error;
 
3940
    (*field)->init(table);
 
3941
    record_length+= (*field)->pack_length();
 
3942
    if (! ((*field)->flags & NOT_NULL_FLAG))
 
3943
      null_count++;
 
3944
 
 
3945
    if ((*field)->flags & BLOB_FLAG)
 
3946
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
 
3947
 
 
3948
    field++;
 
3949
  }
 
3950
  *field= NULL;                             /* mark the end of the list */
 
3951
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
 
3952
  share->blob_fields= blob_count;
 
3953
 
 
3954
  null_pack_length= (null_count + 7)/8;
 
3955
  share->reclength= record_length + null_pack_length;
 
3956
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
3957
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
 
3958
  if (!table->record[0])
 
3959
    goto error;
 
3960
 
 
3961
  if (null_pack_length)
 
3962
  {
 
3963
    table->null_flags= (unsigned char*) table->record[0];
 
3964
    share->null_fields= null_count;
 
3965
    share->null_bytes= null_pack_length;
 
3966
  }
 
3967
 
 
3968
  table->in_use= session;           /* field->reset() may access table->in_use */
 
3969
  {
 
3970
    /* Set up field pointers */
 
3971
    unsigned char *null_pos= table->record[0];
 
3972
    unsigned char *field_pos= null_pos + share->null_bytes;
 
3973
    uint32_t null_bit= 1;
 
3974
 
 
3975
    for (field= table->field; *field; ++field)
 
3976
    {
 
3977
      Field *cur_field= *field;
 
3978
      if ((cur_field->flags & NOT_NULL_FLAG))
 
3979
        cur_field->move_field(field_pos);
 
3980
      else
 
3981
      {
 
3982
        cur_field->move_field(field_pos, (unsigned char*) null_pos, null_bit);
 
3983
        null_bit<<= 1;
 
3984
        if (null_bit == (1 << 8))
 
3985
        {
 
3986
          ++null_pos;
 
3987
          null_bit= 1;
 
3988
        }
 
3989
      }
 
3990
      cur_field->reset();
 
3991
 
 
3992
      field_pos+= cur_field->pack_length();
 
3993
    }
 
3994
  }
 
3995
  return table;
 
3996
error:
 
3997
  for (field= table->field; *field; ++field)
 
3998
    delete *field;                         /* just invokes field destructor */
 
3999
  return 0;
 
4000
}
 
4001
 
 
4002
 
 
4003
bool Table::open_tmp_table()
 
4004
{
 
4005
  int error;
 
4006
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
 
4007
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
 
4008
  {
 
4009
    file->print_error(error,MYF(0)); /* purecov: inspected */
 
4010
    db_stat=0;
 
4011
    return(1);
 
4012
  }
 
4013
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
4014
  return(0);
 
4015
}
 
4016
 
 
4017
 
 
4018
/*
 
4019
  Create MyISAM temporary table
 
4020
 
 
4021
  SYNOPSIS
 
4022
    create_myisam_tmp_table()
 
4023
      keyinfo         Description of the index (there is always one index)
 
4024
      start_recinfo   MyISAM's column descriptions
 
4025
      recinfo INOUT   End of MyISAM's column descriptions
 
4026
      options         Option bits
 
4027
 
 
4028
  DESCRIPTION
 
4029
    Create a MyISAM temporary table according to passed description. The is
 
4030
    assumed to have one unique index or constraint.
 
4031
 
 
4032
    The passed array or MI_COLUMNDEF structures must have this form:
 
4033
 
 
4034
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
 
4035
         when there are many nullable columns)
 
4036
      2. Table columns
 
4037
      3. One free MI_COLUMNDEF element (*recinfo points here)
 
4038
 
 
4039
    This function may use the free element to create hash column for unique
 
4040
    constraint.
 
4041
 
 
4042
   RETURN
 
4043
     false - OK
 
4044
     true  - Error
 
4045
*/
 
4046
 
 
4047
bool Table::create_myisam_tmp_table(KEY *keyinfo,
 
4048
                                    MI_COLUMNDEF *start_recinfo,
 
4049
                                    MI_COLUMNDEF **recinfo,
 
4050
                                    uint64_t options)
 
4051
{
 
4052
  int error;
 
4053
  MI_KEYDEF keydef;
 
4054
  MI_UNIQUEDEF uniquedef;
 
4055
  TableShare *share= s;
 
4056
 
 
4057
  if (share->keys)
 
4058
  {                                             // Get keys for ni_create
 
4059
    bool using_unique_constraint=0;
 
4060
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
 
4061
                                            sizeof(*seg) * keyinfo->key_parts);
 
4062
    if (!seg)
 
4063
      goto err;
 
4064
 
 
4065
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
 
4066
    if (keyinfo->key_length >= file->max_key_length() ||
 
4067
        keyinfo->key_parts > file->max_key_parts() ||
 
4068
        share->uniques)
 
4069
    {
 
4070
      /* Can't create a key; Make a unique constraint instead of a key */
 
4071
      share->keys=    0;
 
4072
      share->uniques= 1;
 
4073
      using_unique_constraint=1;
 
4074
      memset(&uniquedef, 0, sizeof(uniquedef));
 
4075
      uniquedef.keysegs=keyinfo->key_parts;
 
4076
      uniquedef.seg=seg;
 
4077
      uniquedef.null_are_equal=1;
 
4078
 
 
4079
      /* Create extra column for hash value */
 
4080
      memset(*recinfo, 0, sizeof(**recinfo));
 
4081
      (*recinfo)->type= FIELD_CHECK;
 
4082
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
 
4083
      (*recinfo)++;
 
4084
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
 
4085
    }
 
4086
    else
 
4087
    {
 
4088
      /* Create an unique key */
 
4089
      memset(&keydef, 0, sizeof(keydef));
 
4090
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
 
4091
      keydef.keysegs=  keyinfo->key_parts;
 
4092
      keydef.seg= seg;
 
4093
    }
 
4094
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
 
4095
    {
 
4096
      Field *key_field=keyinfo->key_part[i].field;
 
4097
      seg->flag=     0;
 
4098
      seg->language= key_field->charset()->number;
 
4099
      seg->length=   keyinfo->key_part[i].length;
 
4100
      seg->start=    keyinfo->key_part[i].offset;
 
4101
      if (key_field->flags & BLOB_FLAG)
 
4102
      {
 
4103
        seg->type=
 
4104
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
 
4105
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
 
4106
        seg->bit_start= (uint8_t)(key_field->pack_length()
 
4107
                                  - share->blob_ptr_size);
 
4108
        seg->flag= HA_BLOB_PART;
 
4109
        seg->length=0;                  // Whole blob in unique constraint
 
4110
      }
 
4111
      else
 
4112
      {
 
4113
        seg->type= keyinfo->key_part[i].type;
 
4114
      }
 
4115
      if (!(key_field->flags & NOT_NULL_FLAG))
 
4116
      {
 
4117
        seg->null_bit= key_field->null_bit;
 
4118
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
 
4119
        /*
 
4120
          We are using a GROUP BY on something that contains NULL
 
4121
          In this case we have to tell MyISAM that two NULL should
 
4122
          on INSERT be regarded at the same value
 
4123
        */
 
4124
        if (!using_unique_constraint)
 
4125
          keydef.flag|= HA_NULL_ARE_EQUAL;
 
4126
      }
 
4127
    }
 
4128
  }
 
4129
  MI_CREATE_INFO create_info;
 
4130
  memset(&create_info, 0, sizeof(create_info));
 
4131
 
 
4132
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
4133
      OPTION_BIG_TABLES)
 
4134
    create_info.data_file_length= ~(uint64_t) 0;
 
4135
 
 
4136
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
 
4137
                       (uint32_t) (*recinfo-start_recinfo),
 
4138
                       start_recinfo,
 
4139
                       share->uniques, &uniquedef,
 
4140
                       &create_info,
 
4141
                       HA_CREATE_TMP_TABLE)))
 
4142
  {
 
4143
    file->print_error(error,MYF(0));    /* purecov: inspected */
 
4144
    db_stat=0;
 
4145
    goto err;
 
4146
  }
 
4147
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
 
4148
  share->db_record_offset= 1;
 
4149
  return false;
 
4150
 err:
 
4151
  return true;
 
4152
}
 
4153
 
 
4154
 
 
4155
void Table::free_tmp_table(Session *session)
 
4156
{
 
4157
  MEM_ROOT own_root= mem_root;
 
4158
  const char *save_proc_info;
 
4159
 
 
4160
  save_proc_info=session->get_proc_info();
 
4161
  session->set_proc_info("removing tmp table");
 
4162
 
 
4163
  // Release latches since this can take a long time
 
4164
  ha_release_temporary_latches(session);
 
4165
 
 
4166
  if (file)
 
4167
  {
 
4168
    if (db_stat)
 
4169
      file->ha_drop_table(s->table_name.str);
 
4170
    else
 
4171
      file->ha_delete_table(s->table_name.str);
 
4172
    delete file;
 
4173
  }
 
4174
 
 
4175
  /* free blobs */
 
4176
  for (Field **ptr= field ; *ptr ; ptr++)
 
4177
    (*ptr)->free();
 
4178
  free_io_cache(this);
 
4179
 
 
4180
  if (temp_pool_slot != BIT_NONE)
 
4181
    temp_pool.reset(temp_pool_slot);
 
4182
 
 
4183
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
 
4184
  session->set_proc_info(save_proc_info);
 
4185
 
 
4186
  return;
 
4187
}
 
4188
 
 
4189
/**
 
4190
  If a HEAP table gets full, create a MyISAM table and copy all rows
 
4191
  to this.
 
4192
*/
 
4193
 
 
4194
bool create_myisam_from_heap(Session *session, Table *table,
 
4195
                             MI_COLUMNDEF *start_recinfo,
 
4196
                             MI_COLUMNDEF **recinfo,
 
4197
                             int error, bool ignore_last_dupp_key_error)
 
4198
{
 
4199
  Table new_table;
 
4200
  TableShare share;
 
4201
  const char *save_proc_info;
 
4202
  int write_err;
 
4203
 
 
4204
  if (table->s->db_type() != heap_engine ||
 
4205
      error != HA_ERR_RECORD_FILE_FULL)
 
4206
  {
 
4207
    table->file->print_error(error,MYF(0));
 
4208
    return(1);
 
4209
  }
 
4210
 
 
4211
  // Release latches since this can take a long time
 
4212
  ha_release_temporary_latches(session);
 
4213
 
 
4214
  new_table= *table;
 
4215
  share= *table->s;
 
4216
  new_table.s= &share;
 
4217
  new_table.s->storage_engine= myisam_engine;
 
4218
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
4219
                                        new_table.s->db_type())))
 
4220
    return(1);                          // End of memory
 
4221
 
 
4222
  save_proc_info=session->get_proc_info();
 
4223
  session->set_proc_info("converting HEAP to MyISAM");
 
4224
 
 
4225
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
 
4226
                                        recinfo, session->lex->select_lex.options |
 
4227
                                        session->options))
 
4228
    goto err2;
 
4229
  if (new_table.open_tmp_table())
 
4230
    goto err1;
 
4231
  if (table->file->indexes_are_disabled())
 
4232
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
4233
  table->file->ha_index_or_rnd_end();
 
4234
  table->file->ha_rnd_init(1);
 
4235
  if (table->no_rows)
 
4236
  {
 
4237
    new_table.file->extra(HA_EXTRA_NO_ROWS);
 
4238
    new_table.no_rows=1;
 
4239
  }
 
4240
 
 
4241
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
 
4242
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
 
4243
 
 
4244
  /*
 
4245
    copy all old rows from heap table to MyISAM table
 
4246
    This is the only code that uses record[1] to read/write but this
 
4247
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
 
4248
  */
 
4249
  while (!table->file->rnd_next(new_table.record[1]))
 
4250
  {
 
4251
    write_err= new_table.file->ha_write_row(new_table.record[1]);
 
4252
    if (write_err)
 
4253
      goto err;
 
4254
  }
 
4255
  /* copy row that filled HEAP table */
 
4256
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
 
4257
  {
 
4258
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
4259
        !ignore_last_dupp_key_error)
 
4260
      goto err;
 
4261
  }
 
4262
 
 
4263
  /* remove heap table and change to use myisam table */
 
4264
  (void) table->file->ha_rnd_end();
 
4265
  (void) table->file->close();                  // This deletes the table !
 
4266
  delete table->file;
 
4267
  table->file=0;
 
4268
  new_table.s= table->s;                       // Keep old share
 
4269
  *table= new_table;
 
4270
  *table->s= share;
 
4271
 
 
4272
  table->file->change_table_ptr(table, table->s);
 
4273
  table->use_all_columns();
 
4274
  if (save_proc_info)
 
4275
  {
 
4276
    const char *new_proc_info=
 
4277
      (!strcmp(save_proc_info,"Copying to tmp table") ?
 
4278
      "Copying to tmp table on disk" : save_proc_info);
 
4279
    session->set_proc_info(new_proc_info);
 
4280
  }
 
4281
  return(0);
 
4282
 
 
4283
 err:
 
4284
  table->file->print_error(write_err, MYF(0));
 
4285
  (void) table->file->ha_rnd_end();
 
4286
  (void) new_table.file->close();
 
4287
 err1:
 
4288
  new_table.file->ha_delete_table(new_table.s->table_name.str);
 
4289
 err2:
 
4290
  delete new_table.file;
 
4291
  session->set_proc_info(save_proc_info);
 
4292
  table->mem_root= new_table.mem_root;
 
4293
  return(1);
 
4294
}
 
4295
 
 
4296
bitset<MAX_FIELDS> *Table::use_all_columns(bitset<MAX_FIELDS> *bitmap)
 
4297
{
 
4298
  bitset<MAX_FIELDS> *old= bitmap;
 
4299
  bitmap= &s->all_set;
1418
4300
  return old;
1419
4301
}
1420
4302
 
1421
 
void Table::restore_column_map(const boost::dynamic_bitset<>& old)
 
4303
void Table::restore_column_map(bitset<MAX_FIELDS> *old)
1422
4304
{
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
 
  }
 
4305
  read_set= old;
1434
4306
}
1435
4307
 
1436
4308
uint32_t Table::find_shortest_key(const key_map *usable_keys)
1439
4311
  uint32_t best= MAX_KEY;
1440
4312
  if (usable_keys->any())
1441
4313
  {
1442
 
    for (uint32_t nr= 0; nr < getShare()->sizeKeys() ; nr++)
 
4314
    for (uint32_t nr=0; nr < s->keys ; nr++)
1443
4315
    {
1444
4316
      if (usable_keys->test(nr))
1445
4317
      {
1466
4338
{
1467
4339
  for (; *ptr ; ptr++)
1468
4340
  {
1469
 
    if ((*ptr)->cmp_offset(getShare()->rec_buff_length))
 
4341
    if ((*ptr)->cmp_offset(s->rec_buff_length))
1470
4342
      return true;
1471
4343
  }
1472
4344
  return false;
1473
4345
}
1474
4346
 
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
 
 
 
4347
/* Return false if row hasn't changed */
 
4348
 
 
4349
bool Table::compare_record()
 
4350
{
 
4351
  if (s->blob_fields + s->varchar_fields == 0)
 
4352
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
1536
4353
  /* 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
 
 
 
4354
  if (memcmp(null_flags,
 
4355
             null_flags + s->rec_buff_length,
 
4356
             s->null_bytes))
 
4357
    return true;                                // Diff in NULL value
1540
4358
  /* Compare updated fields */
1541
4359
  for (Field **ptr= field ; *ptr ; ptr++)
1542
4360
  {
1543
 
    if (isWriteSet((*ptr)->position()) &&
1544
 
        (*ptr)->cmp_binary_offset(getShare()->rec_buff_length))
 
4361
    if (write_set->test((*ptr)->field_index) &&
 
4362
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
1545
4363
      return true;
1546
4364
  }
1547
4365
  return false;
1553
4371
 */
1554
4372
void Table::storeRecord()
1555
4373
{
1556
 
  memcpy(getUpdateRecord(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
4374
  memcpy(record[1], record[0], (size_t) s->reclength);
1557
4375
}
1558
4376
 
1559
4377
/*
1562
4380
 */
1563
4381
void Table::storeRecordAsInsert()
1564
4382
{
1565
 
  assert(insert_values.size() >= getShare()->getRecordLength());
1566
 
  memcpy(&insert_values[0], getInsertRecord(), (size_t) getShare()->getRecordLength());
 
4383
  memcpy(insert_values, record[0], (size_t) s->reclength);
1567
4384
}
1568
4385
 
1569
4386
/*
1572
4389
 */
1573
4390
void Table::storeRecordAsDefault()
1574
4391
{
1575
 
  memcpy(getMutableShare()->getDefaultValues(), getInsertRecord(), (size_t) getShare()->getRecordLength());
 
4392
  memcpy(s->default_values, record[0], (size_t) s->reclength);
1576
4393
}
1577
4394
 
1578
4395
/*
1581
4398
 */
1582
4399
void Table::restoreRecord()
1583
4400
{
1584
 
  memcpy(getInsertRecord(), getUpdateRecord(), (size_t) getShare()->getRecordLength());
 
4401
  memcpy(record[0], record[1], (size_t) s->reclength);
1585
4402
}
1586
4403
 
1587
4404
/*
1590
4407
 */
1591
4408
void Table::restoreRecordAsDefault()
1592
4409
{
1593
 
  memcpy(getInsertRecord(), getMutableShare()->getDefaultValues(), (size_t) getShare()->getRecordLength());
 
4410
  memcpy(record[0], s->default_values, (size_t) s->reclength);
1594
4411
}
1595
4412
 
1596
4413
/*
1600
4417
void Table::emptyRecord()
1601
4418
{
1602
4419
  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
 
  quick_rows(),
1652
 
  const_key_parts(),
1653
 
  quick_key_parts(),
1654
 
  quick_n_ranges()
1655
 
{
1656
 
  record[0]= (unsigned char *) 0;
1657
 
  record[1]= (unsigned char *) 0;
 
4420
  memset(null_flags, 255, s->null_bytes);
1658
4421
}
1659
4422
 
1660
4423
/*****************************************************************************
1662
4425
  Returns -1 if row was not found, 0 if row was found and 1 on errors
1663
4426
*****************************************************************************/
1664
4427
 
1665
 
/** Help function when we get some an error from the table Cursor. */
 
4428
/** Help function when we get some an error from the table handler. */
1666
4429
 
1667
4430
int Table::report_error(int error)
1668
4431
{
1676
4439
    print them to the .err log
1677
4440
  */
1678
4441
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
1679
 
    errmsg_printf(error::ERROR, _("Got error %d when reading table '%s'"),
1680
 
                  error, getShare()->getPath());
1681
 
  print_error(error, MYF(0));
 
4442
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
 
4443
                    error, s->path.str);
 
4444
  file->print_error(error,MYF(0));
1682
4445
 
1683
4446
  return 1;
1684
4447
}
1691
4454
  null_row= 0;
1692
4455
  status= STATUS_NO_RECORD;
1693
4456
  maybe_null= table_list->outer_join;
1694
 
  TableList *embedding= table_list->getEmbedding();
 
4457
  TableList *embedding= table_list->embedding;
1695
4458
  while (!maybe_null && embedding)
1696
4459
  {
1697
4460
    maybe_null= embedding->outer_join;
1698
 
    embedding= embedding->getEmbedding();
 
4461
    embedding= embedding->embedding;
1699
4462
  }
1700
4463
  tablenr= table_number;
1701
4464
  map= (table_map) 1 << table_number;
1702
4465
  force_index= table_list->force_index;
1703
 
  covering_keys= getShare()->keys_for_keyread;
 
4466
  covering_keys= s->keys_for_keyread;
1704
4467
  merge_keys.reset();
1705
4468
}
1706
4469
 
1707
4470
 
1708
 
bool Table::fill_item_list(List<Item> *item_list) const
1709
 
{
1710
 
  /*
1711
 
    All Item_field's created using a direct pointer to a field
1712
 
    are fixed in Item_field constructor.
1713
 
  */
1714
 
  for (Field **ptr= field; *ptr; ptr++)
1715
 
  {
1716
 
    Item_field *item= new Item_field(*ptr);
1717
 
    if (!item || item_list->push_back(item))
1718
 
      return true;
1719
 
  }
1720
 
  return false;
1721
 
}
1722
 
 
1723
 
 
1724
 
void Table::filesort_free_buffers(bool full)
1725
 
{
1726
 
  if (sort.record_pointers)
1727
 
  {
1728
 
    free((unsigned char*) sort.record_pointers);
1729
 
    sort.record_pointers=0;
1730
 
  }
1731
 
  if (full)
1732
 
  {
1733
 
    if (sort.sort_keys )
1734
 
    {
1735
 
      if ((unsigned char*) sort.sort_keys)
1736
 
        free((unsigned char*) sort.sort_keys);
1737
 
      sort.sort_keys= 0;
1738
 
    }
1739
 
    if (sort.buffpek)
1740
 
    {
1741
 
      if ((unsigned char*) sort.buffpek)
1742
 
        free((unsigned char*) sort.buffpek);
1743
 
      sort.buffpek= 0;
1744
 
      sort.buffpek_len= 0;
1745
 
    }
1746
 
  }
1747
 
 
1748
 
  if (sort.addon_buf)
1749
 
  {
1750
 
    free((char *) sort.addon_buf);
1751
 
    free((char *) sort.addon_field);
1752
 
    sort.addon_buf=0;
1753
 
    sort.addon_field=0;
1754
 
  }
1755
 
}
1756
 
 
1757
 
/*
1758
 
  Is this instance of the table should be reopen or represents a name-lock?
1759
 
*/
1760
 
bool Table::needs_reopen_or_name_lock() const
1761
 
1762
 
  return getShare()->getVersion() != refresh_version;
1763
 
}
1764
 
 
1765
 
uint32_t Table::index_flags(uint32_t idx) const
1766
 
{
1767
 
  return getShare()->getEngine()->index_flags(getShare()->getKeyInfo(idx).algorithm);
1768
 
}
1769
 
 
1770
 
void Table::print_error(int error, myf errflag) const
1771
 
{
1772
 
  getShare()->getEngine()->print_error(error, errflag, *this);
1773
 
}
1774
 
 
1775
 
} /* namespace drizzled */
 
4471
/*****************************************************************************
 
4472
** Instansiate templates
 
4473
*****************************************************************************/
 
4474
 
 
4475
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
4476
template class List<String>;
 
4477
template class List_iterator<String>;
 
4478
#endif