~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2009-02-21 00:18:15 UTC
  • Revision ID: brian@tangent.org-20090221001815-x20e8h71e984lvs1
Completion (?) of uint conversion.

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