~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
RemoveĀ uint.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
28
 
#include <drizzled/error.h>
29
 
#include <drizzled/gettext.h>
30
 
 
31
 
#include "drizzled/plugin/transactional_storage_engine.h"
32
 
#include "drizzled/plugin/authorization.h"
33
 
#include <drizzled/nested_join.h>
34
 
#include <drizzled/sql_parse.h>
35
 
#include <drizzled/item/sum.h>
36
 
#include <drizzled/table_list.h>
37
 
#include <drizzled/session.h>
38
 
#include <drizzled/sql_base.h>
39
 
#include <drizzled/sql_select.h>
40
 
#include <drizzled/field/blob.h>
41
 
#include <drizzled/field/varstring.h>
42
 
#include <drizzled/field/double.h>
43
 
#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
 
 
50
 
#include <drizzled/item/string.h>
51
 
#include <drizzled/item/int.h>
52
 
#include <drizzled/item/decimal.h>
53
 
#include <drizzled/item/float.h>
54
 
#include <drizzled/item/null.h>
55
 
#include <drizzled/temporal.h>
56
 
 
57
 
#include "drizzled/table_proto.h"
58
 
 
59
 
using namespace std;
60
 
 
61
 
namespace drizzled
62
 
{
63
 
 
64
 
extern pid_t current_pid;
65
 
extern plugin::StorageEngine *heap_engine;
66
 
extern plugin::StorageEngine *myisam_engine;
67
 
 
68
 
/* Functions defined in this cursor */
69
 
 
70
 
void open_table_error(TableShare *share, int error, int db_errno,
 
19
#include <drizzled/server_includes.h>
 
20
#include <drizzled/drizzled_error_messages.h>
 
21
 
 
22
#include "tmp_table.h"
 
23
#include "sj_tmp_table.h"
 
24
 
 
25
/* INFORMATION_SCHEMA name */
 
26
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
 
27
 
 
28
/* Functions defined in this file */
 
29
 
 
30
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
71
31
                      myf errortype, int errarg);
 
32
static int open_binary_frm(THD *thd, TABLE_SHARE *share,
 
33
                           unsigned char *head, File file);
 
34
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
 
35
                              uint32_t types, char **names);
 
36
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length);
72
37
 
73
38
/*************************************************************************/
74
39
 
75
40
/* Get column name from column hash */
76
41
 
77
 
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
 
42
static unsigned char *get_field_name(Field **buff, size_t *length,
 
43
                             bool not_used __attribute__((unused)))
78
44
{
79
 
  *length= (uint32_t) strlen((*buff)->field_name);
 
45
  *length= (uint) strlen((*buff)->field_name);
80
46
  return (unsigned char*) (*buff)->field_name;
81
47
}
82
48
 
83
 
/*
84
 
  Allocate a setup TableShare structure
 
49
 
 
50
/*
 
51
  Returns pointer to '.frm' extension of the file name.
 
52
 
 
53
  SYNOPSIS
 
54
    fn_rext()
 
55
    name       file name
 
56
 
 
57
  DESCRIPTION
 
58
    Checks file name part starting with the rightmost '.' character,
 
59
    and returns it if it is equal to '.frm'. 
 
60
 
 
61
  TODO
 
62
    It is a good idea to get rid of this function modifying the code
 
63
    to garantee that the functions presently calling fn_rext() always
 
64
    get arguments in the same format: either with '.frm' or without '.frm'.
 
65
 
 
66
  RETURN VALUES
 
67
    Pointer to the '.frm' extension. If there is no extension,
 
68
    or extension is not '.frm', pointer at the end of file name.
 
69
*/
 
70
 
 
71
char *fn_rext(char *name)
 
72
{
 
73
  char *res= strrchr(name, '.');
 
74
  if (res && !strcmp(res, reg_ext))
 
75
    return res;
 
76
  return name + strlen(name);
 
77
}
 
78
 
 
79
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
 
80
{
 
81
  assert(db != NULL);
 
82
  assert(name != NULL);
 
83
 
 
84
  if ((db->length == INFORMATION_SCHEMA_NAME.length) &&
 
85
      (my_strcasecmp(system_charset_info,
 
86
                    INFORMATION_SCHEMA_NAME.str,
 
87
                    db->str) == 0))
 
88
  {
 
89
    return TABLE_CATEGORY_INFORMATION;
 
90
  }
 
91
 
 
92
  return TABLE_CATEGORY_USER;
 
93
}
 
94
 
 
95
 
 
96
/*
 
97
  Allocate a setup TABLE_SHARE structure
85
98
 
86
99
  SYNOPSIS
87
100
    alloc_table_share()
94
107
    #  Share
95
108
*/
96
109
 
97
 
TableShare *alloc_table_share(TableList *table_list, char *key,
 
110
TABLE_SHARE *alloc_table_share(TableList *table_list, char *key,
98
111
                               uint32_t key_length)
99
112
{
100
 
  memory::Root mem_root;
101
 
  TableShare *share;
 
113
  MEM_ROOT mem_root;
 
114
  TABLE_SHARE *share;
102
115
  char *key_buff, *path_buff;
103
 
  std::string path;
104
 
 
105
 
  build_table_filename(path, table_list->db, table_list->table_name, false);
106
 
 
107
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
116
  char path[FN_REFLEN];
 
117
  uint32_t path_length;
 
118
 
 
119
  path_length= build_table_filename(path, sizeof(path) - 1,
 
120
                                    table_list->db,
 
121
                                    table_list->table_name, "", 0);
 
122
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
108
123
  if (multi_alloc_root(&mem_root,
109
124
                       &share, sizeof(*share),
110
125
                       &key_buff, key_length,
111
 
                       &path_buff, path.length() + 1,
 
126
                       &path_buff, path_length + 1,
112
127
                       NULL))
113
128
  {
114
129
    memset(share, 0, sizeof(*share));
115
130
 
116
131
    share->set_table_cache_key(key_buff, key, key_length);
117
132
 
118
 
    share->path.str= path_buff,
119
 
    share->path.length= path.length();
120
 
    strcpy(share->path.str, path.c_str());
 
133
    share->path.str= path_buff;
 
134
    share->path.length= path_length;
 
135
    my_stpcpy(share->path.str, path);
121
136
    share->normalized_path.str=    share->path.str;
122
 
    share->normalized_path.length= path.length();
 
137
    share->normalized_path.length= path_length;
123
138
 
124
139
    share->version=       refresh_version;
125
140
 
 
141
    /*
 
142
      This constant is used to mark that no table map version has been
 
143
      assigned.  No arithmetic is done on the value: it will be
 
144
      overwritten with a value taken from DRIZZLE_BIN_LOG.
 
145
    */
 
146
    share->table_map_version= UINT64_MAX;
 
147
 
 
148
    /*
 
149
      Since alloc_table_share() can be called without any locking (for
 
150
      example, ha_create_table... functions), we do not assign a table
 
151
      map id here.  Instead we assign a value that is not used
 
152
      elsewhere, and then assign a table map id inside open_table()
 
153
      under the protection of the LOCK_open mutex.
 
154
    */
 
155
    share->table_map_id= UINT32_MAX;
 
156
    share->cached_row_logging_check= -1;
 
157
 
126
158
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
127
159
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
128
160
    pthread_cond_init(&share->cond, NULL);
131
163
}
132
164
 
133
165
 
134
 
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
135
 
{
136
 
  enum_field_types field_type;
137
 
 
138
 
  switch(proto_field_type)
139
 
  {
140
 
  case message::Table::Field::INTEGER:
141
 
    field_type= DRIZZLE_TYPE_LONG;
142
 
    break;
143
 
  case message::Table::Field::DOUBLE:
144
 
    field_type= DRIZZLE_TYPE_DOUBLE;
145
 
    break;
146
 
  case message::Table::Field::TIMESTAMP:
147
 
    field_type= DRIZZLE_TYPE_TIMESTAMP;
148
 
    break;
149
 
  case message::Table::Field::BIGINT:
150
 
    field_type= DRIZZLE_TYPE_LONGLONG;
151
 
    break;
152
 
  case message::Table::Field::DATETIME:
153
 
    field_type= DRIZZLE_TYPE_DATETIME;
154
 
    break;
155
 
  case message::Table::Field::DATE:
156
 
    field_type= DRIZZLE_TYPE_DATE;
157
 
    break;
158
 
  case message::Table::Field::VARCHAR:
159
 
    field_type= DRIZZLE_TYPE_VARCHAR;
160
 
    break;
161
 
  case message::Table::Field::DECIMAL:
162
 
    field_type= DRIZZLE_TYPE_DECIMAL;
163
 
    break;
164
 
  case message::Table::Field::ENUM:
165
 
    field_type= DRIZZLE_TYPE_ENUM;
166
 
    break;
167
 
  case message::Table::Field::BLOB:
168
 
    field_type= DRIZZLE_TYPE_BLOB;
169
 
    break;
170
 
  default:
171
 
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
 
166
/*
 
167
  Initialize share for temporary tables
 
168
 
 
169
  SYNOPSIS
 
170
    init_tmp_table_share()
 
171
    thd         thread handle
 
172
    share       Share to fill
 
173
    key         Table_cache_key, as generated from create_table_def_key.
 
174
                must start with db name.    
 
175
    key_length  Length of key
 
176
    table_name  Table name
 
177
    path        Path to file (possible in lower case) without .frm
 
178
 
 
179
  NOTES
 
180
    This is different from alloc_table_share() because temporary tables
 
181
    don't have to be shared between threads or put into the table def
 
182
    cache, so we can do some things notable simpler and faster
 
183
 
 
184
    If table is not put in thd->temporary_tables (happens only when
 
185
    one uses OPEN TEMPORARY) then one can specify 'db' as key and
 
186
    use key_length= 0 as neither table_cache_key or key_length will be used).
 
187
*/
 
188
 
 
189
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
 
190
                          uint32_t key_length, const char *table_name,
 
191
                          const char *path)
 
192
{
 
193
 
 
194
  memset(share, 0, sizeof(*share));
 
195
  init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
196
  share->table_category=         TABLE_CATEGORY_TEMPORARY;
 
197
  share->tmp_table=              INTERNAL_TMP_TABLE;
 
198
  share->db.str=                 (char*) key;
 
199
  share->db.length=              strlen(key);
 
200
  share->table_cache_key.str=    (char*) key;
 
201
  share->table_cache_key.length= key_length;
 
202
  share->table_name.str=         (char*) table_name;
 
203
  share->table_name.length=      strlen(table_name);
 
204
  share->path.str=               (char*) path;
 
205
  share->normalized_path.str=    (char*) path;
 
206
  share->path.length= share->normalized_path.length= strlen(path);
 
207
  share->frm_version=            FRM_VER_TRUE_VARCHAR;
 
208
  /*
 
209
    Temporary tables are not replicated, but we set up these fields
 
210
    anyway to be able to catch errors.
 
211
   */
 
212
  share->table_map_version= ~(uint64_t)0;
 
213
  share->cached_row_logging_check= -1;
 
214
 
 
215
  /*
 
216
    table_map_id is also used for MERGE tables to suppress repeated
 
217
    compatibility checks.
 
218
  */
 
219
  share->table_map_id= (ulong) thd->query_id;
 
220
 
 
221
  return;
 
222
}
 
223
 
 
224
 
 
225
/*
 
226
  Free table share and memory used by it
 
227
 
 
228
  SYNOPSIS
 
229
    free_table_share()
 
230
    share               Table share
 
231
 
 
232
  NOTES
 
233
    share->mutex must be locked when we come here if it's not a temp table
 
234
*/
 
235
 
 
236
void free_table_share(TABLE_SHARE *share)
 
237
{
 
238
  MEM_ROOT mem_root;
 
239
  assert(share->ref_count == 0);
 
240
 
 
241
  /*
 
242
    If someone is waiting for this to be deleted, inform it about this.
 
243
    Don't do a delete until we know that no one is refering to this anymore.
 
244
  */
 
245
  if (share->tmp_table == NO_TMP_TABLE)
 
246
  {
 
247
    /* share->mutex is locked in release_table_share() */
 
248
    while (share->waiting_on_cond)
 
249
    {
 
250
      pthread_cond_broadcast(&share->cond);
 
251
      pthread_cond_wait(&share->cond, &share->mutex);
 
252
    }
 
253
    /* No thread refers to this anymore */
 
254
    pthread_mutex_unlock(&share->mutex);
 
255
    pthread_mutex_destroy(&share->mutex);
 
256
    pthread_cond_destroy(&share->cond);
 
257
  }
 
258
  hash_free(&share->name_hash);
 
259
  
 
260
  plugin_unlock(NULL, share->db_plugin);
 
261
  share->db_plugin= NULL;
 
262
 
 
263
  /* We must copy mem_root from share because share is allocated through it */
 
264
  memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
 
265
  free_root(&mem_root, MYF(0));                 // Free's share
 
266
  return;
 
267
}
 
268
 
 
269
/*
 
270
  Read table definition from a binary / text based .frm file
 
271
  
 
272
  SYNOPSIS
 
273
  open_table_def()
 
274
  thd           Thread handler
 
275
  share         Fill this with table definition
 
276
  db_flags      Bit mask of the following flags: OPEN_VIEW
 
277
 
 
278
  NOTES
 
279
    This function is called when the table definition is not cached in
 
280
    table_def_cache
 
281
    The data is returned in 'share', which is alloced by
 
282
    alloc_table_share().. The code assumes that share is initialized.
 
283
 
 
284
  RETURN VALUES
 
285
   0    ok
 
286
   1    Error (see open_table_error)
 
287
   2    Error (see open_table_error)
 
288
   3    Wrong data in .frm file
 
289
   4    Error (see open_table_error)
 
290
   5    Error (see open_table_error: charset unavailable)
 
291
   6    Unknown .frm version
 
292
*/
 
293
 
 
294
int open_table_def(THD *thd, TABLE_SHARE *share, uint32_t db_flags  __attribute__((unused)))
 
295
{
 
296
  int error, table_type;
 
297
  bool error_given;
 
298
  File file;
 
299
  unsigned char head[64], *disk_buff;
 
300
  char  path[FN_REFLEN];
 
301
  MEM_ROOT **root_ptr, *old_root;
 
302
 
 
303
  error= 1;
 
304
  error_given= 0;
 
305
  disk_buff= NULL;
 
306
 
 
307
  strxmov(path, share->normalized_path.str, reg_ext, NULL);
 
308
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
 
309
  {
 
310
    /*
 
311
      We don't try to open 5.0 unencoded name, if
 
312
      - non-encoded name contains '@' signs, 
 
313
        because '@' can be misinterpreted.
 
314
        It is not clear if '@' is escape character in 5.1,
 
315
        or a normal character in 5.0.
 
316
        
 
317
      - non-encoded db or table name contain "#mysql50#" prefix.
 
318
        This kind of tables must have been opened only by the
 
319
        my_open() above.
 
320
    */
 
321
    if (strchr(share->table_name.str, '@') ||
 
322
        !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
 
323
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
 
324
        !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
 
325
                 MYSQL50_TABLE_NAME_PREFIX_LENGTH))
 
326
      goto err_not_open;
 
327
 
 
328
    /* Try unencoded 5.0 name */
 
329
    uint32_t length;
 
330
    strxnmov(path, sizeof(path)-1,
 
331
             mysql_data_home, "/", share->db.str, "/",
 
332
             share->table_name.str, reg_ext, NULL);
 
333
    length= unpack_filename(path, path) - reg_ext_length;
 
334
    /*
 
335
      The following is a safety test and should never fail
 
336
      as the old file name should never be longer than the new one.
 
337
    */
 
338
    assert(length <= share->normalized_path.length);
 
339
    /*
 
340
      If the old and the new names have the same length,
 
341
      then table name does not have tricky characters,
 
342
      so no need to check the old file name.
 
343
    */
 
344
    if (length == share->normalized_path.length ||
 
345
        ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
 
346
      goto err_not_open;
 
347
 
 
348
    /* Unencoded 5.0 table name found */
 
349
    path[length]= '\0'; // Remove .frm extension
 
350
    my_stpcpy(share->normalized_path.str, path);
 
351
    share->normalized_path.length= length;
 
352
  }
 
353
 
 
354
  error= 4;
 
355
  if (my_read(file, head, 64, MYF(MY_NABP)))
 
356
    goto err;
 
357
 
 
358
  if (head[0] == (unsigned char) 254 && head[1] == 1)
 
359
  {
 
360
    if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
 
361
        (head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
 
362
    {
 
363
      table_type= 1;
 
364
    }
 
365
    else
 
366
    {
 
367
      error= 6;                                 // Unkown .frm version
 
368
      goto err;
 
369
    }
 
370
  }
 
371
  else
 
372
    goto err;
 
373
 
 
374
  /* No handling of text based files yet */
 
375
  if (table_type == 1)
 
376
  {
 
377
    root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
 
378
    old_root= *root_ptr;
 
379
    *root_ptr= &share->mem_root;
 
380
    error= open_binary_frm(thd, share, head, file);
 
381
    *root_ptr= old_root;
 
382
    error_given= 1;
 
383
  }
 
384
  else
172
385
    assert(1);
173
 
  }
174
 
 
175
 
  return field_type;
176
 
}
177
 
 
178
 
static Item *default_value_item(enum_field_types field_type,
179
 
                                const CHARSET_INFO *charset,
180
 
                                bool default_null, const string *default_value,
181
 
                                const string *default_bin_value)
182
 
{
183
 
  Item *default_item= NULL;
184
 
  int error= 0;
185
 
 
186
 
  if (default_null)
187
 
  {
188
 
    return new Item_null();
189
 
  }
190
 
 
191
 
  switch(field_type)
192
 
  {
193
 
  case DRIZZLE_TYPE_LONG:
194
 
  case DRIZZLE_TYPE_LONGLONG:
195
 
    default_item= new Item_int(default_value->c_str(),
196
 
                               (int64_t) internal::my_strtoll10(default_value->c_str(),
197
 
                                                                NULL,
198
 
                                                                &error),
199
 
                               default_value->length());
200
 
    break;
201
 
  case DRIZZLE_TYPE_DOUBLE:
202
 
    default_item= new Item_float(default_value->c_str(),
203
 
                                 default_value->length());
204
 
    break;
205
 
  case DRIZZLE_TYPE_NULL:
206
 
    assert(false);
207
 
  case DRIZZLE_TYPE_TIMESTAMP:
208
 
  case DRIZZLE_TYPE_DATETIME:
209
 
  case DRIZZLE_TYPE_DATE:
210
 
    if (default_value->compare("NOW()") == 0)
211
 
      break;
212
 
  case DRIZZLE_TYPE_ENUM:
213
 
    default_item= new Item_string(default_value->c_str(),
214
 
                                  default_value->length(),
215
 
                                  system_charset_info);
216
 
    break;
217
 
  case DRIZZLE_TYPE_VARCHAR:
218
 
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
219
 
    if (charset==&my_charset_bin)
220
 
    {
221
 
      default_item= new Item_string(default_bin_value->c_str(),
222
 
                                    default_bin_value->length(),
223
 
                                    &my_charset_bin);
224
 
    }
225
 
    else
226
 
    {
227
 
      default_item= new Item_string(default_value->c_str(),
228
 
                                    default_value->length(),
229
 
                                    system_charset_info);
230
 
    }
231
 
    break;
232
 
  case DRIZZLE_TYPE_DECIMAL:
233
 
    default_item= new Item_decimal(default_value->c_str(),
234
 
                                   default_value->length(),
235
 
                                   system_charset_info);
236
 
    break;
237
 
  }
238
 
 
239
 
  return default_item;
240
 
}
241
 
 
242
 
int parse_table_proto(Session& session,
243
 
                      message::Table &table,
244
 
                      TableShare *share)
245
 
{
246
 
  int error= 0;
247
 
 
248
 
  if (! table.IsInitialized())
249
 
  {
250
 
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
251
 
    return ER_CORRUPT_TABLE_DEFINITION;
252
 
  }
253
 
 
254
 
  share->setTableProto(new(nothrow) message::Table(table));
255
 
 
256
 
  share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
257
 
  assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
258
 
 
259
 
  message::Table::TableOptions table_options;
260
 
 
261
 
  if (table.has_options())
262
 
    table_options= table.options();
263
 
 
264
 
  uint32_t db_create_options= 0;
265
 
 
266
 
  if (table_options.has_pack_keys())
267
 
  {
268
 
    if (table_options.pack_keys())
269
 
      db_create_options|= HA_OPTION_PACK_KEYS;
270
 
    else
271
 
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
272
 
  }
273
 
 
274
 
  if (table_options.pack_record())
275
 
    db_create_options|= HA_OPTION_PACK_RECORD;
276
 
 
277
 
  /* db_create_options was stored as 2 bytes in FRM
278
 
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
279
 
   */
280
 
  share->db_create_options= (db_create_options & 0x0000FFFF);
 
386
 
 
387
  share->table_category= get_table_category(& share->db, & share->table_name);
 
388
 
 
389
  if (!error)
 
390
    thd->status_var.opened_shares++;
 
391
 
 
392
err:
 
393
  my_close(file, MYF(MY_WME));
 
394
 
 
395
err_not_open:
 
396
  if (error && !error_given)
 
397
  {
 
398
    share->error= error;
 
399
    open_table_error(share, error, (share->open_errno= my_errno), 0);
 
400
  }
 
401
 
 
402
  return(error);
 
403
}
 
404
 
 
405
 
 
406
/*
 
407
  Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
 
408
*/
 
409
 
 
410
static int open_binary_frm(THD *thd, TABLE_SHARE *share, unsigned char *head,
 
411
                           File file)
 
412
{
 
413
  int error, errarg= 0;
 
414
  uint32_t new_frm_ver, field_pack_length, new_field_pack_flag;
 
415
  uint32_t interval_count, interval_parts, read_length, int_length;
 
416
  uint32_t db_create_options, keys, key_parts, n_length;
 
417
  uint32_t key_info_length, com_length, null_bit_pos=0;
 
418
  uint32_t extra_rec_buf_length;
 
419
  uint32_t i,j;
 
420
  bool use_hash;
 
421
  unsigned char forminfo[288];
 
422
  char *keynames, *names, *comment_pos;
 
423
  unsigned char *record;
 
424
  unsigned char *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
 
425
  ulong pos, record_offset, *rec_per_key, rec_buff_length;
 
426
  handler *handler_file= 0;
 
427
  KEY   *keyinfo;
 
428
  KEY_PART_INFO *key_part;
 
429
  Field  **field_ptr, *reg_field;
 
430
  const char **interval_array;
 
431
  enum legacy_db_type legacy_db_type;
 
432
  my_bitmap_map *bitmaps;
 
433
  unsigned char *buff= 0;
 
434
  unsigned char *field_extra_info= 0;
 
435
 
 
436
  new_field_pack_flag= head[27];
 
437
  new_frm_ver= (head[2] - FRM_VER);
 
438
  field_pack_length= new_frm_ver < 2 ? 11 : 17;
 
439
  disk_buff= 0;
 
440
 
 
441
  error= 3;
 
442
  if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
 
443
    goto err;                                   /* purecov: inspected */
 
444
  my_seek(file,pos,MY_SEEK_SET,MYF(0));
 
445
  if (my_read(file,forminfo,288,MYF(MY_NABP)))
 
446
    goto err;
 
447
 
 
448
  share->frm_version= head[2];
 
449
  /*
 
450
    Check if .frm file created by MySQL 5.0. In this case we want to
 
451
    display CHAR fields as CHAR and not as VARCHAR.
 
452
    We do it this way as we want to keep the old frm version to enable
 
453
    MySQL 4.1 to read these files.
 
454
  */
 
455
  if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
 
456
    share->frm_version= FRM_VER_TRUE_VARCHAR;
 
457
 
 
458
  legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
 
459
  assert(share->db_plugin == NULL);
 
460
  /*
 
461
    if the storage engine is dynamic, no point in resolving it by its
 
462
    dynamically allocated legacy_db_type. We will resolve it later by name.
 
463
  */
 
464
  if (legacy_db_type > DB_TYPE_UNKNOWN && 
 
465
      legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
 
466
    share->db_plugin= ha_lock_engine(NULL, 
 
467
                                     ha_checktype(thd, legacy_db_type, 0, 0));
 
468
  share->db_create_options= db_create_options= uint2korr(head+30);
281
469
  share->db_options_in_use= share->db_create_options;
282
 
 
283
 
  share->row_type= table_options.has_row_type() ?
284
 
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
285
 
 
286
 
  share->block_size= table_options.has_block_size() ?
287
 
    table_options.block_size() : 0;
288
 
 
289
 
  share->table_charset= get_charset(table_options.has_collation_id()?
290
 
                                    table_options.collation_id() : 0);
291
 
 
 
470
  share->mysql_version= uint4korr(head+51);
 
471
  share->null_field_first= 0;
 
472
  if (!head[32])                                // New frm file in 3.23
 
473
  {
 
474
    share->avg_row_length= uint4korr(head+34);
 
475
    share->transactional= (ha_choice) (head[39] & 3);
 
476
    share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
 
477
    share->row_type= (row_type) head[40];
 
478
    share->block_size= uint4korr(head+43);
 
479
    share->table_charset= get_charset((uint) head[38],MYF(0));
 
480
    share->null_field_first= 1;
 
481
  }
292
482
  if (!share->table_charset)
293
483
  {
294
484
    /* unknown charset in head[38] or pre-3.23 frm */
295
485
    if (use_mb(default_charset_info))
296
486
    {
297
487
      /* Warn that we may be changing the size of character columns */
298
 
      errmsg_printf(ERRMSG_LVL_WARN,
299
 
                    _("'%s' had no or invalid character set, "
300
 
                      "and default character set is multi-byte, "
301
 
                      "so character column sizes may have changed"),
302
 
                    share->path.str);
 
488
      sql_print_warning(_("'%s' had no or invalid character set, "
 
489
                        "and default character set is multi-byte, "
 
490
                        "so character column sizes may have changed"),
 
491
                        share->path.str);
303
492
    }
304
493
    share->table_charset= default_charset_info;
305
494
  }
306
 
 
307
495
  share->db_record_offset= 1;
308
 
 
309
 
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
310
 
 
311
 
  share->keys= table.indexes_size();
312
 
 
313
 
  share->key_parts= 0;
314
 
  for (int indx= 0; indx < table.indexes_size(); indx++)
315
 
    share->key_parts+= table.indexes(indx).index_part_size();
316
 
 
317
 
  share->key_info= (KEY*) alloc_root(&share->mem_root,
318
 
                                     table.indexes_size() * sizeof(KEY)
319
 
                                     +share->key_parts*sizeof(KEY_PART_INFO));
320
 
 
321
 
  KEY_PART_INFO *key_part;
322
 
 
323
 
  key_part= reinterpret_cast<KEY_PART_INFO*>
324
 
    (share->key_info+table.indexes_size());
325
 
 
326
 
 
327
 
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
328
 
                                            sizeof(ulong*)*share->key_parts);
329
 
 
330
 
  share->keynames.count= table.indexes_size();
331
 
  share->keynames.name= NULL;
332
 
  share->keynames.type_names= (const char**)
333
 
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
334
 
 
335
 
  share->keynames.type_lengths= (unsigned int*)
336
 
    alloc_root(&share->mem_root,
337
 
               sizeof(unsigned int) * (table.indexes_size()+1));
338
 
 
339
 
  share->keynames.type_names[share->keynames.count]= NULL;
340
 
  share->keynames.type_lengths[share->keynames.count]= 0;
341
 
 
342
 
  KEY* keyinfo= share->key_info;
343
 
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
344
 
  {
345
 
    message::Table::Index indx= table.indexes(keynr);
346
 
 
347
 
    keyinfo->table= 0;
348
 
    keyinfo->flags= 0;
349
 
 
350
 
    if (indx.is_unique())
351
 
      keyinfo->flags|= HA_NOSAME;
352
 
 
353
 
    if (indx.has_options())
354
 
    {
355
 
      message::Table::Index::IndexOptions indx_options= indx.options();
356
 
      if (indx_options.pack_key())
357
 
        keyinfo->flags|= HA_PACK_KEY;
358
 
 
359
 
      if (indx_options.var_length_key())
360
 
        keyinfo->flags|= HA_VAR_LENGTH_PART;
361
 
 
362
 
      if (indx_options.null_part_key())
363
 
        keyinfo->flags|= HA_NULL_PART_KEY;
364
 
 
365
 
      if (indx_options.binary_pack_key())
366
 
        keyinfo->flags|= HA_BINARY_PACK_KEY;
367
 
 
368
 
      if (indx_options.has_partial_segments())
369
 
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
370
 
 
371
 
      if (indx_options.auto_generated_key())
372
 
        keyinfo->flags|= HA_GENERATED_KEY;
373
 
 
374
 
      if (indx_options.has_key_block_size())
375
 
      {
376
 
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
377
 
        keyinfo->block_size= indx_options.key_block_size();
378
 
      }
379
 
      else
380
 
      {
381
 
        keyinfo->block_size= 0;
382
 
      }
383
 
    }
384
 
 
385
 
    switch (indx.type())
386
 
    {
387
 
    case message::Table::Index::UNKNOWN_INDEX:
388
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
389
 
      break;
390
 
    case message::Table::Index::BTREE:
391
 
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
392
 
      break;
393
 
    case message::Table::Index::HASH:
394
 
      keyinfo->algorithm= HA_KEY_ALG_HASH;
395
 
      break;
396
 
 
397
 
    default:
398
 
      /* TODO: suitable warning ? */
399
 
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
400
 
      break;
401
 
    }
402
 
 
403
 
    keyinfo->key_length= indx.key_length();
404
 
 
405
 
    keyinfo->key_parts= indx.index_part_size();
406
 
 
407
 
    keyinfo->key_part= key_part;
 
496
  if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
 
497
    share->blob_ptr_size= portable_sizeof_char_ptr;
 
498
  /* Set temporarily a good value for db_low_byte_first */
 
499
  share->db_low_byte_first= true;
 
500
  error=4;
 
501
  share->max_rows= uint4korr(head+18);
 
502
  share->min_rows= uint4korr(head+22);
 
503
 
 
504
  /* Read keyinformation */
 
505
  key_info_length= (uint) uint2korr(head+28);
 
506
  my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0));
 
507
  if (read_string(file,(unsigned char**) &disk_buff,key_info_length))
 
508
    goto err;                                   /* purecov: inspected */
 
509
  if (disk_buff[0] & 0x80)
 
510
  {
 
511
    share->keys=      keys=      (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
 
512
    share->key_parts= key_parts= uint2korr(disk_buff+2);
 
513
  }
 
514
  else
 
515
  {
 
516
    share->keys=      keys=      disk_buff[0];
 
517
    share->key_parts= key_parts= disk_buff[1];
 
518
  }
 
519
  share->keys_for_keyread.init(0);
 
520
  share->keys_in_use.init(keys);
 
521
 
 
522
  n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
 
523
  if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
 
524
                                    n_length + uint2korr(disk_buff+4))))
 
525
    goto err;                                   /* purecov: inspected */
 
526
  memset(keyinfo, 0, n_length);
 
527
  share->key_info= keyinfo;
 
528
  key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
 
529
  strpos=disk_buff+6;
 
530
 
 
531
  if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
 
532
                                         sizeof(ulong*)*key_parts)))
 
533
    goto err;
 
534
 
 
535
  for (i=0 ; i < keys ; i++, keyinfo++)
 
536
  {
 
537
    keyinfo->table= 0;                           // Updated in open_frm
 
538
    if (new_frm_ver >= 3)
 
539
    {
 
540
      keyinfo->flags=      (uint) uint2korr(strpos) ^ HA_NOSAME;
 
541
      keyinfo->key_length= (uint) uint2korr(strpos+2);
 
542
      keyinfo->key_parts=  (uint) strpos[4];
 
543
      keyinfo->algorithm=  (enum ha_key_alg) strpos[5];
 
544
      keyinfo->block_size= uint2korr(strpos+6);
 
545
      strpos+=8;
 
546
    }
 
547
 
 
548
    keyinfo->key_part=   key_part;
408
549
    keyinfo->rec_per_key= rec_per_key;
409
 
 
410
 
    for (unsigned int partnr= 0;
411
 
         partnr < keyinfo->key_parts;
412
 
         partnr++, key_part++)
413
 
    {
414
 
      message::Table::Index::IndexPart part;
415
 
      part= indx.index_part(partnr);
416
 
 
417
 
      *rec_per_key++= 0;
418
 
 
419
 
      key_part->field= NULL;
420
 
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
421
 
      key_part->null_bit= 0;
422
 
      /* key_part->null_offset is only set if null_bit (see later) */
423
 
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
424
 
      /* key_part->type ???? */
425
 
      key_part->key_part_flag= 0;
426
 
      if (part.has_in_reverse_order())
427
 
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
428
 
 
429
 
      key_part->length= part.compare_length();
430
 
 
431
 
      key_part->store_length= key_part->length;
432
 
 
433
 
      /* key_part->offset is set later */
434
 
      key_part->key_type= part.key_type();
435
 
    }
436
 
 
437
 
    if (! indx.has_comment())
438
 
    {
439
 
      keyinfo->comment.length= 0;
440
 
      keyinfo->comment.str= NULL;
441
 
    }
442
 
    else
443
 
    {
444
 
      keyinfo->flags|= HA_USES_COMMENT;
445
 
      keyinfo->comment.length= indx.comment().length();
446
 
      keyinfo->comment.str= strmake_root(&share->mem_root,
447
 
                                         indx.comment().c_str(),
448
 
                                         keyinfo->comment.length);
449
 
    }
450
 
 
451
 
    keyinfo->name= strmake_root(&share->mem_root,
452
 
                                indx.name().c_str(),
453
 
                                indx.name().length());
454
 
 
455
 
    share->keynames.type_names[keynr]= keyinfo->name;
456
 
    share->keynames.type_lengths[keynr]= indx.name().length();
457
 
  }
458
 
 
459
 
  share->keys_for_keyread.reset();
460
 
  set_prefix(share->keys_in_use, share->keys);
461
 
 
462
 
  share->fields= table.field_size();
463
 
 
464
 
  share->field= (Field**) alloc_root(&share->mem_root,
465
 
                                     ((share->fields+1) * sizeof(Field*)));
466
 
  share->field[share->fields]= NULL;
467
 
 
468
 
  uint32_t null_fields= 0;
469
 
  share->reclength= 0;
470
 
 
471
 
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
472
 
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
473
 
 
474
 
  assert(field_offsets && field_pack_length); // TODO: fixme
475
 
 
476
 
  uint32_t interval_count= 0;
477
 
  uint32_t interval_parts= 0;
478
 
 
479
 
  uint32_t stored_columns_reclength= 0;
480
 
 
481
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
482
 
  {
483
 
    message::Table::Field pfield= table.field(fieldnr);
484
 
    if (pfield.constraints().is_nullable())
485
 
      null_fields++;
486
 
 
487
 
    enum_field_types drizzle_field_type=
488
 
      proto_field_type_to_drizzle_type(pfield.type());
489
 
 
490
 
    field_offsets[fieldnr]= stored_columns_reclength;
491
 
 
492
 
    /* the below switch is very similar to
493
 
       CreateField::create_length_to_internal_length in field.cc
494
 
       (which should one day be replace by just this code)
495
 
    */
496
 
    switch(drizzle_field_type)
497
 
    {
498
 
    case DRIZZLE_TYPE_BLOB:
499
 
    case DRIZZLE_TYPE_VARCHAR:
500
 
      {
501
 
        message::Table::Field::StringFieldOptions field_options= pfield.string_options();
502
 
 
503
 
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
504
 
                                            field_options.collation_id() : 0);
505
 
 
506
 
        if (! cs)
507
 
          cs= default_charset_info;
508
 
 
509
 
        field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
510
 
                                                     field_options.length() * cs->mbmaxlen);
511
 
      }
512
 
      break;
513
 
    case DRIZZLE_TYPE_ENUM:
514
 
      {
515
 
        message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
516
 
 
517
 
        field_pack_length[fieldnr]=
518
 
          get_enum_pack_length(field_options.field_value_size());
519
 
 
520
 
        interval_count++;
521
 
        interval_parts+= field_options.field_value_size();
522
 
      }
523
 
      break;
524
 
    case DRIZZLE_TYPE_DECIMAL:
525
 
      {
526
 
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
527
 
 
528
 
        field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
529
 
      }
530
 
      break;
531
 
    default:
532
 
      /* Zero is okay here as length is fixed for other types. */
533
 
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
534
 
    }
535
 
 
536
 
    share->reclength+= field_pack_length[fieldnr];
537
 
    stored_columns_reclength+= field_pack_length[fieldnr];
538
 
  }
539
 
 
540
 
  /* data_offset added to stored_rec_length later */
541
 
  share->stored_rec_length= stored_columns_reclength;
542
 
 
543
 
  share->null_fields= null_fields;
544
 
 
545
 
  ulong null_bits= null_fields;
546
 
  if (! table_options.pack_record())
547
 
    null_bits++;
548
 
  ulong data_offset= (null_bits + 7)/8;
549
 
 
550
 
 
551
 
  share->reclength+= data_offset;
552
 
  share->stored_rec_length+= data_offset;
553
 
 
554
 
  ulong rec_buff_length;
555
 
 
556
 
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
 
550
    for (j=keyinfo->key_parts ; j-- ; key_part++)
 
551
    {
 
552
      *rec_per_key++=0;
 
553
      key_part->fieldnr=        (uint16_t) (uint2korr(strpos) & FIELD_NR_MASK);
 
554
      key_part->offset= (uint) uint2korr(strpos+2)-1;
 
555
      key_part->key_type=       (uint) uint2korr(strpos+5);
 
556
      // key_part->field=       (Field*) 0;     // Will be fixed later
 
557
      if (new_frm_ver >= 1)
 
558
      {
 
559
        key_part->key_part_flag= *(strpos+4);
 
560
        key_part->length=       (uint) uint2korr(strpos+7);
 
561
        strpos+=9;
 
562
      }
 
563
      else
 
564
      {
 
565
        key_part->length=       *(strpos+4);
 
566
        key_part->key_part_flag=0;
 
567
        if (key_part->length > 128)
 
568
        {
 
569
          key_part->length&=127;                /* purecov: inspected */
 
570
          key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
 
571
        }
 
572
        strpos+=7;
 
573
      }
 
574
      key_part->store_length=key_part->length;
 
575
    }
 
576
  }
 
577
  keynames=(char*) key_part;
 
578
  strpos+= (my_stpcpy(keynames, (char *) strpos) - keynames)+1;
 
579
 
 
580
  //reading index comments
 
581
  for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
 
582
  {
 
583
    if (keyinfo->flags & HA_USES_COMMENT)
 
584
    {
 
585
      keyinfo->comment.length= uint2korr(strpos);
 
586
      keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
 
587
                                         keyinfo->comment.length);
 
588
      strpos+= 2 + keyinfo->comment.length;
 
589
    } 
 
590
    assert(test(keyinfo->flags & HA_USES_COMMENT) == 
 
591
               (keyinfo->comment.length > 0));
 
592
  }
 
593
 
 
594
  share->reclength = uint2korr((head+16));
 
595
 
 
596
  record_offset= (ulong) (uint2korr(head+6)+
 
597
                          ((uint2korr(head+14) == 0xffff ?
 
598
                            uint4korr(head+47) : uint2korr(head+14))));
 
599
 
 
600
  if ((n_length= uint4korr(head+55)))
 
601
  {
 
602
    /* Read extra data segment */
 
603
    unsigned char *next_chunk, *buff_end;
 
604
    if (!(next_chunk= buff= (unsigned char*) my_malloc(n_length, MYF(MY_WME))))
 
605
      goto err;
 
606
    if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
 
607
    {
 
608
      goto err;
 
609
    }
 
610
    share->connect_string.length= uint2korr(buff);
 
611
    if (!(share->connect_string.str= strmake_root(&share->mem_root,
 
612
                                                  (char*) next_chunk + 2,
 
613
                                                  share->connect_string.
 
614
                                                  length)))
 
615
    {
 
616
      goto err;
 
617
    }
 
618
    next_chunk+= share->connect_string.length + 2;
 
619
    buff_end= buff + n_length;
 
620
    if (next_chunk + 2 < buff_end)
 
621
    {
 
622
      uint32_t str_db_type_length= uint2korr(next_chunk);
 
623
      LEX_STRING name;
 
624
      name.str= (char*) next_chunk + 2;
 
625
      name.length= str_db_type_length;
 
626
 
 
627
      plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
 
628
      if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
 
629
      {
 
630
        if (legacy_db_type > DB_TYPE_UNKNOWN &&
 
631
            legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
 
632
            legacy_db_type != ha_legacy_type(
 
633
                plugin_data(tmp_plugin, handlerton *)))
 
634
        {
 
635
          /* bad file, legacy_db_type did not match the name */
 
636
          free(buff);
 
637
          goto err;
 
638
        }
 
639
        /*
 
640
          tmp_plugin is locked with a local lock.
 
641
          we unlock the old value of share->db_plugin before
 
642
          replacing it with a globally locked version of tmp_plugin
 
643
        */
 
644
        plugin_unlock(NULL, share->db_plugin);
 
645
        share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
 
646
      }
 
647
      else if (!tmp_plugin)
 
648
      {
 
649
        /* purecov: begin inspected */
 
650
        error= 8;
 
651
        my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
 
652
        free(buff);
 
653
        goto err;
 
654
        /* purecov: end */
 
655
      }
 
656
      next_chunk+= str_db_type_length + 2;
 
657
    }
 
658
    if (share->mysql_version >= 50110)
 
659
    {
 
660
      /* New auto_partitioned indicator introduced in 5.1.11 */
 
661
      next_chunk++;
 
662
    }
 
663
    if (forminfo[46] == (unsigned char)255)
 
664
    {
 
665
      //reading long table comment
 
666
      if (next_chunk + 2 > buff_end)
 
667
      {
 
668
          free(buff);
 
669
          goto err;
 
670
      }
 
671
      share->comment.length = uint2korr(next_chunk);
 
672
      if (! (share->comment.str= strmake_root(&share->mem_root,
 
673
                               (char*)next_chunk + 2, share->comment.length)))
 
674
      {
 
675
          free(buff);
 
676
          goto err;
 
677
      }
 
678
      next_chunk+= 2 + share->comment.length;
 
679
    }
 
680
    assert(next_chunk <= buff_end);
 
681
    if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
 
682
    {
 
683
      /*
 
684
       New frm format in mysql_version 5.2.5 (originally in
 
685
       mysql-5.1.22-ndb-6.2.5)
 
686
       New column properties added:
 
687
       COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
 
688
       TABLESPACE name is now stored in frm
 
689
      */
 
690
      if (next_chunk >= buff_end)
 
691
      {
 
692
        if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
 
693
        {
 
694
          goto err;
 
695
        }
 
696
      }
 
697
      else
 
698
      {
 
699
        const uint32_t format_section_header_size= 8;
 
700
        uint32_t format_section_len= uint2korr(next_chunk+0);
 
701
 
 
702
        field_extra_info= next_chunk + format_section_header_size + 1;
 
703
        next_chunk+= format_section_len;
 
704
      }
 
705
    }
 
706
    assert (next_chunk <= buff_end);
 
707
    if (next_chunk > buff_end)
 
708
    {
 
709
      goto err;
 
710
    }
 
711
  }
 
712
  share->key_block_size= uint2korr(head+62);
 
713
 
 
714
  error=4;
 
715
  extra_rec_buf_length= uint2korr(head+59);
 
716
  rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
557
717
  share->rec_buff_length= rec_buff_length;
558
 
 
559
 
  unsigned char* record= NULL;
560
 
 
561
 
  if (! (record= (unsigned char *) alloc_root(&share->mem_root,
562
 
                                              rec_buff_length)))
563
 
    abort();
564
 
 
565
 
  memset(record, 0, rec_buff_length);
566
 
 
567
 
  int null_count= 0;
568
 
 
569
 
  if (! table_options.pack_record())
570
 
  {
571
 
    null_count++; // one bit for delete mark.
572
 
    *record|= 1;
573
 
  }
574
 
 
 
718
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
 
719
                                     rec_buff_length)))
 
720
    goto err;                                   /* purecov: inspected */
575
721
  share->default_values= record;
576
 
 
577
 
  if (interval_count)
 
722
  if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
 
723
    goto err;                                   /* purecov: inspected */
 
724
 
 
725
  my_seek(file,pos+288,MY_SEEK_SET,MYF(0));
 
726
 
 
727
  share->fields= uint2korr(forminfo+258);
 
728
  pos= uint2korr(forminfo+260);                 /* Length of all screens */
 
729
  n_length= uint2korr(forminfo+268);
 
730
  interval_count= uint2korr(forminfo+270);
 
731
  interval_parts= uint2korr(forminfo+272);
 
732
  int_length= uint2korr(forminfo+274);
 
733
  share->null_fields= uint2korr(forminfo+282);
 
734
  com_length= uint2korr(forminfo+284);
 
735
  if (forminfo[46] != (unsigned char)255)
578
736
  {
579
 
    share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
580
 
                                           interval_count*sizeof(TYPELIB));
 
737
    share->comment.length=  (int) (forminfo[46]);
 
738
    share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
 
739
                                     share->comment.length);
581
740
  }
582
 
  else
583
 
    share->intervals= NULL;
584
 
 
585
 
  share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
586
 
                                                          (share->fields + 1) * sizeof(char*));
587
 
 
588
 
  share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
589
 
                                                             (share->fields + 1) * sizeof(unsigned int));
590
 
 
591
 
  share->fieldnames.type_names[share->fields]= NULL;
592
 
  share->fieldnames.type_lengths[share->fields]= 0;
593
 
  share->fieldnames.count= share->fields;
594
 
 
595
 
 
596
 
  /* Now fix the TYPELIBs for the intervals (enum values)
597
 
     and field names.
598
 
   */
599
 
 
600
 
  uint32_t interval_nr= 0;
601
 
 
602
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
741
 
 
742
 
 
743
  if (!(field_ptr = (Field **)
 
744
        alloc_root(&share->mem_root,
 
745
                   (uint) ((share->fields+1)*sizeof(Field*)+
 
746
                           interval_count*sizeof(TYPELIB)+
 
747
                           (share->fields+interval_parts+
 
748
                            keys+3)*sizeof(char *)+
 
749
                           (n_length+int_length+com_length)))))
 
750
    goto err;                                   /* purecov: inspected */
 
751
 
 
752
  share->field= field_ptr;
 
753
  read_length=(uint) (share->fields * field_pack_length +
 
754
                      pos+ (uint) (n_length+int_length+com_length));
 
755
  if (read_string(file,(unsigned char**) &disk_buff,read_length))
 
756
    goto err;                                   /* purecov: inspected */
 
757
  strpos= disk_buff+pos;
 
758
 
 
759
  share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
 
760
  interval_array= (const char **) (share->intervals+interval_count);
 
761
  names= (char*) (interval_array+share->fields+interval_parts+keys+3);
 
762
  if (!interval_count)
 
763
    share->intervals= 0;                        // For better debugging
 
764
  memcpy(names, strpos+(share->fields*field_pack_length),
 
765
         (uint) (n_length+int_length));
 
766
  comment_pos= names+(n_length+int_length);
 
767
  memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
 
768
 
 
769
  fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
 
770
  if (share->fieldnames.count != share->fields)
 
771
    goto err;
 
772
  fix_type_pointers(&interval_array, share->intervals, interval_count,
 
773
                    &names);
 
774
 
603
775
  {
604
 
    message::Table::Field pfield= table.field(fieldnr);
605
 
 
606
 
    /* field names */
607
 
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
608
 
                                                        pfield.name().c_str(),
609
 
                                                        pfield.name().length());
610
 
 
611
 
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
612
 
 
613
 
    /* enum typelibs */
614
 
    if (pfield.type() != message::Table::Field::ENUM)
615
 
      continue;
616
 
 
617
 
    message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
618
 
 
619
 
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
620
 
                                             field_options.collation_id() : 0);
621
 
 
622
 
    if (! charset)
623
 
      charset= default_charset_info;
624
 
 
625
 
    TYPELIB *t= &(share->intervals[interval_nr]);
626
 
 
627
 
    t->type_names= (const char**)alloc_root(&share->mem_root,
628
 
                                            (field_options.field_value_size() + 1) * sizeof(char*));
629
 
 
630
 
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
631
 
                                                (field_options.field_value_size() + 1) * sizeof(unsigned int));
632
 
 
633
 
    t->type_names[field_options.field_value_size()]= NULL;
634
 
    t->type_lengths[field_options.field_value_size()]= 0;
635
 
 
636
 
    t->count= field_options.field_value_size();
637
 
    t->name= NULL;
638
 
 
639
 
    for (int n= 0; n < field_options.field_value_size(); n++)
 
776
    /* Set ENUM and SET lengths */
 
777
    TYPELIB *interval;
 
778
    for (interval= share->intervals;
 
779
         interval < share->intervals + interval_count;
 
780
         interval++)
640
781
    {
641
 
      t->type_names[n]= strmake_root(&share->mem_root,
642
 
                                     field_options.field_value(n).c_str(),
643
 
                                     field_options.field_value(n).length());
644
 
 
645
 
      /* 
646
 
       * Go ask the charset what the length is as for "" length=1
647
 
       * and there's stripping spaces or some other crack going on.
648
 
       */
649
 
      uint32_t lengthsp;
650
 
      lengthsp= charset->cset->lengthsp(charset,
651
 
                                        t->type_names[n],
652
 
                                        field_options.field_value(n).length());
653
 
      t->type_lengths[n]= lengthsp;
 
782
      uint32_t count= (uint) (interval->count + 1) * sizeof(uint);
 
783
      if (!(interval->type_lengths= (uint32_t *) alloc_root(&share->mem_root,
 
784
                                                        count)))
 
785
        goto err;
 
786
      for (count= 0; count < interval->count; count++)
 
787
      {
 
788
        char *val= (char*) interval->type_names[count];
 
789
        interval->type_lengths[count]= strlen(val);
 
790
      }
 
791
      interval->type_lengths[count]= 0;
654
792
    }
655
 
    interval_nr++;
656
 
  }
657
 
 
658
 
 
659
 
  /* and read the fields */
660
 
  interval_nr= 0;
661
 
 
662
 
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
663
 
 
 
793
  }
 
794
 
 
795
  if (keynames)
 
796
    fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
 
797
 
 
798
 /* Allocate handler */
 
799
  if (!(handler_file= get_new_handler(share, thd->mem_root,
 
800
                                      share->db_type())))
 
801
    goto err;
 
802
 
 
803
  record= share->default_values-1;              /* Fieldstart = 1 */
 
804
  if (share->null_field_first)
 
805
  {
 
806
    null_flags= null_pos= (unsigned char*) record+1;
 
807
    null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
 
808
    /*
 
809
      null_bytes below is only correct under the condition that
 
810
      there are no bit fields.  Correct values is set below after the
 
811
      table struct is initialized
 
812
    */
 
813
    share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
 
814
  }
 
815
 
 
816
  use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
664
817
  if (use_hash)
665
 
    use_hash= ! hash_init(&share->name_hash,
666
 
                          system_charset_info,
667
 
                          share->fields,
668
 
                          0,
669
 
                          0,
670
 
                          (hash_get_key) get_field_name,
671
 
                          0,
672
 
                          0);
673
 
 
674
 
  unsigned char* null_pos= record;;
675
 
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
676
 
 
677
 
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
 
818
    use_hash= !hash_init(&share->name_hash,
 
819
                         system_charset_info,
 
820
                         share->fields,0,0,
 
821
                         (hash_get_key) get_field_name,0,0);
 
822
 
 
823
  for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
678
824
  {
679
 
    message::Table::Field pfield= table.field(fieldnr);
680
 
 
 
825
    uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
 
826
    enum_field_types field_type;
681
827
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
682
 
 
683
 
    switch (pfield.format())
684
 
    {
685
 
    case message::Table::Field::DefaultFormat:
686
 
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
687
 
      break;
688
 
    case message::Table::Field::FixedFormat:
689
 
      column_format= COLUMN_FORMAT_TYPE_FIXED;
690
 
      break;
691
 
    case message::Table::Field::DynamicFormat:
692
 
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
693
 
      break;
694
 
    default:
695
 
      assert(1);
696
 
    }
697
 
 
698
 
    Field::utype unireg_type= Field::NONE;
699
 
 
700
 
    if (pfield.has_numeric_options() &&
701
 
        pfield.numeric_options().is_autoincrement())
702
 
    {
703
 
      unireg_type= Field::NEXT_NUMBER;
704
 
    }
705
 
 
706
 
    if (pfield.has_options() &&
707
 
        pfield.options().has_default_value() &&
708
 
        pfield.options().default_value().compare("NOW()") == 0)
709
 
    {
710
 
      if (pfield.options().has_update_value() &&
711
 
          pfield.options().update_value().compare("NOW()") == 0)
712
 
      {
713
 
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
714
 
      }
715
 
      else if (! pfield.options().has_update_value())
716
 
      {
717
 
        unireg_type= Field::TIMESTAMP_DN_FIELD;
718
 
      }
719
 
      else
720
 
        assert(1); // Invalid update value.
721
 
    }
722
 
    else if (pfield.has_options() &&
723
 
             pfield.options().has_update_value() &&
724
 
             pfield.options().update_value().compare("NOW()") == 0)
725
 
    {
726
 
      unireg_type= Field::TIMESTAMP_UN_FIELD;
727
 
    }
728
 
 
 
828
    const CHARSET_INFO *charset= NULL;
729
829
    LEX_STRING comment;
730
 
    if (!pfield.has_comment())
731
 
    {
732
 
      comment.str= (char*)"";
733
 
      comment.length= 0;
 
830
 
 
831
    if (field_extra_info)
 
832
    {
 
833
      char tmp= field_extra_info[i];
 
834
      column_format= (enum column_format_type)
 
835
                    ((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
 
836
    }
 
837
    if (new_frm_ver >= 3)
 
838
    {
 
839
      /* new frm file in 4.1 */
 
840
      field_length= uint2korr(strpos+3);
 
841
      recpos=       uint3korr(strpos+5);
 
842
      pack_flag=    uint2korr(strpos+8);
 
843
      unireg_type=  (uint) strpos[10];
 
844
      interval_nr=  (uint) strpos[12];
 
845
      uint32_t comment_length=uint2korr(strpos+15);
 
846
      field_type=(enum_field_types) (uint) strpos[13];
 
847
 
 
848
      {
 
849
        if (!strpos[14])
 
850
          charset= &my_charset_bin;
 
851
        else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
 
852
        {
 
853
          error= 5; // Unknown or unavailable charset
 
854
          errarg= (int) strpos[14];
 
855
          goto err;
 
856
        }
 
857
      }
 
858
      if (!comment_length)
 
859
      {
 
860
        comment.str= (char*) "";
 
861
        comment.length=0;
 
862
      }
 
863
      else
 
864
      {
 
865
        comment.str=    (char*) comment_pos;
 
866
        comment.length= comment_length;
 
867
        comment_pos+=   comment_length;
 
868
      }
734
869
    }
735
870
    else
736
871
    {
737
 
      size_t len= pfield.comment().length();
738
 
      const char* str= pfield.comment().c_str();
739
 
 
740
 
      comment.str= strmake_root(&share->mem_root, str, len);
741
 
      comment.length= len;
742
 
    }
743
 
 
744
 
    enum_field_types field_type;
745
 
 
746
 
    field_type= proto_field_type_to_drizzle_type(pfield.type());
747
 
 
748
 
    const CHARSET_INFO *charset= &my_charset_bin;
749
 
 
750
 
    if (field_type == DRIZZLE_TYPE_BLOB ||
751
 
        field_type == DRIZZLE_TYPE_VARCHAR)
752
 
    {
753
 
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
754
 
 
755
 
      charset= get_charset(field_options.has_collation_id() ?
756
 
                           field_options.collation_id() : 0);
757
 
 
758
 
      if (! charset)
759
 
        charset= default_charset_info;
760
 
    }
761
 
 
762
 
    if (field_type == DRIZZLE_TYPE_ENUM)
763
 
    {
764
 
      message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
765
 
 
766
 
      charset= get_charset(field_options.has_collation_id()?
767
 
                           field_options.collation_id() : 0);
768
 
 
769
 
      if (! charset)
770
 
              charset= default_charset_info;
771
 
    }
772
 
 
773
 
    uint8_t decimals= 0;
774
 
    if (field_type == DRIZZLE_TYPE_DECIMAL
775
 
        || field_type == DRIZZLE_TYPE_DOUBLE)
776
 
    {
777
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
778
 
 
779
 
      if (! pfield.has_numeric_options() || ! fo.has_scale())
 
872
      field_length= (uint) strpos[3];
 
873
      recpos=       uint2korr(strpos+4),
 
874
      pack_flag=    uint2korr(strpos+6);
 
875
      pack_flag&=   ~FIELDFLAG_NO_DEFAULT;     // Safety for old files
 
876
      unireg_type=  (uint) strpos[8];
 
877
      interval_nr=  (uint) strpos[10];
 
878
 
 
879
      /* old frm file */
 
880
      field_type= (enum_field_types) f_packtype(pack_flag);
 
881
      if (f_is_binary(pack_flag))
780
882
      {
781
883
        /*
782
 
          We don't write the default to table proto so
783
 
          if no decimals specified for DOUBLE, we use the default.
 
884
          Try to choose the best 4.1 type:
 
885
          - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" 
 
886
            try to find a binary collation for character set.
 
887
          - for other types (e.g. BLOB) just use my_charset_bin. 
784
888
        */
785
 
        decimals= NOT_FIXED_DEC;
786
 
      }
787
 
      else
788
 
      {
789
 
        if (fo.scale() > DECIMAL_MAX_SCALE)
790
 
        {
791
 
          error= 4;
792
 
          goto err;
793
 
        }
794
 
        decimals= static_cast<uint8_t>(fo.scale());
795
 
      }
796
 
    }
797
 
 
798
 
    Item *default_value= NULL;
799
 
 
800
 
    if (pfield.options().has_default_value() ||
801
 
        pfield.options().has_default_null()  ||
802
 
        pfield.options().has_default_bin_value())
803
 
    {
804
 
      default_value= default_value_item(field_type,
805
 
                                        charset,
806
 
                                        pfield.options().default_null(),
807
 
                                        &pfield.options().default_value(),
808
 
                                        &pfield.options().default_bin_value());
809
 
    }
810
 
 
811
 
 
812
 
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
813
 
    memset(&temp_table, 0, sizeof(temp_table));
814
 
    temp_table.s= share;
815
 
    temp_table.in_use= &session;
816
 
    temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
817
 
    temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
818
 
 
819
 
    uint32_t field_length= 0; //Assignment is for compiler complaint.
820
 
 
821
 
    switch (field_type)
822
 
    {
823
 
    case DRIZZLE_TYPE_BLOB:
824
 
    case DRIZZLE_TYPE_VARCHAR:
825
 
    {
826
 
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
827
 
 
828
 
      charset= get_charset(field_options.has_collation_id() ?
829
 
                           field_options.collation_id() : 0);
830
 
 
831
 
      if (! charset)
832
 
        charset= default_charset_info;
833
 
 
834
 
      field_length= field_options.length() * charset->mbmaxlen;
835
 
    }
836
 
      break;
837
 
    case DRIZZLE_TYPE_DOUBLE:
838
 
    {
839
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
840
 
      if (!fo.has_precision() && !fo.has_scale())
841
 
      {
842
 
        field_length= DBL_DIG+7;
843
 
      }
844
 
      else
845
 
      {
846
 
        field_length= fo.precision();
847
 
      }
848
 
      if (field_length < decimals &&
849
 
          decimals != NOT_FIXED_DEC)
850
 
      {
851
 
        my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
852
 
        error= 1;
853
 
        goto err;
854
 
      }
855
 
      break;
856
 
    }
857
 
    case DRIZZLE_TYPE_DECIMAL:
858
 
    {
859
 
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
860
 
 
861
 
      field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
862
 
                                                   false);
863
 
      break;
864
 
    }
865
 
    case DRIZZLE_TYPE_TIMESTAMP:
866
 
    case DRIZZLE_TYPE_DATETIME:
867
 
      field_length= DateTime::MAX_STRING_LENGTH;
868
 
      break;
869
 
    case DRIZZLE_TYPE_DATE:
870
 
      field_length= Date::MAX_STRING_LENGTH;
871
 
      break;
872
 
    case DRIZZLE_TYPE_ENUM:
873
 
    {
874
 
      field_length= 0;
875
 
 
876
 
      message::Table::Field::EnumerationValues fo= pfield.enumeration_values();
877
 
 
878
 
      for (int valnr= 0; valnr < fo.field_value_size(); valnr++)
879
 
      {
880
 
        if (fo.field_value(valnr).length() > field_length)
881
 
        {
882
 
          field_length= charset->cset->numchars(charset,
883
 
                                                fo.field_value(valnr).c_str(),
884
 
                                                fo.field_value(valnr).c_str()
885
 
                                                + fo.field_value(valnr).length())
886
 
            * charset->mbmaxlen;
887
 
        }
888
 
      }
889
 
    }
890
 
    break;
891
 
    case DRIZZLE_TYPE_LONG:
892
 
      {
893
 
        uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
894
 
          field_length= MAX_INT_WIDTH+sign_len;
895
 
      }
896
 
      break;
897
 
    case DRIZZLE_TYPE_LONGLONG:
898
 
      field_length= MAX_BIGINT_WIDTH;
899
 
      break;
900
 
    case DRIZZLE_TYPE_NULL:
901
 
      abort(); // Programming error
902
 
    }
903
 
 
904
 
    Field* f= make_field(share,
905
 
                         &share->mem_root,
906
 
                         record + field_offsets[fieldnr] + data_offset,
907
 
                         field_length,
908
 
                         pfield.constraints().is_nullable(),
909
 
                         null_pos,
910
 
                         null_bit_pos,
911
 
                         decimals,
912
 
                         field_type,
913
 
                         charset,
914
 
                         (Field::utype) MTYP_TYPENR(unireg_type),
915
 
                         ((field_type == DRIZZLE_TYPE_ENUM) ?
916
 
                          share->intervals + (interval_nr++)
917
 
                          : (TYPELIB*) 0),
918
 
                         share->fieldnames.type_names[fieldnr]);
919
 
 
920
 
    share->field[fieldnr]= f;
921
 
 
922
 
    f->init(&temp_table); /* blob default values need table obj */
923
 
 
924
 
    if (! (f->flags & NOT_NULL_FLAG))
925
 
    {
926
 
      *f->null_ptr|= f->null_bit;
927
 
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
 
889
        if (!f_is_blob(pack_flag))
 
890
        {
 
891
          // 3.23 or 4.0 string
 
892
          if (!(charset= get_charset_by_csname(share->table_charset->csname,
 
893
                                               MY_CS_BINSORT, MYF(0))))
 
894
            charset= &my_charset_bin;
 
895
        }
 
896
        else
 
897
          charset= &my_charset_bin;
 
898
      }
 
899
      else
 
900
        charset= share->table_charset;
 
901
      memset(&comment, 0, sizeof(comment));
 
902
    }
 
903
 
 
904
    if (interval_nr && charset->mbminlen > 1)
 
905
    {
 
906
      /* Unescape UCS2 intervals from HEX notation */
 
907
      TYPELIB *interval= share->intervals + interval_nr - 1;
 
908
      unhex_type2(interval);
 
909
    }
 
910
 
 
911
    *field_ptr= reg_field=
 
912
      make_field(share, record+recpos,
 
913
                 (uint32_t) field_length,
 
914
                 null_pos, null_bit_pos,
 
915
                 pack_flag,
 
916
                 field_type,
 
917
                 charset,
 
918
                 (Field::utype) MTYP_TYPENR(unireg_type),
 
919
                 (interval_nr ?
 
920
                  share->intervals+interval_nr-1 :
 
921
                  (TYPELIB*) 0),
 
922
                 share->fieldnames.type_names[i]);
 
923
    if (!reg_field)                             // Not supported field type
 
924
    {
 
925
      error= 4;
 
926
      goto err;                 /* purecov: inspected */
 
927
    }
 
928
 
 
929
    reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
 
930
    reg_field->field_index= i;
 
931
    reg_field->comment=comment;
 
932
    if (!(reg_field->flags & NOT_NULL_FLAG))
 
933
    {
 
934
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
928
935
        null_pos++;
929
 
      null_count++;
930
 
    }
931
 
 
932
 
    if (default_value)
933
 
    {
934
 
      enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
935
 
      session.count_cuted_fields= CHECK_FIELD_WARN;
936
 
      int res= default_value->save_in_field(f, 1);
937
 
      session.count_cuted_fields= old_count_cuted_fields;
938
 
      if (res != 0 && res != 3) /* @TODO Huh? */
939
 
      {
940
 
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
941
 
        error= 1;
942
 
        goto err;
943
 
      }
944
 
    }
945
 
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
946
 
             (f->flags & NOT_NULL_FLAG))
947
 
    {
948
 
      f->set_notnull();
949
 
      f->store((int64_t) 1, true);
950
 
    }
951
 
    else
952
 
      f->reset();
953
 
 
954
 
    /* hack to undo f->init() */
955
 
    f->table= NULL;
956
 
    f->orig_table= NULL;
957
 
 
958
 
    f->field_index= fieldnr;
959
 
    f->comment= comment;
960
 
    if (! default_value &&
961
 
        ! (f->unireg_check==Field::NEXT_NUMBER) &&
962
 
        (f->flags & NOT_NULL_FLAG) &&
963
 
        (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
964
 
    {
965
 
      f->flags|= NO_DEFAULT_VALUE_FLAG;
966
 
    }
967
 
 
968
 
    if (f->unireg_check == Field::NEXT_NUMBER)
969
 
      share->found_next_number_field= &(share->field[fieldnr]);
970
 
 
971
 
    if (share->timestamp_field == f)
972
 
      share->timestamp_field_offset= fieldnr;
973
 
 
974
 
    if (use_hash) /* supposedly this never fails... but comments lie */
 
936
    }
 
937
    if (f_no_default(pack_flag))
 
938
      reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
 
939
 
 
940
    if (reg_field->unireg_check == Field::NEXT_NUMBER)
 
941
      share->found_next_number_field= field_ptr;
 
942
    if (share->timestamp_field == reg_field)
 
943
      share->timestamp_field_offset= i;
 
944
 
 
945
    if (use_hash)
975
946
      (void) my_hash_insert(&share->name_hash,
976
 
                            (unsigned char*)&(share->field[fieldnr]));
977
 
 
978
 
  }
979
 
 
980
 
  keyinfo= share->key_info;
981
 
  for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
982
 
  {
983
 
    key_part= keyinfo->key_part;
984
 
 
985
 
    for (unsigned int partnr= 0;
986
 
         partnr < keyinfo->key_parts;
987
 
         partnr++, key_part++)
988
 
    {
989
 
      /* 
990
 
       * Fix up key_part->offset by adding data_offset.
991
 
       * We really should compute offset as well.
992
 
       * But at least this way we are a little better.
993
 
       */
994
 
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
995
 
    }
996
 
  }
997
 
 
998
 
  /*
999
 
    We need to set the unused bits to 1. If the number of bits is a multiple
1000
 
    of 8 there are no unused bits.
1001
 
  */
1002
 
 
1003
 
  if (null_count & 7)
1004
 
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1005
 
 
1006
 
  share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1007
 
 
1008
 
  share->last_null_bit_pos= null_bit_pos;
1009
 
 
1010
 
  free(field_offsets);
1011
 
  field_offsets= NULL;
1012
 
  free(field_pack_length);
1013
 
  field_pack_length= NULL;
1014
 
 
1015
 
  /* Fix key stuff */
1016
 
  if (share->key_parts)
1017
 
  {
1018
 
    uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1019
 
                                                &share->keynames, 3) - 1); /* @TODO Huh? */
1020
 
 
 
947
                            (unsigned char*) field_ptr); // never fail
 
948
  }
 
949
  *field_ptr=0;                                 // End marker
 
950
 
 
951
  /* Fix key->name and key_part->field */
 
952
  if (key_parts)
 
953
  {
 
954
    uint32_t primary_key=(uint) (find_type((char*) primary_key_name,
 
955
                                       &share->keynames, 3) - 1);
 
956
    int64_t ha_option= handler_file->ha_table_flags();
1021
957
    keyinfo= share->key_info;
1022
958
    key_part= keyinfo->key_part;
1023
959
 
1024
 
    for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
 
960
    for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1025
961
    {
1026
962
      uint32_t usable_parts= 0;
 
963
      keyinfo->name=(char*) share->keynames.type_names[key];
1027
964
 
1028
965
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1029
966
      {
1030
 
        /*
1031
 
          If the UNIQUE key doesn't have NULL columns and is not a part key
1032
 
          declare this as a primary key.
1033
 
        */
1034
 
        primary_key=key;
1035
 
        for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1036
 
        {
1037
 
          uint32_t fieldnr= key_part[i].fieldnr;
1038
 
          if (! fieldnr ||
1039
 
              share->field[fieldnr-1]->null_ptr ||
1040
 
              share->field[fieldnr-1]->key_length() != key_part[i].length)
1041
 
          {
1042
 
            primary_key= MAX_KEY; // Can't be used
1043
 
            break;
1044
 
          }
1045
 
        }
 
967
        /*
 
968
          If the UNIQUE key doesn't have NULL columns and is not a part key
 
969
          declare this as a primary key.
 
970
        */
 
971
        primary_key=key;
 
972
        for (i=0 ; i < keyinfo->key_parts ;i++)
 
973
        {
 
974
          uint32_t fieldnr= key_part[i].fieldnr;
 
975
          if (!fieldnr ||
 
976
              share->field[fieldnr-1]->null_ptr ||
 
977
              share->field[fieldnr-1]->key_length() !=
 
978
              key_part[i].length)
 
979
          {
 
980
            primary_key=MAX_KEY;                // Can't be used
 
981
            break;
 
982
          }
 
983
        }
1046
984
      }
1047
985
 
1048
 
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
 
986
      for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1049
987
      {
1050
988
        Field *field;
1051
 
        if (! key_part->fieldnr)
 
989
        if (new_field_pack_flag <= 1)
 
990
          key_part->fieldnr= (uint16_t) find_field(share->field,
 
991
                                                 share->default_values,
 
992
                                                 (uint) key_part->offset,
 
993
                                                 (uint) key_part->length);
 
994
        if (!key_part->fieldnr)
1052
995
        {
1053
 
          abort(); // goto err;
 
996
          error= 4;                             // Wrong file
 
997
          goto err;
1054
998
        }
1055
999
        field= key_part->field= share->field[key_part->fieldnr-1];
1056
1000
        key_part->type= field->key_type();
1057
1001
        if (field->null_ptr)
1058
1002
        {
1059
 
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
 
1003
          key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
1060
1004
                                        share->default_values);
1061
1005
          key_part->null_bit= field->null_bit;
1062
1006
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1080
1024
                           (keyinfo->key_parts == 1)) ?
1081
1025
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1082
1026
        if (i == 0)
1083
 
          field->key_start.set(key);
 
1027
          field->key_start.set_bit(key);
1084
1028
        if (field->key_length() == key_part->length &&
1085
1029
            !(field->flags & BLOB_FLAG))
1086
1030
        {
1087
 
          enum ha_key_alg algo= share->key_info[key].algorithm;
1088
 
          if (share->db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
 
1031
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1089
1032
          {
1090
 
            share->keys_for_keyread.set(key);
1091
 
            field->part_of_key.set(key);
1092
 
            field->part_of_key_not_clustered.set(key);
 
1033
            share->keys_for_keyread.set_bit(key);
 
1034
            field->part_of_key.set_bit(key);
 
1035
            field->part_of_key_not_clustered.set_bit(key);
1093
1036
          }
1094
 
          if (share->db_type()->index_flags(algo) & HA_READ_ORDER)
1095
 
            field->part_of_sortkey.set(key);
 
1037
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
 
1038
            field->part_of_sortkey.set_bit(key);
1096
1039
        }
1097
1040
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1098
1041
            usable_parts == i)
1105
1048
            If this field is part of the primary key and all keys contains
1106
1049
            the primary key, then we can use any key to find this column
1107
1050
          */
1108
 
          if (share->storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
 
1051
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1109
1052
          {
1110
1053
            field->part_of_key= share->keys_in_use;
1111
 
            if (field->part_of_sortkey.test(key))
 
1054
            if (field->part_of_sortkey.is_set(key))
1112
1055
              field->part_of_sortkey= share->keys_in_use;
1113
1056
          }
1114
1057
        }
1122
1065
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1123
1066
                    keyinfo->key_parts);
1124
1067
      share->total_key_length+= keyinfo->key_length;
1125
 
 
1126
 
      if (keyinfo->flags & HA_NOSAME)
1127
 
      {
 
1068
      /*
 
1069
        MERGE tables do not have unique indexes. But every key could be
 
1070
        an unique index on the underlying MyISAM table. (Bug #10400)
 
1071
      */
 
1072
      if ((keyinfo->flags & HA_NOSAME) ||
 
1073
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1128
1074
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1129
 
      }
1130
1075
    }
1131
1076
    if (primary_key < MAX_KEY &&
1132
 
        (share->keys_in_use.test(primary_key)))
 
1077
        (share->keys_in_use.is_set(primary_key)))
1133
1078
    {
1134
1079
      share->primary_key= primary_key;
1135
1080
      /*
1136
 
        If we are using an integer as the primary key then allow the user to
1137
 
        refer to it as '_rowid'
 
1081
        If we are using an integer as the primary key then allow the user to
 
1082
        refer to it as '_rowid'
1138
1083
      */
1139
1084
      if (share->key_info[primary_key].key_parts == 1)
1140
1085
      {
1141
 
        Field *field= share->key_info[primary_key].key_part[0].field;
1142
 
        if (field && field->result_type() == INT_RESULT)
 
1086
        Field *field= share->key_info[primary_key].key_part[0].field;
 
1087
        if (field && field->result_type() == INT_RESULT)
1143
1088
        {
1144
1089
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1145
 
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
 
1090
          share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1146
1091
                                      fieldnr);
1147
1092
        }
1148
1093
      }
1152
1097
  }
1153
1098
  else
1154
1099
    share->primary_key= MAX_KEY;
 
1100
  if (disk_buff)
 
1101
    free(disk_buff);
 
1102
  disk_buff= NULL;
 
1103
  if (new_field_pack_flag <= 1)
 
1104
  {
 
1105
    /* Old file format with default as not null */
 
1106
    uint32_t null_length= (share->null_fields+7)/8;
 
1107
    memset(share->default_values + (null_flags - (unsigned char*) record), 
 
1108
          null_length, 255);
 
1109
  }
1155
1110
 
1156
1111
  if (share->found_next_number_field)
1157
1112
  {
1158
 
    Field *reg_field= *share->found_next_number_field;
1159
 
    if ((int) (share->next_number_index= (uint32_t)
 
1113
    reg_field= *share->found_next_number_field;
 
1114
    if ((int) (share->next_number_index= (uint)
1160
1115
               find_ref_key(share->key_info, share->keys,
1161
1116
                            share->default_values, reg_field,
1162
1117
                            &share->next_number_key_offset,
1178
1133
    /* Store offsets to blob fields to find them fast */
1179
1134
    if (!(share->blob_field= save=
1180
1135
          (uint*) alloc_root(&share->mem_root,
1181
 
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
 
1136
                             (uint) (share->blob_fields* sizeof(uint)))))
1182
1137
      goto err;
1183
 
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
 
1138
    for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1184
1139
    {
1185
1140
      if ((*ptr)->flags & BLOB_FLAG)
1186
 
        (*save++)= k;
 
1141
        (*save++)= k;
1187
1142
    }
1188
1143
  }
1189
1144
 
1190
 
  share->db_low_byte_first= true; // @todo Question this.
 
1145
  /*
 
1146
    the correct null_bytes can now be set, since bitfields have been taken
 
1147
    into account
 
1148
  */
 
1149
  share->null_bytes= (null_pos - (unsigned char*) null_flags +
 
1150
                      (null_bit_pos + 7) / 8);
 
1151
  share->last_null_bit_pos= null_bit_pos;
 
1152
 
 
1153
  share->db_low_byte_first= handler_file->low_byte_first();
1191
1154
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1192
1155
 
1193
 
  my_bitmap_map *bitmaps;
1194
 
 
1195
1156
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1196
1157
                                             share->column_bitmap_size)))
1197
1158
    goto err;
1198
 
  share->all_set.init(bitmaps, share->fields);
1199
 
  share->all_set.setAll();
 
1159
  bitmap_init(&share->all_set, bitmaps, share->fields, false);
 
1160
  bitmap_set_all(&share->all_set);
1200
1161
 
 
1162
  delete handler_file;
 
1163
  if (buff)
 
1164
    free(buff);
1201
1165
  return (0);
1202
1166
 
1203
 
err:
1204
 
  if (field_offsets)
1205
 
    free(field_offsets);
1206
 
  if (field_pack_length)
1207
 
    free(field_pack_length);
1208
 
 
 
1167
 err:
 
1168
  if (buff)
 
1169
    free(buff);
1209
1170
  share->error= error;
1210
 
  share->open_errno= errno;
1211
 
  share->errarg= 0;
 
1171
  share->open_errno= my_errno;
 
1172
  share->errarg= errarg;
 
1173
  if (disk_buff)
 
1174
    free(disk_buff);
 
1175
  delete handler_file;
1212
1176
  hash_free(&share->name_hash);
1213
 
  share->open_table_error(error, share->open_errno, 0);
1214
 
 
1215
 
  return error;
1216
 
}
1217
 
 
1218
 
/*
1219
 
  Read table definition from a binary / text based .frm cursor
1220
 
 
1221
 
  SYNOPSIS
1222
 
  open_table_def()
1223
 
  session               Thread Cursor
1224
 
  share         Fill this with table definition
1225
 
 
1226
 
  NOTES
1227
 
    This function is called when the table definition is not cached in
1228
 
    table_def_cache
1229
 
    The data is returned in 'share', which is alloced by
1230
 
    alloc_table_share().. The code assumes that share is initialized.
1231
 
 
1232
 
  RETURN VALUES
1233
 
   0    ok
1234
 
   1    Error (see open_table_error)
1235
 
   2    Error (see open_table_error)
1236
 
   3    Wrong data in .frm cursor
1237
 
   4    Error (see open_table_error)
1238
 
   5    Error (see open_table_error: charset unavailable)
1239
 
   6    Unknown .frm version
1240
 
*/
1241
 
 
1242
 
int open_table_def(Session& session, TableIdentifier &identifier, TableShare *share)
1243
 
{
1244
 
  int error;
1245
 
  bool error_given;
1246
 
 
1247
 
  error= 1;
1248
 
  error_given= 0;
1249
 
 
1250
 
  message::Table table;
1251
 
 
1252
 
  error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1253
 
 
1254
 
  if (error != EEXIST)
1255
 
  {
1256
 
    if (error > 0)
1257
 
    {
1258
 
      errno= error;
1259
 
      error= 1;
1260
 
    }
1261
 
    else
1262
 
    {
1263
 
      if (not table.IsInitialized())
1264
 
      {
1265
 
        error= 4;
1266
 
      }
1267
 
    }
1268
 
    goto err_not_open;
1269
 
  }
1270
 
 
1271
 
  error= parse_table_proto(session, table, share);
1272
 
 
1273
 
  share->table_category= TABLE_CATEGORY_USER;
1274
 
 
1275
 
err_not_open:
1276
 
  if (error && !error_given)
1277
 
  {
1278
 
    share->error= error;
1279
 
    share->open_table_error(error, (share->open_errno= errno), 0);
1280
 
  }
1281
 
 
 
1177
 
 
1178
  open_table_error(share, error, share->open_errno, errarg);
1282
1179
  return(error);
1283
 
}
 
1180
} /* open_binary_frm */
1284
1181
 
1285
1182
 
1286
1183
/*
1287
 
  Open a table based on a TableShare
 
1184
  Open a table based on a TABLE_SHARE
1288
1185
 
1289
1186
  SYNOPSIS
1290
1187
    open_table_from_share()
1291
 
    session                     Thread Cursor
 
1188
    thd                 Thread handler
1292
1189
    share               Table definition
1293
1190
    alias               Alias for table
1294
1191
    db_stat             open flags (for example HA_OPEN_KEYFILE|
1295
1192
                        HA_OPEN_RNDFILE..) can be 0 (example in
1296
1193
                        ha_example_table)
 
1194
    prgflag             READ_ALL etc..
1297
1195
    ha_open_flags       HA_OPEN_ABORT_IF_LOCKED etc..
1298
1196
    outparam            result table
 
1197
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
 
1198
                        if OTM_CREATE some errors are ignore
 
1199
                        if OTM_ALTER HA_OPEN is not called
1299
1200
 
1300
1201
  RETURN VALUES
1301
1202
   0    ok
1302
1203
   1    Error (see open_table_error)
1303
1204
   2    Error (see open_table_error)
1304
 
   3    Wrong data in .frm cursor
 
1205
   3    Wrong data in .frm file
1305
1206
   4    Error (see open_table_error)
1306
1207
   5    Error (see open_table_error: charset unavailable)
1307
1208
   7    Table definition has changed in engine
1308
1209
*/
1309
1210
 
1310
 
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1311
 
                          uint32_t db_stat, uint32_t ha_open_flags,
1312
 
                          Table *outparam)
 
1211
int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
 
1212
                          uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
 
1213
                          Table *outparam, open_table_mode open_mode)
1313
1214
{
1314
1215
  int error;
1315
1216
  uint32_t records, i, bitmap_size;
1317
1218
  unsigned char *record, *bitmaps;
1318
1219
  Field **field_ptr;
1319
1220
 
1320
 
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1321
 
  assert(session->lex->is_lex_started);
 
1221
  /* Parsing of partitioning information from .frm needs thd->lex set up. */
 
1222
  assert(thd->lex->is_lex_started);
1322
1223
 
1323
1224
  error= 1;
1324
 
  outparam->resetTable(session, share, db_stat);
1325
 
 
1326
 
 
1327
 
  if (not (outparam->alias= strdup(alias)))
1328
 
    goto err;
1329
 
 
1330
 
  /* Allocate Cursor */
1331
 
  if (not (outparam->cursor= share->db_type()->getCursor(*share, &outparam->mem_root)))
1332
 
    goto err;
 
1225
  memset(outparam, 0, sizeof(*outparam));
 
1226
  outparam->in_use= thd;
 
1227
  outparam->s= share;
 
1228
  outparam->db_stat= db_stat;
 
1229
  outparam->write_row_record= NULL;
 
1230
 
 
1231
  init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
1232
 
 
1233
  if (!(outparam->alias= my_strdup(alias, MYF(MY_WME))))
 
1234
    goto err;
 
1235
  outparam->quick_keys.init();
 
1236
  outparam->covering_keys.init();
 
1237
  outparam->keys_in_use_for_query.init();
 
1238
 
 
1239
  /* Allocate handler */
 
1240
  outparam->file= 0;
 
1241
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
 
1242
  {
 
1243
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
 
1244
                                          share->db_type())))
 
1245
      goto err;
 
1246
  }
 
1247
  else
 
1248
  {
 
1249
    assert(!db_stat);
 
1250
  }
1333
1251
 
1334
1252
  error= 4;
1335
 
  records= 0;
1336
 
  if ((db_stat & HA_OPEN_KEYFILE))
 
1253
  outparam->reginfo.lock_type= TL_UNLOCK;
 
1254
  outparam->current_lock= F_UNLCK;
 
1255
  records=0;
 
1256
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1337
1257
    records=1;
1338
 
 
1339
 
  records++;
 
1258
  if (prgflag & (READ_ALL+EXTRA_RECORD))
 
1259
    records++;
1340
1260
 
1341
1261
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1342
1262
                                   share->rec_buff_length * records)))
1343
 
    goto err;
 
1263
    goto err;                                   /* purecov: inspected */
1344
1264
 
1345
1265
  if (records == 0)
1346
1266
  {
1372
1292
#endif
1373
1293
 
1374
1294
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
1375
 
                                          (uint32_t) ((share->fields+1)*
 
1295
                                          (uint) ((share->fields+1)*
1376
1296
                                                  sizeof(Field*)))))
1377
 
    goto err;
 
1297
    goto err;                                   /* purecov: inspected */
1378
1298
 
1379
1299
  outparam->field= field_ptr;
1380
1300
 
1381
1301
  record= (unsigned char*) outparam->record[0]-1;       /* Fieldstart = 1 */
1382
 
 
1383
 
  outparam->null_flags= (unsigned char*) record+1;
 
1302
  if (share->null_field_first)
 
1303
    outparam->null_flags= (unsigned char*) record+1;
 
1304
  else
 
1305
    outparam->null_flags= (unsigned char*) (record+ 1+ share->reclength -
 
1306
                                    share->null_bytes);
1384
1307
 
1385
1308
  /* Setup copy of fields from share, but use the right alias and record */
1386
 
  for (i= 0 ; i < share->fields; i++, field_ptr++)
 
1309
  for (i=0 ; i < share->fields; i++, field_ptr++)
1387
1310
  {
1388
1311
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1389
1312
      goto err;
1392
1315
 
1393
1316
  if (share->found_next_number_field)
1394
1317
    outparam->found_next_number_field=
1395
 
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
 
1318
      outparam->field[(uint) (share->found_next_number_field - share->field)];
1396
1319
  if (share->timestamp_field)
1397
1320
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1398
1321
 
1408
1331
      goto err;
1409
1332
    outparam->key_info= key_info;
1410
1333
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
1411
 
 
 
1334
    
1412
1335
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1413
1336
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1414
1337
                                                   share->key_parts));
1448
1371
  bitmap_size= share->column_bitmap_size;
1449
1372
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1450
1373
    goto err;
1451
 
  outparam->def_read_set.init((my_bitmap_map*) bitmaps, share->fields);
1452
 
  outparam->def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
1453
 
  outparam->tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
 
1374
  bitmap_init(&outparam->def_read_set,
 
1375
              (my_bitmap_map*) bitmaps, share->fields, false);
 
1376
  bitmap_init(&outparam->def_write_set,
 
1377
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, false);
 
1378
  bitmap_init(&outparam->tmp_set,
 
1379
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, false);
1454
1380
  outparam->default_column_bitmaps();
1455
1381
 
1456
1382
  /* The table struct is now initialized;  Open the table */
1457
1383
  error= 2;
1458
 
  if (db_stat)
 
1384
  if (db_stat && open_mode != OTM_ALTER)
1459
1385
  {
1460
1386
    int ha_err;
1461
 
    if ((ha_err= (outparam->cursor->
 
1387
    if ((ha_err= (outparam->file->
1462
1388
                  ha_open(outparam, share->normalized_path.str,
1463
1389
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1464
1390
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
1467
1393
                          HA_OPEN_ABORT_IF_LOCKED :
1468
1394
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1469
1395
    {
 
1396
      /* Set a flag if the table is crashed and it can be auto. repaired */
 
1397
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
 
1398
                       outparam->file->auto_repair() &&
 
1399
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
 
1400
 
1470
1401
      switch (ha_err)
1471
1402
      {
1472
1403
        case HA_ERR_NO_SUCH_TABLE:
1473
1404
          /*
1474
1405
            The table did not exists in storage engine, use same error message
1475
 
            as if the .frm cursor didn't exist
 
1406
            as if the .frm file didn't exist
1476
1407
          */
1477
1408
          error= 1;
1478
 
          errno= ENOENT;
 
1409
          my_errno= ENOENT;
1479
1410
          break;
1480
1411
        case EMFILE:
1481
1412
          /*
1482
1413
            Too many files opened, use same error message as if the .frm
1483
 
            cursor can't open
 
1414
            file can't open
1484
1415
           */
1485
1416
          error= 1;
1486
 
          errno= EMFILE;
 
1417
          my_errno= EMFILE;
1487
1418
          break;
1488
1419
        default:
1489
 
          outparam->print_error(ha_err, MYF(0));
 
1420
          outparam->file->print_error(ha_err, MYF(0));
1490
1421
          error_reported= true;
1491
1422
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1492
1423
            error= 7;
1493
1424
          break;
1494
1425
      }
1495
 
      goto err;
 
1426
      goto err;                                 /* purecov: inspected */
1496
1427
    }
1497
1428
  }
1498
1429
 
1499
 
#if defined(HAVE_purify)
 
1430
#if defined(HAVE_purify) 
1500
1431
  memset(bitmaps, 0, bitmap_size*3);
1501
1432
#endif
1502
1433
 
1503
 
  return 0;
 
1434
  outparam->no_replicate= outparam->file;
 
1435
  thd->status_var.opened_tables++;
 
1436
 
 
1437
  return (0);
1504
1438
 
1505
1439
 err:
1506
 
  if (!error_reported)
1507
 
    share->open_table_error(error, errno, 0);
1508
 
  delete outparam->cursor;
1509
 
  outparam->cursor= 0;                          // For easier error checking
1510
 
  outparam->db_stat= 0;
 
1440
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
 
1441
    open_table_error(share, error, my_errno, 0);
 
1442
  delete outparam->file;
 
1443
  outparam->file= 0;                            // For easier error checking
 
1444
  outparam->db_stat=0;
1511
1445
  free_root(&outparam->mem_root, MYF(0));       // Safe to call on zeroed root
1512
1446
  free((char*) outparam->alias);
1513
1447
  return (error);
1514
1448
}
1515
1449
 
1516
 
bool Table::fill_item_list(List<Item> *item_list) const
1517
 
{
1518
 
  /*
1519
 
    All Item_field's created using a direct pointer to a field
1520
 
    are fixed in Item_field constructor.
1521
 
  */
1522
 
  for (Field **ptr= field; *ptr; ptr++)
1523
 
  {
1524
 
    Item_field *item= new Item_field(*ptr);
1525
 
    if (!item || item_list->push_back(item))
1526
 
      return true;
1527
 
  }
1528
 
  return false;
1529
 
}
1530
 
 
1531
 
int Table::closefrm(bool free_share)
1532
 
{
1533
 
  int error= 0;
1534
 
 
1535
 
  if (db_stat)
1536
 
    error= cursor->close();
1537
 
  free((char*) alias);
1538
 
  alias= NULL;
1539
 
  if (field)
1540
 
  {
1541
 
    for (Field **ptr=field ; *ptr ; ptr++)
 
1450
 
 
1451
/*
 
1452
  Free information allocated by openfrm
 
1453
 
 
1454
  SYNOPSIS
 
1455
    closefrm()
 
1456
    table               Table object to free
 
1457
    free_share          Is 1 if we also want to free table_share
 
1458
*/
 
1459
 
 
1460
int closefrm(register Table *table, bool free_share)
 
1461
{
 
1462
  int error=0;
 
1463
 
 
1464
  if (table->db_stat)
 
1465
    error=table->file->close();
 
1466
  free((char*) table->alias);
 
1467
  table->alias= 0;
 
1468
  if (table->field)
 
1469
  {
 
1470
    for (Field **ptr=table->field ; *ptr ; ptr++)
1542
1471
      delete *ptr;
1543
 
    field= 0;
 
1472
    table->field= 0;
1544
1473
  }
1545
 
  delete cursor;
1546
 
  cursor= 0;                            /* For easier errorchecking */
 
1474
  delete table->file;
 
1475
  table->file= 0;                               /* For easier errorchecking */
1547
1476
  if (free_share)
1548
1477
  {
1549
 
    if (s->tmp_table == message::Table::STANDARD)
1550
 
      TableShare::release(s);
 
1478
    if (table->s->tmp_table == NO_TMP_TABLE)
 
1479
      release_table_share(table->s, RELEASE_NORMAL);
1551
1480
    else
1552
 
      s->free_table_share();
 
1481
      free_table_share(table->s);
1553
1482
  }
1554
 
  free_root(&mem_root, MYF(0));
1555
 
 
1556
 
  return error;
1557
 
}
1558
 
 
1559
 
 
1560
 
void Table::resetTable(Session *session,
1561
 
                       TableShare *share,
1562
 
                       uint32_t db_stat_arg)
1563
 
{
1564
 
  s= share;
1565
 
  field= NULL;
1566
 
 
1567
 
  cursor= NULL;
1568
 
  next= NULL;
1569
 
  prev= NULL;
1570
 
 
1571
 
  read_set= NULL;
1572
 
  write_set= NULL;
1573
 
 
1574
 
  tablenr= 0;
1575
 
  db_stat= db_stat_arg;
1576
 
 
1577
 
  in_use= session;
1578
 
  record[0]= (unsigned char *) NULL;
1579
 
  record[1]= (unsigned char *) NULL;
1580
 
 
1581
 
  insert_values= NULL;
1582
 
  key_info= NULL;
1583
 
  next_number_field= NULL;
1584
 
  found_next_number_field= NULL;
1585
 
  timestamp_field= NULL;
1586
 
 
1587
 
  pos_in_table_list= NULL;
1588
 
  group= NULL;
1589
 
  alias= NULL;
1590
 
  null_flags= NULL;
1591
 
 
1592
 
  lock_position= 0;
1593
 
  lock_data_start= 0;
1594
 
  lock_count= 0;
1595
 
  used_fields= 0;
1596
 
  status= 0;
1597
 
  derived_select_number= 0;
1598
 
  current_lock= F_UNLCK;
1599
 
  copy_blobs= false;
1600
 
 
1601
 
  maybe_null= false;
1602
 
 
1603
 
  null_row= false;
1604
 
 
1605
 
  force_index= false;
1606
 
  distinct= false;
1607
 
  const_table= false;
1608
 
  no_rows= false;
1609
 
  key_read= false;
1610
 
  no_keyread= false;
1611
 
 
1612
 
  open_placeholder= false;
1613
 
  locked_by_name= false;
1614
 
  no_cache= false;
1615
 
 
1616
 
  auto_increment_field_not_null= false;
1617
 
  alias_name_used= false;
1618
 
 
1619
 
  query_id= 0;
1620
 
  quick_condition_rows= 0;
1621
 
 
1622
 
  timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1623
 
  map= 0;
1624
 
 
1625
 
  reginfo.reset();
1626
 
 
1627
 
  covering_keys.reset();
1628
 
 
1629
 
  quick_keys.reset();
1630
 
  merge_keys.reset();
1631
 
 
1632
 
  keys_in_use_for_query.reset();
1633
 
  keys_in_use_for_group_by.reset();
1634
 
  keys_in_use_for_order_by.reset();
1635
 
 
1636
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
1637
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
1638
 
 
1639
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
1640
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
1641
 
 
1642
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1643
 
  memset(&sort, 0, sizeof(filesort_info_st));
1644
 
}
1645
 
 
 
1483
  free_root(&table->mem_root, MYF(0));
 
1484
  return(error);
 
1485
}
1646
1486
 
1647
1487
 
1648
1488
/* Deallocate temporary blob storage */
1657
1497
}
1658
1498
 
1659
1499
 
1660
 
        /* error message when opening a form cursor */
1661
 
 
1662
 
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
 
1500
        /* Find where a form starts */
 
1501
        /* if formname is NULL then only formnames is read */
 
1502
 
 
1503
ulong get_form_pos(File file, unsigned char *head, TYPELIB *save_names)
 
1504
{
 
1505
  uint32_t a_length,names,length;
 
1506
  unsigned char *pos,*buf;
 
1507
  ulong ret_value=0;
 
1508
 
 
1509
  names=uint2korr(head+8);
 
1510
  a_length=(names+2)*sizeof(char *);            /* Room for two extra */
 
1511
 
 
1512
  if (!save_names)
 
1513
    a_length=0;
 
1514
  else
 
1515
    save_names->type_names=0;                   /* Clear if error */
 
1516
 
 
1517
  if (names)
 
1518
  {
 
1519
    length=uint2korr(head+4);
 
1520
    my_seek(file,64L,MY_SEEK_SET,MYF(0));
 
1521
    if (!(buf= (unsigned char*) my_malloc((size_t) length+a_length+names*4,
 
1522
                                  MYF(MY_WME))) ||
 
1523
        my_read(file, buf+a_length, (size_t) (length+names*4),
 
1524
                MYF(MY_NABP)))
 
1525
    {                                           /* purecov: inspected */
 
1526
      if (buf)
 
1527
        free(buf);
 
1528
      return(0L);                               /* purecov: inspected */
 
1529
    }
 
1530
    pos= buf+a_length+length;
 
1531
    ret_value=uint4korr(pos);
 
1532
  }
 
1533
  if (! save_names)
 
1534
  {
 
1535
    if (names)
 
1536
      free((unsigned char*) buf);
 
1537
  }
 
1538
  else if (!names)
 
1539
    memset(save_names, 0, sizeof(save_names));
 
1540
  else
 
1541
  {
 
1542
    char *str;
 
1543
    str=(char *) (buf+a_length);
 
1544
    fix_type_pointers((const char ***) &buf,save_names,1,&str);
 
1545
  }
 
1546
  return(ret_value);
 
1547
}
 
1548
 
 
1549
 
 
1550
/*
 
1551
  Read string from a file with malloc
 
1552
 
 
1553
  NOTES:
 
1554
    We add an \0 at end of the read string to make reading of C strings easier
 
1555
*/
 
1556
 
 
1557
int read_string(File file, unsigned char**to, size_t length)
 
1558
{
 
1559
 
 
1560
  if (*to)
 
1561
    free(*to);
 
1562
  if (!(*to= (unsigned char*) my_malloc(length+1,MYF(MY_WME))) ||
 
1563
      my_read(file, *to, length,MYF(MY_NABP)))
 
1564
  {
 
1565
    if (*to)
 
1566
      free(*to);
 
1567
    *to= NULL;
 
1568
    return(1);                           /* purecov: inspected */
 
1569
  }
 
1570
  *((char*) *to+length)= '\0';
 
1571
  return (0);
 
1572
} /* read_string */
 
1573
 
 
1574
 
 
1575
        /* Add a new form to a form file */
 
1576
 
 
1577
ulong make_new_entry(File file, unsigned char *fileinfo, TYPELIB *formnames,
 
1578
                     const char *newname)
 
1579
{
 
1580
  uint32_t i,bufflength,maxlength,n_length,length,names;
 
1581
  ulong endpos,newpos;
 
1582
  unsigned char buff[IO_SIZE];
 
1583
  unsigned char *pos;
 
1584
 
 
1585
  length=(uint) strlen(newname)+1;
 
1586
  n_length=uint2korr(fileinfo+4);
 
1587
  maxlength=uint2korr(fileinfo+6);
 
1588
  names=uint2korr(fileinfo+8);
 
1589
  newpos=uint4korr(fileinfo+10);
 
1590
 
 
1591
  if (64+length+n_length+(names+1)*4 > maxlength)
 
1592
  {                                             /* Expand file */
 
1593
    newpos+=IO_SIZE;
 
1594
    int4store(fileinfo+10,newpos);
 
1595
    endpos=(ulong) my_seek(file,0L,MY_SEEK_END,MYF(0));/* Copy from file-end */
 
1596
    bufflength= (uint) (endpos & (IO_SIZE-1));  /* IO_SIZE is a power of 2 */
 
1597
 
 
1598
    while (endpos > maxlength)
 
1599
    {
 
1600
      my_seek(file,(ulong) (endpos-bufflength),MY_SEEK_SET,MYF(0));
 
1601
      if (my_read(file, buff, bufflength, MYF(MY_NABP+MY_WME)))
 
1602
        return(0L);
 
1603
      my_seek(file,(ulong) (endpos-bufflength+IO_SIZE),MY_SEEK_SET,
 
1604
                   MYF(0));
 
1605
      if ((my_write(file, buff,bufflength,MYF(MY_NABP+MY_WME))))
 
1606
        return(0);
 
1607
      endpos-=bufflength; bufflength=IO_SIZE;
 
1608
    }
 
1609
    memset(buff, 0, IO_SIZE);                   /* Null new block */
 
1610
    my_seek(file,(ulong) maxlength,MY_SEEK_SET,MYF(0));
 
1611
    if (my_write(file,buff,bufflength,MYF(MY_NABP+MY_WME)))
 
1612
        return(0L);
 
1613
    maxlength+=IO_SIZE;                         /* Fix old ref */
 
1614
    int2store(fileinfo+6,maxlength);
 
1615
    for (i=names, pos= (unsigned char*) *formnames->type_names+n_length-1; i-- ;
 
1616
         pos+=4)
 
1617
    {
 
1618
      endpos=uint4korr(pos)+IO_SIZE;
 
1619
      int4store(pos,endpos);
 
1620
    }
 
1621
  }
 
1622
 
 
1623
  if (n_length == 1 )
 
1624
  {                                             /* First name */
 
1625
    length++;
 
1626
    strxmov((char*) buff,"/",newname,"/",NULL);
 
1627
  }
 
1628
  else
 
1629
    strxmov((char*) buff,newname,"/",NULL); /* purecov: inspected */
 
1630
  my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0));
 
1631
  if (my_write(file, buff, (size_t) length+1,MYF(MY_NABP+MY_WME)) ||
 
1632
      (names && my_write(file,(unsigned char*) (*formnames->type_names+n_length-1),
 
1633
                         names*4, MYF(MY_NABP+MY_WME))) ||
 
1634
      my_write(file, fileinfo+10, 4,MYF(MY_NABP+MY_WME)))
 
1635
    return(0L); /* purecov: inspected */
 
1636
 
 
1637
  int2store(fileinfo+8,names+1);
 
1638
  int2store(fileinfo+4,n_length+length);
 
1639
  (void)ftruncate(file, newpos);/* Append file with '\0' */
 
1640
  return(newpos);
 
1641
} /* make_new_entry */
 
1642
 
 
1643
 
 
1644
        /* error message when opening a form file */
 
1645
 
 
1646
void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
1663
1647
{
1664
1648
  int err_no;
1665
1649
  char buff[FN_REFLEN];
1666
1650
  myf errortype= ME_ERROR+ME_WAITTANG;
1667
1651
 
1668
 
  switch (pass_error) {
 
1652
  switch (error) {
1669
1653
  case 7:
1670
1654
  case 1:
1671
1655
    if (db_errno == ENOENT)
1672
 
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
 
1656
      my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
1673
1657
    else
1674
1658
    {
1675
 
      snprintf(buff, sizeof(buff), "%s",normalized_path.str);
 
1659
      strxmov(buff, share->normalized_path.str, reg_ext, NULL);
1676
1660
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1677
1661
               errortype, buff, db_errno);
1678
1662
    }
1679
1663
    break;
1680
1664
  case 2:
1681
1665
  {
1682
 
    Cursor *cursor= 0;
 
1666
    handler *file= 0;
1683
1667
    const char *datext= "";
1684
 
 
1685
 
    if (db_type() != NULL)
 
1668
    
 
1669
    if (share->db_type() != NULL)
1686
1670
    {
1687
 
      if ((cursor= db_type()->getCursor(*this, current_session->mem_root)))
 
1671
      if ((file= get_new_handler(share, current_thd->mem_root,
 
1672
                                 share->db_type())))
1688
1673
      {
1689
 
        if (!(datext= *db_type()->bas_ext()))
 
1674
        if (!(datext= *file->bas_ext()))
1690
1675
          datext= "";
1691
1676
      }
1692
1677
    }
1693
1678
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1694
1679
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1695
 
    snprintf(buff, sizeof(buff), "%s%s", normalized_path.str,datext);
 
1680
    strxmov(buff, share->normalized_path.str, datext, NULL);
1696
1681
    my_error(err_no,errortype, buff, db_errno);
1697
 
    delete cursor;
 
1682
    delete file;
1698
1683
    break;
1699
1684
  }
1700
1685
  case 5:
1701
1686
  {
1702
 
    const char *csname= get_charset_name((uint32_t) pass_errarg);
 
1687
    const char *csname= get_charset_name((uint) errarg);
1703
1688
    char tmp[10];
1704
1689
    if (!csname || csname[0] =='?')
1705
1690
    {
1706
 
      snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
 
1691
      snprintf(tmp, sizeof(tmp), "#%d", errarg);
1707
1692
      csname= tmp;
1708
1693
    }
1709
1694
    my_printf_error(ER_UNKNOWN_COLLATION,
1710
 
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1711
 
                    MYF(0), csname, table_name.str);
 
1695
                    _("Unknown collation '%s' in table '%-.64s' definition"), 
 
1696
                    MYF(0), csname, share->table_name.str);
1712
1697
    break;
1713
1698
  }
1714
1699
  case 6:
1715
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
 
1700
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
1716
1701
    my_printf_error(ER_NOT_FORM_FILE,
1717
1702
                    _("Table '%-.64s' was created with a different version "
1718
 
                    "of Drizzle and cannot be read"),
 
1703
                    "of MySQL and cannot be read"), 
1719
1704
                    MYF(0), buff);
1720
1705
    break;
1721
1706
  case 8:
1722
1707
    break;
1723
1708
  default:                              /* Better wrong error than none */
1724
1709
  case 4:
1725
 
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
 
1710
    strxmov(buff, share->normalized_path.str, reg_ext, NULL);
1726
1711
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1727
1712
    break;
1728
1713
  }
1730
1715
} /* open_table_error */
1731
1716
 
1732
1717
 
1733
 
TYPELIB *typelib(memory::Root *mem_root, List<String> &strings)
 
1718
        /*
 
1719
        ** fix a str_type to a array type
 
1720
        ** typeparts separated with some char. differents types are separated
 
1721
        ** with a '\0'
 
1722
        */
 
1723
 
 
1724
static void
 
1725
fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint32_t types,
 
1726
                  char **names)
 
1727
{
 
1728
  char *type_name, *ptr;
 
1729
  char chr;
 
1730
 
 
1731
  ptr= *names;
 
1732
  while (types--)
 
1733
  {
 
1734
    point_to_type->name=0;
 
1735
    point_to_type->type_names= *array;
 
1736
 
 
1737
    if ((chr= *ptr))                    /* Test if empty type */
 
1738
    {
 
1739
      while ((type_name=strchr(ptr+1,chr)) != NULL)
 
1740
      {
 
1741
        *((*array)++) = ptr+1;
 
1742
        *type_name= '\0';               /* End string */
 
1743
        ptr=type_name;
 
1744
      }
 
1745
      ptr+=2;                           /* Skip end mark and last 0 */
 
1746
    }
 
1747
    else
 
1748
      ptr++;
 
1749
    point_to_type->count= (uint) (*array - point_to_type->type_names);
 
1750
    point_to_type++;
 
1751
    *((*array)++)= NULL;                /* End of type */
 
1752
  }
 
1753
  *names=ptr;                           /* Update end */
 
1754
  return;
 
1755
} /* fix_type_pointers */
 
1756
 
 
1757
 
 
1758
TYPELIB *typelib(MEM_ROOT *mem_root, List<String> &strings)
1734
1759
{
1735
1760
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
1736
1761
  if (!result)
1737
1762
    return 0;
1738
 
  result->count= strings.elements;
1739
 
  result->name= "";
1740
 
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
1741
 
  
 
1763
  result->count=strings.elements;
 
1764
  result->name="";
 
1765
  uint32_t nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1);
1742
1766
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1743
1767
    return 0;
1744
 
    
1745
1768
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1746
 
 
1747
1769
  List_iterator<String> it(strings);
1748
1770
  String *tmp;
1749
 
  for (uint32_t i= 0; (tmp= it++); i++)
 
1771
  for (uint32_t i=0; (tmp=it++) ; i++)
1750
1772
  {
1751
1773
    result->type_names[i]= tmp->ptr();
1752
1774
    result->type_lengths[i]= tmp->length();
1753
1775
  }
1754
 
 
1755
 
  result->type_names[result->count]= 0;   // End marker
 
1776
  result->type_names[result->count]= 0;         // End marker
1756
1777
  result->type_lengths[result->count]= 0;
1757
 
 
1758
1778
  return result;
1759
1779
}
1760
1780
 
 
1781
 
 
1782
/*
 
1783
 Search after a field with given start & length
 
1784
 If an exact field isn't found, return longest field with starts
 
1785
 at right position.
 
1786
 
 
1787
 NOTES
 
1788
   This is needed because in some .frm fields 'fieldnr' was saved wrong
 
1789
 
 
1790
 RETURN
 
1791
   0  error
 
1792
   #  field number +1
 
1793
*/
 
1794
 
 
1795
static uint32_t find_field(Field **fields, unsigned char *record, uint32_t start, uint32_t length)
 
1796
{
 
1797
  Field **field;
 
1798
  uint32_t i, pos;
 
1799
 
 
1800
  pos= 0;
 
1801
  for (field= fields, i=1 ; *field ; i++,field++)
 
1802
  {
 
1803
    if ((*field)->offset(record) == start)
 
1804
    {
 
1805
      if ((*field)->key_length() == length)
 
1806
        return (i);
 
1807
      if (!pos || fields[pos-1]->pack_length() <
 
1808
          (*field)->pack_length())
 
1809
        pos= i;
 
1810
    }
 
1811
  }
 
1812
  return (pos);
 
1813
}
 
1814
 
 
1815
 
1761
1816
        /* Check that the integer is in the internal */
1762
1817
 
1763
1818
int set_zone(register int nr, int min_zone, int max_zone)
1783
1838
/*
1784
1839
  Store an SQL quoted string.
1785
1840
 
1786
 
  SYNOPSIS
 
1841
  SYNOPSIS  
1787
1842
    append_unescaped()
1788
1843
    res         result String
1789
1844
    pos         string to be quoted
1801
1856
 
1802
1857
  for (; pos != end ; pos++)
1803
1858
  {
 
1859
#if defined(USE_MB)
1804
1860
    uint32_t mblen;
1805
1861
    if (use_mb(default_charset_info) &&
1806
1862
        (mblen= my_ismbchar(default_charset_info, pos, end)))
1807
1863
    {
1808
1864
      res->append(pos, mblen);
1809
1865
      pos+= mblen;
1810
 
      if (pos >= end)
1811
 
        break;
1812
1866
      continue;
1813
1867
    }
 
1868
#endif
1814
1869
 
1815
1870
    switch (*pos) {
1816
1871
    case 0:                             /* Must be escaped for 'mysql' */
1842
1897
}
1843
1898
 
1844
1899
 
 
1900
        /* Create a .frm file */
 
1901
 
 
1902
File create_frm(THD *thd, const char *name, const char *db,
 
1903
                const char *table, uint32_t reclength, unsigned char *fileinfo,
 
1904
                HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
 
1905
{
 
1906
  register File file;
 
1907
  ulong length;
 
1908
  unsigned char fill[IO_SIZE];
 
1909
  int create_flags= O_RDWR | O_TRUNC;
 
1910
  ulong key_comment_total_bytes= 0;
 
1911
  uint32_t i;
 
1912
 
 
1913
  if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
 
1914
    create_flags|= O_EXCL | O_NOFOLLOW;
 
1915
 
 
1916
  /* Fix this when we have new .frm files;  Current limit is 4G rows (QQ) */
 
1917
  if (create_info->max_rows > UINT32_MAX)
 
1918
    create_info->max_rows= UINT32_MAX;
 
1919
  if (create_info->min_rows > UINT32_MAX)
 
1920
    create_info->min_rows= UINT32_MAX;
 
1921
 
 
1922
  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
 
1923
  {
 
1924
    uint32_t key_length, tmp_key_length;
 
1925
    uint32_t tmp;
 
1926
    memset(fileinfo, 0, 64);
 
1927
    /* header */
 
1928
    fileinfo[0]=(unsigned char) 254;
 
1929
    fileinfo[1]= 1;
 
1930
    fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
 
1931
 
 
1932
    fileinfo[3]= (unsigned char) ha_legacy_type(
 
1933
          ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
 
1934
    fileinfo[4]=1;
 
1935
    int2store(fileinfo+6,IO_SIZE);              /* Next block starts here */
 
1936
    for (i= 0; i < keys; i++)
 
1937
    {
 
1938
      assert(test(key_info[i].flags & HA_USES_COMMENT) == 
 
1939
                 (key_info[i].comment.length > 0));
 
1940
      if (key_info[i].flags & HA_USES_COMMENT)
 
1941
        key_comment_total_bytes += 2 + key_info[i].comment.length;
 
1942
    }
 
1943
    /*
 
1944
      Keep in sync with pack_keys() in unireg.cc
 
1945
      For each key:
 
1946
      8 bytes for the key header
 
1947
      9 bytes for each key-part (MAX_REF_PARTS)
 
1948
      NAME_LEN bytes for the name
 
1949
      1 byte for the NAMES_SEP_CHAR (before the name)
 
1950
      For all keys:
 
1951
      6 bytes for the header
 
1952
      1 byte for the NAMES_SEP_CHAR (after the last name)
 
1953
      9 extra bytes (padding for safety? alignment?)
 
1954
      comments
 
1955
    */
 
1956
    key_length= (keys * (8 + MAX_REF_PARTS * 9 + NAME_LEN + 1) + 16 +
 
1957
                 key_comment_total_bytes);
 
1958
    length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
 
1959
                                  create_info->extra_size));
 
1960
    int4store(fileinfo+10,length);
 
1961
    tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
 
1962
    int2store(fileinfo+14,tmp_key_length);
 
1963
    int2store(fileinfo+16,reclength);
 
1964
    int4store(fileinfo+18,create_info->max_rows);
 
1965
    int4store(fileinfo+22,create_info->min_rows);
 
1966
    /* fileinfo[26] is set in mysql_create_frm() */
 
1967
    fileinfo[27]=2;                             // Use long pack-fields
 
1968
    /* fileinfo[28 & 29] is set to key_info_length in mysql_create_frm() */
 
1969
    create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
 
1970
    int2store(fileinfo+30,create_info->table_options);
 
1971
    fileinfo[32]=0;                             // No filename anymore
 
1972
    fileinfo[33]=5;                             // Mark for 5.0 frm file
 
1973
    int4store(fileinfo+34,create_info->avg_row_length);
 
1974
    fileinfo[38]= (create_info->default_table_charset ?
 
1975
                   create_info->default_table_charset->number : 0);
 
1976
    fileinfo[39]= (unsigned char) create_info->page_checksum;
 
1977
    fileinfo[40]= (unsigned char) create_info->row_type;
 
1978
    /* Next few bytes where for RAID support */
 
1979
    fileinfo[41]= 0;
 
1980
    fileinfo[42]= 0;
 
1981
    int4store(fileinfo+43,create_info->block_size);
 
1982
 
 
1983
    fileinfo[44]= 0;
 
1984
    fileinfo[45]= 0;
 
1985
    fileinfo[46]= 0;
 
1986
    int4store(fileinfo+47, key_length);
 
1987
    tmp= DRIZZLE_VERSION_ID;          // Store to avoid warning from int4store
 
1988
    int4store(fileinfo+51, tmp);
 
1989
    int4store(fileinfo+55, create_info->extra_size);
 
1990
    /*
 
1991
      59-60 is reserved for extra_rec_buf_length,
 
1992
      61 for default_part_db_type
 
1993
    */
 
1994
    int2store(fileinfo+62, create_info->key_block_size);
 
1995
    memset(fill, 0, IO_SIZE);
 
1996
    for (; length > IO_SIZE ; length-= IO_SIZE)
 
1997
    {
 
1998
      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
 
1999
      {
 
2000
        my_close(file,MYF(0));
 
2001
        my_delete(name,MYF(0));
 
2002
        return(-1);
 
2003
      }
 
2004
    }
 
2005
  }
 
2006
  else
 
2007
  {
 
2008
    if (my_errno == ENOENT)
 
2009
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
2010
    else
 
2011
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table,my_errno);
 
2012
  }
 
2013
  return (file);
 
2014
} /* create_frm */
 
2015
 
1845
2016
/*
1846
2017
  Set up column usage bitmaps for a temporary table
1847
2018
 
1854
2025
{
1855
2026
  uint32_t field_count= s->fields;
1856
2027
 
1857
 
  this->def_read_set.init((my_bitmap_map*) bitmaps, field_count);
1858
 
  this->tmp_set.init((my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
 
2028
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count, false);
 
2029
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count, false);
1859
2030
 
1860
2031
  /* write_set and all_set are copies of read_set */
1861
2032
  def_write_set= def_read_set;
1862
2033
  s->all_set= def_read_set;
1863
 
  this->s->all_set.setAll();
 
2034
  bitmap_set_all(&this->s->all_set);
1864
2035
  default_column_bitmaps();
1865
2036
}
1866
2037
 
1867
2038
 
1868
2039
 
1869
 
void Table::updateCreateInfo(message::Table *table_proto)
1870
 
{
1871
 
  message::Table::TableOptions *table_options= table_proto->mutable_options();
1872
 
  table_options->set_block_size(s->block_size);
1873
 
  table_options->set_comment(s->getComment());
1874
 
}
1875
 
 
1876
 
int rename_file_ext(const char * from,const char * to,const char * ext)
1877
 
{
1878
 
  string from_s, to_s;
1879
 
 
1880
 
  from_s.append(from);
1881
 
  from_s.append(ext);
1882
 
  to_s.append(to);
1883
 
  to_s.append(ext);
1884
 
  return (internal::my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
 
2040
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
 
2041
{
 
2042
  create_info->max_rows= s->max_rows;
 
2043
  create_info->min_rows= s->min_rows;
 
2044
  create_info->table_options= s->db_create_options;
 
2045
  create_info->avg_row_length= s->avg_row_length;
 
2046
  create_info->block_size= s->block_size;
 
2047
  create_info->row_type= s->row_type;
 
2048
  create_info->default_table_charset= s->table_charset;
 
2049
  create_info->table_charset= 0;
 
2050
  create_info->comment= s->comment;
 
2051
 
 
2052
  return;
 
2053
}
 
2054
 
 
2055
int
 
2056
rename_file_ext(const char * from,const char * to,const char * ext)
 
2057
{
 
2058
  char from_b[FN_REFLEN],to_b[FN_REFLEN];
 
2059
  strxmov(from_b,from,ext,NULL);
 
2060
  strxmov(to_b,to,ext,NULL);
 
2061
  return (my_rename(from_b,to_b,MYF(MY_WME)));
 
2062
}
 
2063
 
 
2064
 
 
2065
/*
 
2066
  Allocate string field in MEM_ROOT and return it as String
 
2067
 
 
2068
  SYNOPSIS
 
2069
    get_field()
 
2070
    mem         MEM_ROOT for allocating
 
2071
    field       Field for retrieving of string
 
2072
    res         result String
 
2073
 
 
2074
  RETURN VALUES
 
2075
    1   string is empty
 
2076
    0   all ok
 
2077
*/
 
2078
 
 
2079
bool get_field(MEM_ROOT *mem, Field *field, String *res)
 
2080
{
 
2081
  char buff[MAX_FIELD_WIDTH], *to;
 
2082
  String str(buff,sizeof(buff),&my_charset_bin);
 
2083
  uint32_t length;
 
2084
 
 
2085
  field->val_str(&str);
 
2086
  if (!(length= str.length()))
 
2087
  {
 
2088
    res->length(0);
 
2089
    return 1;
 
2090
  }
 
2091
  if (!(to= strmake_root(mem, str.ptr(), length)))
 
2092
    length= 0;                                  // Safety fix
 
2093
  res->set(to, length, ((Field_str*)field)->charset());
 
2094
  return 0;
 
2095
}
 
2096
 
 
2097
 
 
2098
/*
 
2099
  Allocate string field in MEM_ROOT and return it as NULL-terminated string
 
2100
 
 
2101
  SYNOPSIS
 
2102
    get_field()
 
2103
    mem         MEM_ROOT for allocating
 
2104
    field       Field for retrieving of string
 
2105
 
 
2106
  RETURN VALUES
 
2107
    NULL  string is empty
 
2108
    #      pointer to NULL-terminated string value of field
 
2109
*/
 
2110
 
 
2111
char *get_field(MEM_ROOT *mem, Field *field)
 
2112
{
 
2113
  char buff[MAX_FIELD_WIDTH], *to;
 
2114
  String str(buff,sizeof(buff),&my_charset_bin);
 
2115
  uint32_t length;
 
2116
 
 
2117
  field->val_str(&str);
 
2118
  length= str.length();
 
2119
  if (!length || !(to= (char*) alloc_root(mem,length+1)))
 
2120
    return NULL;
 
2121
  memcpy(to,str.ptr(),(uint) length);
 
2122
  to[length]=0;
 
2123
  return to;
1885
2124
}
1886
2125
 
1887
2126
/*
1890
2129
    that are present in this value, returns the length of the value
1891
2130
*/
1892
2131
uint32_t calculate_key_len(Table *table, uint32_t key,
1893
 
                       const unsigned char *,
 
2132
                       const unsigned char *buf __attribute__((unused)),
1894
2133
                       key_part_map keypart_map)
1895
2134
{
1896
2135
  /* works only with key prefixes */
1917
2156
    check_db_name()
1918
2157
    org_name            Name of database and length
1919
2158
 
 
2159
  NOTES
 
2160
    If lower_case_table_names is set then database is converted to lower case
 
2161
 
1920
2162
  RETURN
1921
 
    false error
1922
 
    true ok
 
2163
    0   ok
 
2164
    1   error
1923
2165
*/
1924
2166
 
1925
 
bool check_db_name(SchemaIdentifier &schema_identifier)
 
2167
bool check_db_name(LEX_STRING *org_name)
1926
2168
{
1927
 
  if (not plugin::Authorization::isAuthorized(current_session->getSecurityContext(), schema_identifier))
1928
 
  {
1929
 
    return false;
1930
 
  }
1931
 
 
1932
 
  return schema_identifier.isValid();
 
2169
  char *name= org_name->str;
 
2170
  uint32_t name_length= org_name->length;
 
2171
 
 
2172
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
 
2173
    return 1;
 
2174
 
 
2175
  if (lower_case_table_names && name != any_db)
 
2176
    my_casedn_str(files_charset_info, name);
 
2177
 
 
2178
  return check_identifier_name(org_name);
1933
2179
}
1934
2180
 
 
2181
 
1935
2182
/*
1936
2183
  Allow anything as a table name, as long as it doesn't contain an
1937
2184
  ' ' at the end
1938
2185
  returns 1 on error
1939
2186
*/
 
2187
 
 
2188
 
1940
2189
bool check_table_name(const char *name, uint32_t length)
1941
2190
{
1942
2191
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
1957
2206
{
1958
2207
  uint32_t name_length= 0;  // name length in symbols
1959
2208
  bool last_char_is_space= true;
1960
 
 
 
2209
  
1961
2210
  while (*name)
1962
2211
  {
 
2212
#if defined(USE_MB) && defined(USE_MB_IDENT)
1963
2213
    last_char_is_space= my_isspace(system_charset_info, *name);
1964
2214
    if (use_mb(system_charset_info))
1965
2215
    {
1966
 
      int len=my_ismbchar(system_charset_info, name,
 
2216
      int len=my_ismbchar(system_charset_info, name, 
1967
2217
                          name+system_charset_info->mbmaxlen);
1968
2218
      if (len)
1969
2219
      {
1974
2224
        continue;
1975
2225
      }
1976
2226
    }
 
2227
#else
 
2228
    last_char_is_space= *name==' ';
 
2229
#endif
1977
2230
    /*
1978
2231
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
1979
2232
      It is defined as 0xFF, which is a not valid byte in utf8.
1985
2238
    name_length++;
1986
2239
  }
1987
2240
  /* Error if empty or too long column name */
1988
 
  return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
 
2241
  return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
 
2242
}
 
2243
 
 
2244
 
 
2245
/**
 
2246
  Checks whether a table is intact. Should be done *just* after the table has
 
2247
  been opened.
 
2248
 
 
2249
  @param[in] table             The table to check
 
2250
  @param[in] table_f_count     Expected number of columns in the table
 
2251
  @param[in] table_def         Expected structure of the table (column name
 
2252
                               and type)
 
2253
 
 
2254
  @retval  false  OK
 
2255
  @retval  TRUE   There was an error. An error message is output
 
2256
                  to the error log.  We do not push an error
 
2257
                  message into the error stack because this
 
2258
                  function is currently only called at start up,
 
2259
                  and such errors never reach the user.
 
2260
*/
 
2261
 
 
2262
bool
 
2263
Table::table_check_intact(const uint32_t table_f_count,
 
2264
                          const TABLE_FIELD_W_TYPE *table_def)
 
2265
{
 
2266
  uint32_t i;
 
2267
  bool error= false;
 
2268
  bool fields_diff_count;
 
2269
 
 
2270
  fields_diff_count= (s->fields != table_f_count);
 
2271
  if (fields_diff_count)
 
2272
  {
 
2273
 
 
2274
    /* previous MySQL version */
 
2275
    if (DRIZZLE_VERSION_ID > s->mysql_version)
 
2276
    {
 
2277
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
 
2278
                      alias, table_f_count, s->fields,
 
2279
                      s->mysql_version, DRIZZLE_VERSION_ID);
 
2280
      return(true);
 
2281
    }
 
2282
    else if (DRIZZLE_VERSION_ID == s->mysql_version)
 
2283
    {
 
2284
      sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
 
2285
                      table_f_count, s->fields);
 
2286
      return(true);
 
2287
    }
 
2288
    /*
 
2289
      Something has definitely changed, but we're running an older
 
2290
      version of MySQL with new system tables.
 
2291
      Let's check column definitions. If a column was added at
 
2292
      the end of the table, then we don't care much since such change
 
2293
      is backward compatible.
 
2294
    */
 
2295
  }
 
2296
  char buffer[STRING_BUFFER_USUAL_SIZE];
 
2297
  for (i=0 ; i < table_f_count; i++, table_def++)
 
2298
  {
 
2299
    String sql_type(buffer, sizeof(buffer), system_charset_info);
 
2300
    sql_type.length(0);
 
2301
    if (i < s->fields)
 
2302
    {
 
2303
      Field *field= this->field[i];
 
2304
 
 
2305
      if (strncmp(field->field_name, table_def->name.str,
 
2306
                  table_def->name.length))
 
2307
      {
 
2308
        /*
 
2309
          Name changes are not fatal, we use ordinal numbers to access columns.
 
2310
          Still this can be a sign of a tampered table, output an error
 
2311
          to the error log.
 
2312
        */
 
2313
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2314
                        "expected column '%s' at position %d, found '%s'."),
 
2315
                        s->db.str, alias, table_def->name.str, i,
 
2316
                        field->field_name);
 
2317
      }
 
2318
      field->sql_type(sql_type);
 
2319
      /*
 
2320
        Generally, if column types don't match, then something is
 
2321
        wrong.
 
2322
 
 
2323
        However, we only compare column definitions up to the
 
2324
        length of the original definition, since we consider the
 
2325
        following definitions compatible:
 
2326
 
 
2327
        1. DATETIME and DATETIM
 
2328
        2. INT(11) and INT(11
 
2329
        3. SET('one', 'two') and SET('one', 'two', 'more')
 
2330
 
 
2331
        For SETs or ENUMs, if the same prefix is there it's OK to
 
2332
        add more elements - they will get higher ordinal numbers and
 
2333
        the new table definition is backward compatible with the
 
2334
        original one.
 
2335
       */
 
2336
      if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
 
2337
                  table_def->type.length - 1))
 
2338
      {
 
2339
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2340
                        "expected column '%s' at position %d to have type "
 
2341
                        "%s, found type %s."), s->db.str, alias,
 
2342
                        table_def->name.str, i, table_def->type.str,
 
2343
                        sql_type.c_ptr_safe());
 
2344
        error= true;
 
2345
      }
 
2346
      else if (table_def->cset.str && !field->has_charset())
 
2347
      {
 
2348
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2349
                        "expected the type of column '%s' at position %d "
 
2350
                        "to have character set '%s' but the type has no "
 
2351
                        "character set."), s->db.str, alias,
 
2352
                        table_def->name.str, i, table_def->cset.str);
 
2353
        error= true;
 
2354
      }
 
2355
      else if (table_def->cset.str &&
 
2356
               strcmp(field->charset()->csname, table_def->cset.str))
 
2357
      {
 
2358
        sql_print_error(_("Incorrect definition of table %s.%s: "
 
2359
                        "expected the type of column '%s' at position %d "
 
2360
                        "to have character set '%s' but found "
 
2361
                        "character set '%s'."), s->db.str, alias,
 
2362
                        table_def->name.str, i, table_def->cset.str,
 
2363
                        field->charset()->csname);
 
2364
        error= true;
 
2365
      }
 
2366
    }
 
2367
    else
 
2368
    {
 
2369
      sql_print_error(_("Incorrect definition of table %s.%s: "
 
2370
                      "expected column '%s' at position %d to have type %s "
 
2371
                      " but the column is not found."),
 
2372
                      s->db.str, alias,
 
2373
                      table_def->name.str, i, table_def->type.str);
 
2374
      error= true;
 
2375
    }
 
2376
  }
 
2377
  return(error);
 
2378
}
 
2379
 
 
2380
 
 
2381
/*
 
2382
  Create Item_field for each column in the table.
 
2383
 
 
2384
  SYNPOSIS
 
2385
    Table::fill_item_list()
 
2386
      item_list          a pointer to an empty list used to store items
 
2387
 
 
2388
  DESCRIPTION
 
2389
    Create Item_field object for each column in the table and
 
2390
    initialize it with the corresponding Field. New items are
 
2391
    created in the current THD memory root.
 
2392
 
 
2393
  RETURN VALUE
 
2394
    0                    success
 
2395
    1                    out of memory
 
2396
*/
 
2397
 
 
2398
bool Table::fill_item_list(List<Item> *item_list) const
 
2399
{
 
2400
  /*
 
2401
    All Item_field's created using a direct pointer to a field
 
2402
    are fixed in Item_field constructor.
 
2403
  */
 
2404
  for (Field **ptr= field; *ptr; ptr++)
 
2405
  {
 
2406
    Item_field *item= new Item_field(*ptr);
 
2407
    if (!item || item_list->push_back(item))
 
2408
      return true;
 
2409
  }
 
2410
  return false;
 
2411
}
 
2412
 
 
2413
/*
 
2414
  Reset an existing list of Item_field items to point to the
 
2415
  Fields of this table.
 
2416
 
 
2417
  SYNPOSIS
 
2418
    Table::fill_item_list()
 
2419
      item_list          a non-empty list with Item_fields
 
2420
 
 
2421
  DESCRIPTION
 
2422
    This is a counterpart of fill_item_list used to redirect
 
2423
    Item_fields to the fields of a newly created table.
 
2424
    The caller must ensure that number of items in the item_list
 
2425
    is the same as the number of columns in the table.
 
2426
*/
 
2427
 
 
2428
void Table::reset_item_list(List<Item> *item_list) const
 
2429
{
 
2430
  List_iterator_fast<Item> it(*item_list);
 
2431
  for (Field **ptr= field; *ptr; ptr++)
 
2432
  {
 
2433
    Item_field *item_field= (Item_field*) it++;
 
2434
    assert(item_field != 0);
 
2435
    item_field->reset_field(*ptr);
 
2436
  }
 
2437
}
 
2438
 
 
2439
 
 
2440
/*
 
2441
  Find underlying base tables (TableList) which represent given
 
2442
  table_to_find (Table)
 
2443
 
 
2444
  SYNOPSIS
 
2445
    TableList::find_underlying_table()
 
2446
    table_to_find table to find
 
2447
 
 
2448
  RETURN
 
2449
    0  table is not found
 
2450
    found table reference
 
2451
*/
 
2452
 
 
2453
TableList *TableList::find_underlying_table(Table *table_to_find)
 
2454
{
 
2455
  /* is this real table and table which we are looking for? */
 
2456
  if (table == table_to_find && merge_underlying_list == 0)
 
2457
    return this;
 
2458
 
 
2459
  for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
 
2460
  {
 
2461
    TableList *result;
 
2462
    if ((result= tbl->find_underlying_table(table_to_find)))
 
2463
      return result;
 
2464
  }
 
2465
  return 0;
 
2466
}
 
2467
 
 
2468
/*
 
2469
  cleunup items belonged to view fields translation table
 
2470
 
 
2471
  SYNOPSIS
 
2472
    TableList::cleanup_items()
 
2473
*/
 
2474
 
 
2475
void TableList::cleanup_items()
 
2476
{
 
2477
  if (!field_translation)
 
2478
    return;
 
2479
 
 
2480
  for (Field_translator *transl= field_translation;
 
2481
       transl < field_translation_end;
 
2482
       transl++)
 
2483
    transl->item->walk(&Item::cleanup_processor, 0, 0);
 
2484
}
 
2485
 
 
2486
 
 
2487
/*
 
2488
  Set insert_values buffer
 
2489
 
 
2490
  SYNOPSIS
 
2491
    set_insert_values()
 
2492
    mem_root   memory pool for allocating
 
2493
 
 
2494
  RETURN
 
2495
    false - OK
 
2496
    TRUE  - out of memory
 
2497
*/
 
2498
 
 
2499
bool TableList::set_insert_values(MEM_ROOT *mem_root)
 
2500
{
 
2501
  if (table)
 
2502
  {
 
2503
    if (!table->insert_values &&
 
2504
        !(table->insert_values= (unsigned char *)alloc_root(mem_root,
 
2505
                                                   table->s->rec_buff_length)))
 
2506
      return true;
 
2507
  }
 
2508
 
 
2509
  return false;
 
2510
}
 
2511
 
 
2512
 
 
2513
/*
 
2514
  Test if this is a leaf with respect to name resolution.
 
2515
 
 
2516
  SYNOPSIS
 
2517
    TableList::is_leaf_for_name_resolution()
 
2518
 
 
2519
  DESCRIPTION
 
2520
    A table reference is a leaf with respect to name resolution if
 
2521
    it is either a leaf node in a nested join tree (table, view,
 
2522
    schema table, subquery), or an inner node that represents a
 
2523
    NATURAL/USING join, or a nested join with materialized join
 
2524
    columns.
 
2525
 
 
2526
  RETURN
 
2527
    TRUE if a leaf, false otherwise.
 
2528
*/
 
2529
bool TableList::is_leaf_for_name_resolution()
 
2530
{
 
2531
  return (is_natural_join || is_join_columns_complete || !nested_join);
 
2532
}
 
2533
 
 
2534
 
 
2535
/*
 
2536
  Retrieve the first (left-most) leaf in a nested join tree with
 
2537
  respect to name resolution.
 
2538
 
 
2539
  SYNOPSIS
 
2540
    TableList::first_leaf_for_name_resolution()
 
2541
 
 
2542
  DESCRIPTION
 
2543
    Given that 'this' is a nested table reference, recursively walk
 
2544
    down the left-most children of 'this' until we reach a leaf
 
2545
    table reference with respect to name resolution.
 
2546
 
 
2547
  IMPLEMENTATION
 
2548
    The left-most child of a nested table reference is the last element
 
2549
    in the list of children because the children are inserted in
 
2550
    reverse order.
 
2551
 
 
2552
  RETURN
 
2553
    If 'this' is a nested table reference - the left-most child of
 
2554
      the tree rooted in 'this',
 
2555
    else return 'this'
 
2556
*/
 
2557
 
 
2558
TableList *TableList::first_leaf_for_name_resolution()
 
2559
{
 
2560
  TableList *cur_table_ref= NULL;
 
2561
  nested_join_st *cur_nested_join;
 
2562
 
 
2563
  if (is_leaf_for_name_resolution())
 
2564
    return this;
 
2565
  assert(nested_join);
 
2566
 
 
2567
  for (cur_nested_join= nested_join;
 
2568
       cur_nested_join;
 
2569
       cur_nested_join= cur_table_ref->nested_join)
 
2570
  {
 
2571
    List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
2572
    cur_table_ref= it++;
 
2573
    /*
 
2574
      If the current nested join is a RIGHT JOIN, the operands in
 
2575
      'join_list' are in reverse order, thus the first operand is
 
2576
      already at the front of the list. Otherwise the first operand
 
2577
      is in the end of the list of join operands.
 
2578
    */
 
2579
    if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
2580
    {
 
2581
      TableList *next;
 
2582
      while ((next= it++))
 
2583
        cur_table_ref= next;
 
2584
    }
 
2585
    if (cur_table_ref->is_leaf_for_name_resolution())
 
2586
      break;
 
2587
  }
 
2588
  return cur_table_ref;
 
2589
}
 
2590
 
 
2591
 
 
2592
/*
 
2593
  Retrieve the last (right-most) leaf in a nested join tree with
 
2594
  respect to name resolution.
 
2595
 
 
2596
  SYNOPSIS
 
2597
    TableList::last_leaf_for_name_resolution()
 
2598
 
 
2599
  DESCRIPTION
 
2600
    Given that 'this' is a nested table reference, recursively walk
 
2601
    down the right-most children of 'this' until we reach a leaf
 
2602
    table reference with respect to name resolution.
 
2603
 
 
2604
  IMPLEMENTATION
 
2605
    The right-most child of a nested table reference is the first
 
2606
    element in the list of children because the children are inserted
 
2607
    in reverse order.
 
2608
 
 
2609
  RETURN
 
2610
    - If 'this' is a nested table reference - the right-most child of
 
2611
      the tree rooted in 'this',
 
2612
    - else - 'this'
 
2613
*/
 
2614
 
 
2615
TableList *TableList::last_leaf_for_name_resolution()
 
2616
{
 
2617
  TableList *cur_table_ref= this;
 
2618
  nested_join_st *cur_nested_join;
 
2619
 
 
2620
  if (is_leaf_for_name_resolution())
 
2621
    return this;
 
2622
  assert(nested_join);
 
2623
 
 
2624
  for (cur_nested_join= nested_join;
 
2625
       cur_nested_join;
 
2626
       cur_nested_join= cur_table_ref->nested_join)
 
2627
  {
 
2628
    cur_table_ref= cur_nested_join->join_list.head();
 
2629
    /*
 
2630
      If the current nested is a RIGHT JOIN, the operands in
 
2631
      'join_list' are in reverse order, thus the last operand is in the
 
2632
      end of the list.
 
2633
    */
 
2634
    if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
 
2635
    {
 
2636
      List_iterator_fast<TableList> it(cur_nested_join->join_list);
 
2637
      TableList *next;
 
2638
      cur_table_ref= it++;
 
2639
      while ((next= it++))
 
2640
        cur_table_ref= next;
 
2641
    }
 
2642
    if (cur_table_ref->is_leaf_for_name_resolution())
 
2643
      break;
 
2644
  }
 
2645
  return cur_table_ref;
1989
2646
}
1990
2647
 
1991
2648
 
2002
2659
    bitmap_clear_all(&table->def_read_set);
2003
2660
    bitmap_clear_all(&table->def_write_set);
2004
2661
  */
2005
 
  def_read_set.clearAll();
2006
 
  def_write_set.clearAll();
 
2662
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
2007
2663
  column_bitmaps_set(&def_read_set, &def_write_set);
2008
2664
}
2009
2665
 
2010
2666
 
2011
2667
/*
2012
 
  Tell Cursor we are going to call position() and rnd_pos() later.
2013
 
 
 
2668
  Tell handler we are going to call position() and rnd_pos() later.
 
2669
  
2014
2670
  NOTES:
2015
2671
  This is needed for handlers that uses the primary key to find the
2016
2672
  row. In this case we have to extend the read bitmap with the primary
2020
2676
void Table::prepare_for_position()
2021
2677
{
2022
2678
 
2023
 
  if ((cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
 
2679
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
2024
2680
      s->primary_key < MAX_KEY)
2025
2681
  {
2026
 
    mark_columns_used_by_index_no_reset(s->primary_key);
 
2682
    mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
2683
    /* signal change */
 
2684
    file->column_bitmaps_signal();
2027
2685
  }
2028
2686
  return;
2029
2687
}
2041
2699
 
2042
2700
void Table::mark_columns_used_by_index(uint32_t index)
2043
2701
{
2044
 
  MyBitmap *bitmap= &tmp_set;
 
2702
  MY_BITMAP *bitmap= &tmp_set;
2045
2703
 
2046
 
  (void) cursor->extra(HA_EXTRA_KEYREAD);
2047
 
  bitmap->clearAll();
 
2704
  (void) file->extra(HA_EXTRA_KEYREAD);
 
2705
  bitmap_clear_all(bitmap);
2048
2706
  mark_columns_used_by_index_no_reset(index, bitmap);
2049
2707
  column_bitmaps_set(bitmap, bitmap);
2050
2708
  return;
2066
2724
{
2067
2725
 
2068
2726
  key_read= 0;
2069
 
  (void) cursor->extra(HA_EXTRA_NO_KEYREAD);
 
2727
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
2070
2728
  default_column_bitmaps();
 
2729
  file->column_bitmaps_signal();
2071
2730
  return;
2072
2731
}
2073
2732
 
2076
2735
  mark columns used by key, but don't reset other fields
2077
2736
*/
2078
2737
 
2079
 
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
2080
 
{
2081
 
    mark_columns_used_by_index_no_reset(index, read_set);
2082
 
}
2083
 
 
2084
2738
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
2085
 
                                                MyBitmap *bitmap)
 
2739
                                                   MY_BITMAP *bitmap)
2086
2740
{
2087
2741
  KEY_PART_INFO *key_part= key_info[index].key_part;
2088
2742
  KEY_PART_INFO *key_part_end= (key_part +
2089
2743
                                key_info[index].key_parts);
2090
2744
  for (;key_part != key_part_end; key_part++)
2091
 
    bitmap->setBit(key_part->fieldnr-1);
 
2745
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
2092
2746
}
2093
2747
 
2094
2748
 
2107
2761
    We must set bit in read set as update_auto_increment() is using the
2108
2762
    store() to check overflow of auto_increment values
2109
2763
  */
2110
 
  setReadSet(found_next_number_field->field_index);
2111
 
  setWriteSet(found_next_number_field->field_index);
 
2764
  bitmap_set_bit(read_set, found_next_number_field->field_index);
 
2765
  bitmap_set_bit(write_set, found_next_number_field->field_index);
2112
2766
  if (s->next_number_keypart)
2113
 
    mark_columns_used_by_index_no_reset(s->next_number_index);
 
2767
    mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
 
2768
  file->column_bitmaps_signal();
2114
2769
}
2115
2770
 
2116
2771
 
2134
2789
 
2135
2790
void Table::mark_columns_needed_for_delete()
2136
2791
{
2137
 
  /*
2138
 
    If the Cursor has no cursor capabilites, or we have row-based
2139
 
    replication active for the current statement, we have to read
2140
 
    either the primary key, the hidden primary key or all columns to
2141
 
    be able to do an delete
2142
 
 
2143
 
  */
2144
 
  if (s->primary_key == MAX_KEY)
2145
 
  {
2146
 
    /* fallback to use all columns in the table to identify row */
2147
 
    use_all_columns();
2148
 
    return;
2149
 
  }
2150
 
  else
2151
 
    mark_columns_used_by_index_no_reset(s->primary_key);
2152
 
 
2153
 
  /* If we the engine wants all predicates we mark all keys */
2154
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2792
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2155
2793
  {
2156
2794
    Field **reg_field;
2157
2795
    for (reg_field= field ; *reg_field ; reg_field++)
2158
2796
    {
2159
2797
      if ((*reg_field)->flags & PART_KEY_FLAG)
2160
 
        setReadSet((*reg_field)->field_index);
 
2798
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
2799
    }
 
2800
    file->column_bitmaps_signal();
 
2801
  }
 
2802
  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
 
2803
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
 
2804
  {
 
2805
    /*
 
2806
      If the handler has no cursor capabilites, or we have row-based
 
2807
      replication active for the current statement, we have to read
 
2808
      either the primary key, the hidden primary key or all columns to
 
2809
      be able to do an delete
 
2810
    */
 
2811
    if (s->primary_key == MAX_KEY)
 
2812
      file->use_hidden_primary_key();
 
2813
    else
 
2814
    {
 
2815
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
2816
      file->column_bitmaps_signal();
2161
2817
    }
2162
2818
  }
2163
2819
}
2175
2831
    if neeed, either the primary key column or all columns to be read.
2176
2832
    (see mark_columns_needed_for_delete() for details)
2177
2833
 
2178
 
    If the engine has HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
 
2834
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
2179
2835
    mark all USED key columns as 'to-be-read'. This allows the engine to
2180
2836
    loop over the given record to find all changed keys and doesn't have to
2181
2837
    retrieve the row again.
2183
2839
 
2184
2840
void Table::mark_columns_needed_for_update()
2185
2841
{
2186
 
  /*
2187
 
    If the Cursor has no cursor capabilites, or we have row-based
2188
 
    logging active for the current statement, we have to read either
2189
 
    the primary key, the hidden primary key or all columns to be
2190
 
    able to do an update
2191
 
  */
2192
 
  if (s->primary_key == MAX_KEY)
2193
 
  {
2194
 
    /* fallback to use all columns in the table to identify row */
2195
 
    use_all_columns();
2196
 
    return;
2197
 
  }
2198
 
  else
2199
 
    mark_columns_used_by_index_no_reset(s->primary_key);
2200
 
 
2201
 
  if (cursor->getEngine()->check_flag(HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE))
 
2842
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2202
2843
  {
2203
2844
    /* Mark all used key columns for read */
2204
2845
    Field **reg_field;
2205
2846
    for (reg_field= field ; *reg_field ; reg_field++)
2206
2847
    {
2207
2848
      /* Merge keys is all keys that had a column refered to in the query */
2208
 
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
2209
 
        setReadSet((*reg_field)->field_index);
2210
 
    }
2211
 
  }
2212
 
 
 
2849
      if (merge_keys.is_overlapping((*reg_field)->part_of_key))
 
2850
        bitmap_set_bit(read_set, (*reg_field)->field_index);
 
2851
    }
 
2852
    file->column_bitmaps_signal();
 
2853
  }
 
2854
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) ||
 
2855
      (mysql_bin_log.is_open() && in_use && in_use->current_stmt_binlog_row_based))
 
2856
  {
 
2857
    /*
 
2858
      If the handler has no cursor capabilites, or we have row-based
 
2859
      logging active for the current statement, we have to read either
 
2860
      the primary key, the hidden primary key or all columns to be
 
2861
      able to do an update
 
2862
    */
 
2863
    if (s->primary_key == MAX_KEY)
 
2864
      file->use_hidden_primary_key();
 
2865
    else
 
2866
    {
 
2867
      mark_columns_used_by_index_no_reset(s->primary_key, read_set);
 
2868
      file->column_bitmaps_signal();
 
2869
    }
 
2870
  }
 
2871
  return;
2213
2872
}
2214
2873
 
2215
2874
 
2216
2875
/*
2217
 
  Mark columns the Cursor needs for doing an insert
 
2876
  Mark columns the handler needs for doing an insert
2218
2877
 
2219
2878
  For now, this is used to mark fields used by the trigger
2220
2879
  as changed.
2226
2885
    mark_auto_increment_column();
2227
2886
}
2228
2887
 
 
2888
/*
 
2889
  Cleanup this table for re-execution.
 
2890
 
 
2891
  SYNOPSIS
 
2892
    TableList::reinit_before_use()
 
2893
*/
 
2894
 
 
2895
void TableList::reinit_before_use(THD *thd)
 
2896
{
 
2897
  /*
 
2898
    Reset old pointers to TABLEs: they are not valid since the tables
 
2899
    were closed in the end of previous prepare or execute call.
 
2900
  */
 
2901
  table= 0;
 
2902
  /* Reset is_schema_table_processed value(needed for I_S tables */
 
2903
  schema_table_state= NOT_PROCESSED;
 
2904
 
 
2905
  TableList *embedded; /* The table at the current level of nesting. */
 
2906
  TableList *parent_embedding= this; /* The parent nested table reference. */
 
2907
  do
 
2908
  {
 
2909
    embedded= parent_embedding;
 
2910
    if (embedded->prep_on_expr)
 
2911
      embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
 
2912
    parent_embedding= embedded->embedding;
 
2913
  }
 
2914
  while (parent_embedding &&
 
2915
         parent_embedding->nested_join->join_list.head() == embedded);
 
2916
}
 
2917
 
 
2918
/*
 
2919
  Return subselect that contains the FROM list this table is taken from
 
2920
 
 
2921
  SYNOPSIS
 
2922
    TableList::containing_subselect()
 
2923
 
 
2924
  RETURN
 
2925
    Subselect item for the subquery that contains the FROM list
 
2926
    this table is taken from if there is any
 
2927
    0 - otherwise
 
2928
 
 
2929
*/
 
2930
 
 
2931
Item_subselect *TableList::containing_subselect()
 
2932
{    
 
2933
  return (select_lex ? select_lex->master_unit()->item : 0);
 
2934
}
 
2935
 
 
2936
/*
 
2937
  Compiles the tagged hints list and fills up the bitmasks.
 
2938
 
 
2939
  SYNOPSIS
 
2940
    process_index_hints()
 
2941
      table         the Table to operate on.
 
2942
 
 
2943
  DESCRIPTION
 
2944
    The parser collects the index hints for each table in a "tagged list" 
 
2945
    (TableList::index_hints). Using the information in this tagged list
 
2946
    this function sets the members Table::keys_in_use_for_query, 
 
2947
    Table::keys_in_use_for_group_by, Table::keys_in_use_for_order_by,
 
2948
    Table::force_index and Table::covering_keys.
 
2949
 
 
2950
    Current implementation of the runtime does not allow mixing FORCE INDEX
 
2951
    and USE INDEX, so this is checked here. Then the FORCE INDEX list 
 
2952
    (if non-empty) is appended to the USE INDEX list and a flag is set.
 
2953
 
 
2954
    Multiple hints of the same kind are processed so that each clause 
 
2955
    is applied to what is computed in the previous clause.
 
2956
    For example:
 
2957
        USE INDEX (i1) USE INDEX (i2)
 
2958
    is equivalent to
 
2959
        USE INDEX (i1,i2)
 
2960
    and means "consider only i1 and i2".
 
2961
        
 
2962
    Similarly
 
2963
        USE INDEX () USE INDEX (i1)
 
2964
    is equivalent to
 
2965
        USE INDEX (i1)
 
2966
    and means "consider only the index i1"
 
2967
 
 
2968
    It is OK to have the same index several times, e.g. "USE INDEX (i1,i1)" is
 
2969
    not an error.
 
2970
        
 
2971
    Different kind of hints (USE/FORCE/IGNORE) are processed in the following
 
2972
    order:
 
2973
      1. All indexes in USE (or FORCE) INDEX are added to the mask.
 
2974
      2. All IGNORE INDEX
 
2975
 
 
2976
    e.g. "USE INDEX i1, IGNORE INDEX i1, USE INDEX i1" will not use i1 at all
 
2977
    as if we had "USE INDEX i1, USE INDEX i1, IGNORE INDEX i1".
 
2978
 
 
2979
    As an optimization if there is a covering index, and we have 
 
2980
    IGNORE INDEX FOR GROUP/order_st, and this index is used for the JOIN part, 
 
2981
    then we have to ignore the IGNORE INDEX FROM GROUP/order_st.
 
2982
 
 
2983
  RETURN VALUE
 
2984
    false                no errors found
 
2985
    TRUE                 found and reported an error.
 
2986
*/
 
2987
bool TableList::process_index_hints(Table *tbl)
 
2988
{
 
2989
  /* initialize the result variables */
 
2990
  tbl->keys_in_use_for_query= tbl->keys_in_use_for_group_by= 
 
2991
    tbl->keys_in_use_for_order_by= tbl->s->keys_in_use;
 
2992
 
 
2993
  /* index hint list processing */
 
2994
  if (index_hints)
 
2995
  {
 
2996
    key_map index_join[INDEX_HINT_FORCE + 1];
 
2997
    key_map index_order[INDEX_HINT_FORCE + 1];
 
2998
    key_map index_group[INDEX_HINT_FORCE + 1];
 
2999
    Index_hint *hint;
 
3000
    int type;
 
3001
    bool have_empty_use_join= false, have_empty_use_order= false, 
 
3002
         have_empty_use_group= false;
 
3003
    List_iterator <Index_hint> iter(*index_hints);
 
3004
 
 
3005
    /* initialize temporary variables used to collect hints of each kind */
 
3006
    for (type= INDEX_HINT_IGNORE; type <= INDEX_HINT_FORCE; type++)
 
3007
    {
 
3008
      index_join[type].clear_all();
 
3009
      index_order[type].clear_all();
 
3010
      index_group[type].clear_all();
 
3011
    }
 
3012
 
 
3013
    /* iterate over the hints list */
 
3014
    while ((hint= iter++))
 
3015
    {
 
3016
      uint32_t pos;
 
3017
 
 
3018
      /* process empty USE INDEX () */
 
3019
      if (hint->type == INDEX_HINT_USE && !hint->key_name.str)
 
3020
      {
 
3021
        if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3022
        {
 
3023
          index_join[hint->type].clear_all();
 
3024
          have_empty_use_join= true;
 
3025
        }
 
3026
        if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3027
        {
 
3028
          index_order[hint->type].clear_all();
 
3029
          have_empty_use_order= true;
 
3030
        }
 
3031
        if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3032
        {
 
3033
          index_group[hint->type].clear_all();
 
3034
          have_empty_use_group= true;
 
3035
        }
 
3036
        continue;
 
3037
      }
 
3038
 
 
3039
      /* 
 
3040
        Check if an index with the given name exists and get his offset in 
 
3041
        the keys bitmask for the table 
 
3042
      */
 
3043
      if (tbl->s->keynames.type_names == 0 ||
 
3044
          (pos= find_type(&tbl->s->keynames, hint->key_name.str,
 
3045
                          hint->key_name.length, 1)) <= 0)
 
3046
      {
 
3047
        my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), hint->key_name.str, alias);
 
3048
        return 1;
 
3049
      }
 
3050
 
 
3051
      pos--;
 
3052
 
 
3053
      /* add to the appropriate clause mask */
 
3054
      if (hint->clause & INDEX_HINT_MASK_JOIN)
 
3055
        index_join[hint->type].set_bit (pos);
 
3056
      if (hint->clause & INDEX_HINT_MASK_ORDER)
 
3057
        index_order[hint->type].set_bit (pos);
 
3058
      if (hint->clause & INDEX_HINT_MASK_GROUP)
 
3059
        index_group[hint->type].set_bit (pos);
 
3060
    }
 
3061
 
 
3062
    /* cannot mix USE INDEX and FORCE INDEX */
 
3063
    if ((!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3064
         !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3065
         !index_group[INDEX_HINT_FORCE].is_clear_all()) &&
 
3066
        (!index_join[INDEX_HINT_USE].is_clear_all() ||  have_empty_use_join ||
 
3067
         !index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order ||
 
3068
         !index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group))
 
3069
    {
 
3070
      my_error(ER_WRONG_USAGE, MYF(0), index_hint_type_name[INDEX_HINT_USE],
 
3071
               index_hint_type_name[INDEX_HINT_FORCE]);
 
3072
      return 1;
 
3073
    }
 
3074
 
 
3075
    /* process FORCE INDEX as USE INDEX with a flag */
 
3076
    if (!index_join[INDEX_HINT_FORCE].is_clear_all() ||
 
3077
        !index_order[INDEX_HINT_FORCE].is_clear_all() ||
 
3078
        !index_group[INDEX_HINT_FORCE].is_clear_all())
 
3079
    {
 
3080
      tbl->force_index= true;
 
3081
      index_join[INDEX_HINT_USE].merge(index_join[INDEX_HINT_FORCE]);
 
3082
      index_order[INDEX_HINT_USE].merge(index_order[INDEX_HINT_FORCE]);
 
3083
      index_group[INDEX_HINT_USE].merge(index_group[INDEX_HINT_FORCE]);
 
3084
    }
 
3085
 
 
3086
    /* apply USE INDEX */
 
3087
    if (!index_join[INDEX_HINT_USE].is_clear_all() || have_empty_use_join)
 
3088
      tbl->keys_in_use_for_query.intersect(index_join[INDEX_HINT_USE]);
 
3089
    if (!index_order[INDEX_HINT_USE].is_clear_all() || have_empty_use_order)
 
3090
      tbl->keys_in_use_for_order_by.intersect (index_order[INDEX_HINT_USE]);
 
3091
    if (!index_group[INDEX_HINT_USE].is_clear_all() || have_empty_use_group)
 
3092
      tbl->keys_in_use_for_group_by.intersect (index_group[INDEX_HINT_USE]);
 
3093
 
 
3094
    /* apply IGNORE INDEX */
 
3095
    tbl->keys_in_use_for_query.subtract (index_join[INDEX_HINT_IGNORE]);
 
3096
    tbl->keys_in_use_for_order_by.subtract (index_order[INDEX_HINT_IGNORE]);
 
3097
    tbl->keys_in_use_for_group_by.subtract (index_group[INDEX_HINT_IGNORE]);
 
3098
  }
 
3099
 
 
3100
  /* make sure covering_keys don't include indexes disabled with a hint */
 
3101
  tbl->covering_keys.intersect(tbl->keys_in_use_for_query);
 
3102
  return 0;
 
3103
}
2229
3104
 
2230
3105
 
2231
3106
size_t Table::max_row_length(const unsigned char *data)
2244
3119
  return length;
2245
3120
}
2246
3121
 
 
3122
/*
 
3123
  Check type of .frm if we are not going to parse it
 
3124
 
 
3125
  SYNOPSIS
 
3126
  mysql_frm_type()
 
3127
  path        path to file
 
3128
 
 
3129
  RETURN
 
3130
  false       error
 
3131
  true       table
 
3132
*/
 
3133
 
 
3134
bool mysql_frm_type(THD *thd __attribute__((unused)),
 
3135
                    char *path, enum legacy_db_type *dbt)
 
3136
{
 
3137
  File file;
 
3138
  unsigned char header[10];     /* This should be optimized */
 
3139
  int error;
 
3140
 
 
3141
  *dbt= DB_TYPE_UNKNOWN;
 
3142
 
 
3143
  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
 
3144
    return false;
 
3145
  error= my_read(file, (unsigned char*) header, sizeof(header), MYF(MY_NABP));
 
3146
  my_close(file, MYF(MY_WME));
 
3147
 
 
3148
  if (error)
 
3149
    return false;
 
3150
 
 
3151
  /*  
 
3152
    This is just a check for DB_TYPE. We'll return default unknown type
 
3153
    if the following test is true (arg #3). This should not have effect
 
3154
    on return value from this function (default FRMTYPE_TABLE)
 
3155
   */  
 
3156
  if (header[0] != (unsigned char) 254 || header[1] != 1 ||
 
3157
      (header[2] != FRM_VER && header[2] != FRM_VER+1 &&
 
3158
       (header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
 
3159
    return true;
 
3160
 
 
3161
  *dbt= (enum legacy_db_type) (uint) *(header + 3);
 
3162
  return true;                   // Is probably a .frm table
 
3163
}
 
3164
 
2247
3165
/****************************************************************************
2248
3166
 Functions for creating temporary tables.
2249
3167
****************************************************************************/
2250
3168
 
2251
3169
 
2252
3170
/* Prototypes */
2253
 
void free_tmp_table(Session *session, Table *entry);
 
3171
void free_tmp_table(THD *thd, Table *entry);
2254
3172
 
2255
3173
/**
2256
3174
  Create field for temporary table from given field.
2257
3175
 
2258
 
  @param session               Thread Cursor
 
3176
  @param thd           Thread handler
2259
3177
  @param org_field    field from which new field will be created
2260
3178
  @param name         New field name
2261
3179
  @param table         Temporary table
2274
3192
    new_created field
2275
3193
*/
2276
3194
 
2277
 
Field *create_tmp_field_from_field(Session *session, Field *org_field,
 
3195
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
2278
3196
                                   const char *name, Table *table,
2279
3197
                                   Item_field *item, uint32_t convert_blob_length)
2280
3198
{
2281
3199
  Field *new_field;
2282
3200
 
2283
 
  /*
2284
 
    Make sure that the blob fits into a Field_varstring which has
2285
 
    2-byte lenght.
 
3201
  /* 
 
3202
    Make sure that the blob fits into a Field_varstring which has 
 
3203
    2-byte lenght. 
2286
3204
  */
2287
3205
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
2288
3206
      (org_field->flags & BLOB_FLAG))
2291
3209
                                   org_field->field_name, table->s,
2292
3210
                                   org_field->charset());
2293
3211
  else
2294
 
    new_field= org_field->new_field(session->mem_root, table,
 
3212
    new_field= org_field->new_field(thd->mem_root, table,
2295
3213
                                    table == org_field->table);
2296
3214
  if (new_field)
2297
3215
  {
2312
3230
  return new_field;
2313
3231
}
2314
3232
 
 
3233
/**
 
3234
  Create field for temporary table using type of given item.
 
3235
 
 
3236
  @param thd                   Thread handler
 
3237
  @param item                  Item to create a field for
 
3238
  @param table                 Temporary table
 
3239
  @param copy_func             If set and item is a function, store copy of
 
3240
                               item in this array
 
3241
  @param modify_item           1 if item->result_field should point to new
 
3242
                               item. This is relevent for how fill_record()
 
3243
                               is going to work:
 
3244
                               If modify_item is 1 then fill_record() will
 
3245
                               update the record in the original table.
 
3246
                               If modify_item is 0 then fill_record() will
 
3247
                               update the temporary table
 
3248
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
 
3249
                               field instead of blob.
 
3250
 
 
3251
  @retval
 
3252
    0  on error
 
3253
  @retval
 
3254
    new_created field
 
3255
*/
 
3256
 
 
3257
static Field *create_tmp_field_from_item(THD *thd __attribute__((unused)),
 
3258
                                         Item *item, Table *table,
 
3259
                                         Item ***copy_func, bool modify_item,
 
3260
                                         uint32_t convert_blob_length)
 
3261
{
 
3262
  bool maybe_null= item->maybe_null;
 
3263
  Field *new_field;
 
3264
 
 
3265
  switch (item->result_type()) {
 
3266
  case REAL_RESULT:
 
3267
    new_field= new Field_double(item->max_length, maybe_null,
 
3268
                                item->name, item->decimals, true);
 
3269
    break;
 
3270
  case INT_RESULT:
 
3271
    /* 
 
3272
      Select an integer type with the minimal fit precision.
 
3273
      MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
 
3274
      Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into 
 
3275
      Field_long : make them Field_int64_t.  
 
3276
    */
 
3277
    if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
 
3278
      new_field=new Field_int64_t(item->max_length, maybe_null,
 
3279
                                   item->name, item->unsigned_flag);
 
3280
    else
 
3281
      new_field=new Field_long(item->max_length, maybe_null,
 
3282
                               item->name, item->unsigned_flag);
 
3283
    break;
 
3284
  case STRING_RESULT:
 
3285
    assert(item->collation.collation);
 
3286
  
 
3287
    enum enum_field_types type;
 
3288
    /*
 
3289
      DATE/TIME fields have STRING_RESULT result type. 
 
3290
      To preserve type they needed to be handled separately.
 
3291
    */
 
3292
    if ((type= item->field_type()) == DRIZZLE_TYPE_DATETIME ||
 
3293
        type == DRIZZLE_TYPE_TIME || type == DRIZZLE_TYPE_NEWDATE ||
 
3294
        type == DRIZZLE_TYPE_TIMESTAMP)
 
3295
      new_field= item->tmp_table_field_from_field_type(table, 1);
 
3296
    /* 
 
3297
      Make sure that the blob fits into a Field_varstring which has 
 
3298
      2-byte lenght. 
 
3299
    */
 
3300
    else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
 
3301
             convert_blob_length <= Field_varstring::MAX_SIZE && 
 
3302
             convert_blob_length)
 
3303
      new_field= new Field_varstring(convert_blob_length, maybe_null,
 
3304
                                     item->name, table->s,
 
3305
                                     item->collation.collation);
 
3306
    else
 
3307
      new_field= item->make_string_field(table);
 
3308
    new_field->set_derivation(item->collation.derivation);
 
3309
    break;
 
3310
  case DECIMAL_RESULT:
 
3311
  {
 
3312
    uint8_t dec= item->decimals;
 
3313
    uint8_t intg= ((Item_decimal *) item)->decimal_precision() - dec;
 
3314
    uint32_t len= item->max_length;
 
3315
 
 
3316
    /*
 
3317
      Trying to put too many digits overall in a DECIMAL(prec,dec)
 
3318
      will always throw a warning. We must limit dec to
 
3319
      DECIMAL_MAX_SCALE however to prevent an assert() later.
 
3320
    */
 
3321
 
 
3322
    if (dec > 0)
 
3323
    {
 
3324
      signed int overflow;
 
3325
 
 
3326
      dec= cmin(dec, (uint8_t)DECIMAL_MAX_SCALE);
 
3327
 
 
3328
      /*
 
3329
        If the value still overflows the field with the corrected dec,
 
3330
        we'll throw out decimals rather than integers. This is still
 
3331
        bad and of course throws a truncation warning.
 
3332
        +1: for decimal point
 
3333
      */
 
3334
 
 
3335
      overflow= my_decimal_precision_to_length(intg + dec, dec,
 
3336
                                               item->unsigned_flag) - len;
 
3337
 
 
3338
      if (overflow > 0)
 
3339
        dec= cmax(0, dec - overflow);            // too long, discard fract
 
3340
      else
 
3341
        len -= item->decimals - dec;            // corrected value fits
 
3342
    }
 
3343
 
 
3344
    new_field= new Field_new_decimal(len, maybe_null, item->name,
 
3345
                                     dec, item->unsigned_flag);
 
3346
    break;
 
3347
  }
 
3348
  case ROW_RESULT:
 
3349
  default:
 
3350
    // This case should never be choosen
 
3351
    assert(0);
 
3352
    new_field= 0;
 
3353
    break;
 
3354
  }
 
3355
  if (new_field)
 
3356
    new_field->init(table);
 
3357
    
 
3358
  if (copy_func && item->is_result_field())
 
3359
    *((*copy_func)++) = item;                   // Save for copy_funcs
 
3360
  if (modify_item)
 
3361
    item->set_result_field(new_field);
 
3362
  if (item->type() == Item::NULL_ITEM)
 
3363
    new_field->is_created_from_null_item= true;
 
3364
  return new_field;
 
3365
}
 
3366
 
 
3367
 
 
3368
/**
 
3369
  Create field for information schema table.
 
3370
 
 
3371
  @param thd            Thread handler
 
3372
  @param table          Temporary table
 
3373
  @param item           Item to create a field for
 
3374
 
 
3375
  @retval
 
3376
    0                   on error
 
3377
  @retval
 
3378
    new_created field
 
3379
*/
 
3380
 
 
3381
Field *create_tmp_field_for_schema(THD *thd __attribute__((unused)),
 
3382
                                   Item *item, Table *table)
 
3383
{
 
3384
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
 
3385
  {
 
3386
    Field *field;
 
3387
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
 
3388
      field= new Field_blob(item->max_length, item->maybe_null,
 
3389
                            item->name, item->collation.collation);
 
3390
    else
 
3391
      field= new Field_varstring(item->max_length, item->maybe_null,
 
3392
                                 item->name,
 
3393
                                 table->s, item->collation.collation);
 
3394
    if (field)
 
3395
      field->init(table);
 
3396
    return field;
 
3397
  }
 
3398
  return item->tmp_table_field_from_field_type(table, 0);
 
3399
}
 
3400
 
 
3401
 
 
3402
/**
 
3403
  Create field for temporary table.
 
3404
 
 
3405
  @param thd            Thread handler
 
3406
  @param table          Temporary table
 
3407
  @param item           Item to create a field for
 
3408
  @param type           Type of item (normally item->type)
 
3409
  @param copy_func      If set and item is a function, store copy of item
 
3410
                       in this array
 
3411
  @param from_field    if field will be created using other field as example,
 
3412
                       pointer example field will be written here
 
3413
  @param default_field  If field has a default value field, store it here
 
3414
  @param group          1 if we are going to do a relative group by on result
 
3415
  @param modify_item    1 if item->result_field should point to new item.
 
3416
                       This is relevent for how fill_record() is going to
 
3417
                       work:
 
3418
                       If modify_item is 1 then fill_record() will update
 
3419
                       the record in the original table.
 
3420
                       If modify_item is 0 then fill_record() will update
 
3421
                       the temporary table
 
3422
  @param convert_blob_length If >0 create a varstring(convert_blob_length)
 
3423
                             field instead of blob.
 
3424
 
 
3425
  @retval
 
3426
    0                   on error
 
3427
  @retval
 
3428
    new_created field
 
3429
*/
 
3430
 
 
3431
Field *create_tmp_field(THD *thd, Table *table,Item *item, Item::Type type,
 
3432
                        Item ***copy_func, Field **from_field,
 
3433
                        Field **default_field,
 
3434
                        bool group, bool modify_item,
 
3435
                        bool table_cant_handle_bit_fields __attribute__((unused)),
 
3436
                        bool make_copy_field,
 
3437
                        uint32_t convert_blob_length)
 
3438
{
 
3439
  Field *result;
 
3440
  Item::Type orig_type= type;
 
3441
  Item *orig_item= 0;
 
3442
 
 
3443
  if (type != Item::FIELD_ITEM &&
 
3444
      item->real_item()->type() == Item::FIELD_ITEM)
 
3445
  {
 
3446
    orig_item= item;
 
3447
    item= item->real_item();
 
3448
    type= Item::FIELD_ITEM;
 
3449
  }
 
3450
 
 
3451
  switch (type) {
 
3452
  case Item::SUM_FUNC_ITEM:
 
3453
  {
 
3454
    Item_sum *item_sum=(Item_sum*) item;
 
3455
    result= item_sum->create_tmp_field(group, table, convert_blob_length);
 
3456
    if (!result)
 
3457
      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
 
3458
    return result;
 
3459
  }
 
3460
  case Item::FIELD_ITEM:
 
3461
  case Item::DEFAULT_VALUE_ITEM:
 
3462
  {
 
3463
    Item_field *field= (Item_field*) item;
 
3464
    bool orig_modify= modify_item;
 
3465
    if (orig_type == Item::REF_ITEM)
 
3466
      modify_item= 0;
 
3467
    /*
 
3468
      If item have to be able to store NULLs but underlaid field can't do it,
 
3469
      create_tmp_field_from_field() can't be used for tmp field creation.
 
3470
    */
 
3471
    if (field->maybe_null && !field->field->maybe_null())
 
3472
    {
 
3473
      result= create_tmp_field_from_item(thd, item, table, NULL,
 
3474
                                         modify_item, convert_blob_length);
 
3475
      *from_field= field->field;
 
3476
      if (result && modify_item)
 
3477
        field->result_field= result;
 
3478
    } 
 
3479
    else
 
3480
      result= create_tmp_field_from_field(thd, (*from_field= field->field),
 
3481
                                          orig_item ? orig_item->name :
 
3482
                                          item->name,
 
3483
                                          table,
 
3484
                                          modify_item ? field :
 
3485
                                          NULL,
 
3486
                                          convert_blob_length);
 
3487
    if (orig_type == Item::REF_ITEM && orig_modify)
 
3488
      ((Item_ref*)orig_item)->set_result_field(result);
 
3489
    if (field->field->eq_def(result))
 
3490
      *default_field= field->field;
 
3491
    return result;
 
3492
  }
 
3493
  /* Fall through */
 
3494
  case Item::FUNC_ITEM:
 
3495
    /* Fall through */
 
3496
  case Item::COND_ITEM:
 
3497
  case Item::FIELD_AVG_ITEM:
 
3498
  case Item::FIELD_STD_ITEM:
 
3499
  case Item::SUBSELECT_ITEM:
 
3500
    /* The following can only happen with 'CREATE TABLE ... SELECT' */
 
3501
  case Item::PROC_ITEM:
 
3502
  case Item::INT_ITEM:
 
3503
  case Item::REAL_ITEM:
 
3504
  case Item::DECIMAL_ITEM:
 
3505
  case Item::STRING_ITEM:
 
3506
  case Item::REF_ITEM:
 
3507
  case Item::NULL_ITEM:
 
3508
  case Item::VARBIN_ITEM:
 
3509
    if (make_copy_field)
 
3510
    {
 
3511
      assert(((Item_result_field*)item)->result_field);
 
3512
      *from_field= ((Item_result_field*)item)->result_field;
 
3513
    }
 
3514
    return create_tmp_field_from_item(thd, item, table,
 
3515
                                      (make_copy_field ? 0 : copy_func),
 
3516
                                       modify_item, convert_blob_length);
 
3517
  case Item::TYPE_HOLDER:  
 
3518
    result= ((Item_type_holder *)item)->make_field_by_type(table);
 
3519
    result->set_derivation(item->collation.derivation);
 
3520
    return result;
 
3521
  default:                                      // Dosen't have to be stored
 
3522
    return 0;
 
3523
  }
 
3524
}
2315
3525
 
2316
3526
/**
2317
3527
  Create a temp table according to a field list.
2324
3534
  corresponding Item_field items, pointing at the fields in the
2325
3535
  temporary table, unless this was prohibited by true
2326
3536
  value of argument save_sum_fields. The Item_field objects
2327
 
  are created in Session memory root.
 
3537
  are created in THD memory root.
2328
3538
 
2329
 
  @param session                  thread handle
 
3539
  @param thd                  thread handle
2330
3540
  @param param                a description used as input to create the table
2331
3541
  @param fields               list of items that will be used to define
2332
3542
                              column types of the table (also see NOTES)
2342
3552
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
2343
3553
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
2344
3554
#define RATIO_TO_PACK_ROWS             2
2345
 
 
2346
 
static void make_internal_temporary_table_path(Session *session, char *path)
2347
 
{
2348
 
  snprintf(path, FN_REFLEN, "%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
2349
 
           session->thread_id, session->tmp_table++);
2350
 
 
2351
 
  internal::fn_format(path, path, drizzle_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
2352
 
}
 
3555
#define MIN_STRING_LENGTH_TO_PACK_ROWS   10
2353
3556
 
2354
3557
Table *
2355
 
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
 
3558
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
2356
3559
                 order_st *group, bool distinct, bool save_sum_fields,
2357
3560
                 uint64_t select_options, ha_rows rows_limit,
2358
 
                 const char *table_alias)
 
3561
                 char *table_alias)
2359
3562
{
2360
 
  memory::Root *mem_root_save, own_root;
 
3563
  MEM_ROOT *mem_root_save, own_root;
2361
3564
  Table *table;
2362
 
  TableShare *share;
 
3565
  TABLE_SHARE *share;
2363
3566
  uint  i,field_count,null_count,null_pack_length;
2364
3567
  uint32_t  copy_func_count= param->func_count;
2365
3568
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
2366
3569
  uint32_t  blob_count,group_null_items, string_count;
 
3570
  uint32_t  temp_pool_slot=MY_BIT_NONE;
2367
3571
  uint32_t fieldnr= 0;
2368
3572
  ulong reclength, string_total_length;
2369
 
  bool  using_unique_constraint= false;
2370
 
  bool  use_packed_rows= true;
 
3573
  bool  using_unique_constraint= 0;
 
3574
  bool  use_packed_rows= 0;
2371
3575
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
2372
 
  char  *tmpname;
2373
 
  char  path[FN_REFLEN];
 
3576
  char  *tmpname,path[FN_REFLEN];
2374
3577
  unsigned char *pos, *group_buff, *bitmaps;
2375
3578
  unsigned char *null_flags;
2376
3579
  Field **reg_field, **from_field, **default_field;
2377
3580
  uint32_t *blob_field;
2378
 
  CopyField *copy= 0;
 
3581
  Copy_field *copy=0;
2379
3582
  KEY *keyinfo;
2380
3583
  KEY_PART_INFO *key_part_info;
2381
3584
  Item **copy_func;
2382
3585
  MI_COLUMNDEF *recinfo;
2383
3586
  uint32_t total_uneven_bit_length= 0;
2384
3587
  bool force_copy_fields= param->force_copy_fields;
2385
 
  uint64_t max_rows= 0;
2386
 
 
2387
 
  status_var_increment(session->status_var.created_tmp_tables);
2388
 
 
2389
 
  make_internal_temporary_table_path(session, path);
 
3588
 
 
3589
  status_var_increment(thd->status_var.created_tmp_tables);
 
3590
 
 
3591
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
 
3592
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
 
3593
 
 
3594
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
 
3595
    sprintf(path, "%s_%lx_%i", tmp_file_prefix,
 
3596
            current_pid, temp_pool_slot);
 
3597
  else
 
3598
  {
 
3599
    /* if we run out of slots or we are not using tempool */
 
3600
    sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
 
3601
            thd->thread_id, thd->tmp_table++);
 
3602
  }
 
3603
 
 
3604
  /*
 
3605
    No need to change table name to lower case as we are only creating
 
3606
    MyISAM or HEAP tables here
 
3607
  */
 
3608
  fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
3609
 
2390
3610
 
2391
3611
  if (group)
2392
3612
  {
2393
 
    if (! param->quick_group)
2394
 
      group= 0;                                 // Can't use group key
 
3613
    if (!param->quick_group)
 
3614
      group=0;                                  // Can't use group key
2395
3615
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
2396
3616
    {
2397
3617
      /*
2402
3622
      */
2403
3623
      (*tmp->item)->marker= 4;
2404
3624
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
2405
 
        using_unique_constraint= true;
 
3625
        using_unique_constraint=1;
2406
3626
    }
2407
3627
    if (param->group_length >= MAX_BLOB_WIDTH)
2408
 
      using_unique_constraint= true;
 
3628
      using_unique_constraint=1;
2409
3629
    if (group)
2410
 
      distinct= 0;                              // Can't use distinct
 
3630
      distinct=0;                               // Can't use distinct
2411
3631
  }
2412
3632
 
2413
3633
  field_count=param->field_count+param->func_count+param->sum_func_count;
2417
3637
    When loose index scan is employed as access method, it already
2418
3638
    computes all groups and the result of all aggregate functions. We
2419
3639
    make space for the items of the aggregate function in the list of
2420
 
    functions Tmp_Table_Param::items_to_copy, so that the values of
 
3640
    functions TMP_TABLE_PARAM::items_to_copy, so that the values of
2421
3641
    these items are stored in the temporary table.
2422
3642
  */
2423
3643
  if (param->precomputed_group_by)
2424
3644
    copy_func_count+= param->sum_func_count;
2425
 
 
2426
 
  memory::init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
 
3645
  
 
3646
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
2427
3647
 
2428
3648
  if (!multi_alloc_root(&own_root,
2429
3649
                        &table, sizeof(*table),
2430
3650
                        &share, sizeof(*share),
2431
3651
                        &reg_field, sizeof(Field*) * (field_count+1),
2432
3652
                        &default_field, sizeof(Field*) * (field_count),
2433
 
                        &blob_field, sizeof(uint32_t)*(field_count+1),
 
3653
                        &blob_field, sizeof(uint)*(field_count+1),
2434
3654
                        &from_field, sizeof(Field*)*field_count,
2435
3655
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
2436
3656
                        &param->keyinfo, sizeof(*param->keyinfo),
2438
3658
                        sizeof(*key_part_info)*(param->group_parts+1),
2439
3659
                        &param->start_recinfo,
2440
3660
                        sizeof(*param->recinfo)*(field_count*2+4),
2441
 
                        &tmpname, (uint32_t) strlen(path)+1,
 
3661
                        &tmpname, (uint) strlen(path)+1,
2442
3662
                        &group_buff, (group && ! using_unique_constraint ?
2443
3663
                                      param->group_length : 0),
2444
3664
                        &bitmaps, bitmap_buffer_size(field_count)*2,
2445
3665
                        NULL))
2446
3666
  {
2447
 
    return NULL;
 
3667
    if (temp_pool_slot != MY_BIT_NONE)
 
3668
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3669
    return(NULL);                               /* purecov: inspected */
2448
3670
  }
2449
 
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
2450
 
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
 
3671
  /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
 
3672
  if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
2451
3673
  {
2452
 
    free_root(&own_root, MYF(0));
2453
 
    return NULL;
 
3674
    if (temp_pool_slot != MY_BIT_NONE)
 
3675
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
3676
    free_root(&own_root, MYF(0));               /* purecov: inspected */
 
3677
    return(NULL);                               /* purecov: inspected */
2454
3678
  }
2455
3679
  param->items_to_copy= copy_func;
2456
 
  strcpy(tmpname,path);
 
3680
  my_stpcpy(tmpname,path);
2457
3681
  /* make table according to fields */
2458
3682
 
2459
3683
  memset(table, 0, sizeof(*table));
2462
3686
  memset(from_field, 0, sizeof(Field*)*field_count);
2463
3687
 
2464
3688
  table->mem_root= own_root;
2465
 
  mem_root_save= session->mem_root;
2466
 
  session->mem_root= &table->mem_root;
 
3689
  mem_root_save= thd->mem_root;
 
3690
  thd->mem_root= &table->mem_root;
2467
3691
 
2468
3692
  table->field=reg_field;
2469
3693
  table->alias= table_alias;
2470
3694
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
2471
3695
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
2472
3696
  table->map=1;
 
3697
  table->temp_pool_slot = temp_pool_slot;
2473
3698
  table->copy_blobs= 1;
2474
 
  table->in_use= session;
2475
 
  table->quick_keys.reset();
2476
 
  table->covering_keys.reset();
2477
 
  table->keys_in_use_for_query.reset();
 
3699
  table->in_use= thd;
 
3700
  table->quick_keys.init();
 
3701
  table->covering_keys.init();
 
3702
  table->keys_in_use_for_query.init();
2478
3703
 
2479
3704
  table->setShare(share);
2480
 
  share->init(tmpname, tmpname);
 
3705
  init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
2481
3706
  share->blob_field= blob_field;
2482
3707
  share->blob_ptr_size= portable_sizeof_char_ptr;
2483
3708
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
2484
3709
  share->table_charset= param->table_charset;
2485
3710
  share->primary_key= MAX_KEY;               // Indicate no primary key
2486
 
  share->keys_for_keyread.reset();
2487
 
  share->keys_in_use.reset();
 
3711
  share->keys_for_keyread.init();
 
3712
  share->keys_in_use.init();
2488
3713
 
2489
3714
  /* Calculate which type of fields we will store in the temporary table */
2490
3715
 
2491
3716
  reclength= string_total_length= 0;
2492
3717
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
2493
 
  param->using_indirect_summary_function= 0;
 
3718
  param->using_indirect_summary_function=0;
2494
3719
 
2495
3720
  List_iterator_fast<Item> li(fields);
2496
3721
  Item *item;
2521
3746
    }
2522
3747
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
2523
3748
    {                                           /* Can't calc group yet */
2524
 
      ((Item_sum*) item)->result_field= 0;
2525
 
      for (i= 0 ; i < ((Item_sum*) item)->arg_count ; i++)
 
3749
      ((Item_sum*) item)->result_field=0;
 
3750
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
2526
3751
      {
2527
3752
        Item **argp= ((Item_sum*) item)->args + i;
2528
3753
        Item *arg= *argp;
2529
3754
        if (!arg->const_item())
2530
3755
        {
2531
3756
          Field *new_field=
2532
 
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
 
3757
            create_tmp_field(thd, table, arg, arg->type(), &copy_func,
2533
3758
                             tmp_from_field, &default_field[fieldnr],
2534
3759
                             group != 0,not_all_columns,
2535
 
                             false,
 
3760
                             distinct, 0,
2536
3761
                             param->convert_blob_length);
2537
3762
          if (!new_field)
2538
3763
            goto err;                                   // Should be OOM
2549
3774
            string_count++;
2550
3775
            string_total_length+= new_field->pack_length();
2551
3776
          }
2552
 
          session->mem_root= mem_root_save;
2553
 
          session->change_item_tree(argp, new Item_field(new_field));
2554
 
          session->mem_root= &table->mem_root;
 
3777
          thd->mem_root= mem_root_save;
 
3778
          thd->change_item_tree(argp, new Item_field(new_field));
 
3779
          thd->mem_root= &table->mem_root;
2555
3780
          if (!(new_field->flags & NOT_NULL_FLAG))
2556
3781
          {
2557
3782
            null_count++;
2577
3802
        We here distinguish between UNION and multi-table-updates by the fact
2578
3803
        that in the later case group is set to the row pointer.
2579
3804
      */
2580
 
      Field *new_field=
2581
 
        create_tmp_field(session, table, item, type, &copy_func,
 
3805
      Field *new_field= (param->schema_table) ?
 
3806
        create_tmp_field_for_schema(thd, item, table) :
 
3807
        create_tmp_field(thd, table, item, type, &copy_func,
2582
3808
                         tmp_from_field, &default_field[fieldnr],
2583
3809
                         group != 0,
2584
3810
                         !force_copy_fields &&
2585
 
                           (not_all_columns || group != 0),
 
3811
                           (not_all_columns || group !=0),
 
3812
                         /*
 
3813
                           If item->marker == 4 then we force create_tmp_field
 
3814
                           to create a 64-bit longs for BIT fields because HEAP
 
3815
                           tables can't index BIT fields directly. We do the same
 
3816
                           for distinct, as we want the distinct index to be
 
3817
                           usable in this case too.
 
3818
                         */
 
3819
                         item->marker == 4 || param->bit_fields_as_long,
2586
3820
                         force_copy_fields,
2587
3821
                         param->convert_blob_length);
2588
3822
 
2589
3823
      if (!new_field)
2590
3824
      {
2591
 
        if (session->is_fatal_error)
 
3825
        if (thd->is_fatal_error)
2592
3826
          goto err;                             // Got OOM
2593
3827
        continue;                               // Some kindf of const item
2594
3828
      }
2626
3860
      null_count= 0;
2627
3861
    }
2628
3862
  }
2629
 
  assert(fieldnr == (uint32_t) (reg_field - table->field));
2630
 
  assert(field_count >= (uint32_t) (reg_field - table->field));
 
3863
  assert(fieldnr == (uint) (reg_field - table->field));
 
3864
  assert(field_count >= (uint) (reg_field - table->field));
2631
3865
  field_count= fieldnr;
2632
3866
  *reg_field= 0;
2633
3867
  *blob_field= 0;                               // End marker
2636
3870
  /* If result table is small; use a heap */
2637
3871
  /* future: storage engine selection can be made dynamic? */
2638
3872
  if (blob_count || using_unique_constraint ||
2639
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == OPTION_BIG_TABLES)
 
3873
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
 
3874
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
2640
3875
  {
2641
 
    share->storage_engine= myisam_engine;
2642
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
3876
    share->db_plugin= ha_lock_engine(0, myisam_hton);
 
3877
    table->file= get_new_handler(share, &table->mem_root,
 
3878
                                 share->db_type());
2643
3879
    if (group &&
2644
 
        (param->group_parts > table->cursor->getEngine()->max_key_parts() ||
2645
 
         param->group_length > table->cursor->getEngine()->max_key_length()))
2646
 
      using_unique_constraint= true;
 
3880
        (param->group_parts > table->file->max_key_parts() ||
 
3881
         param->group_length > table->file->max_key_length()))
 
3882
      using_unique_constraint=1;
2647
3883
  }
2648
3884
  else
2649
3885
  {
2650
 
    share->storage_engine= heap_engine;
2651
 
    table->cursor= share->db_type()->getCursor(*share, &table->mem_root);
 
3886
    share->db_plugin= ha_lock_engine(0, heap_hton);
 
3887
    table->file= get_new_handler(share, &table->mem_root,
 
3888
                                 share->db_type());
2652
3889
  }
2653
 
  if (! table->cursor)
 
3890
  if (!table->file)
2654
3891
    goto err;
2655
3892
 
2656
3893
 
2657
 
  if (! using_unique_constraint)
 
3894
  if (!using_unique_constraint)
2658
3895
    reclength+= group_null_items;       // null flag is stored separately
2659
3896
 
2660
3897
  share->blob_fields= blob_count;
2686
3923
    table->record[1]= table->record[0]+alloc_length;
2687
3924
    share->default_values= table->record[1]+alloc_length;
2688
3925
  }
2689
 
  copy_func[0]= 0;                              // End marker
2690
 
  param->func_count= copy_func - param->items_to_copy;
 
3926
  copy_func[0]=0;                               // End marker
 
3927
  param->func_count= copy_func - param->items_to_copy; 
2691
3928
 
2692
3929
  table->setup_tmp_table_column_bitmaps(bitmaps);
2693
3930
 
2708
3945
  }
2709
3946
  null_count= (blob_count == 0) ? 1 : 0;
2710
3947
  hidden_field_count=param->hidden_field_count;
2711
 
  for (i= 0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
 
3948
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
2712
3949
  {
2713
3950
    Field *field= *reg_field;
2714
3951
    uint32_t length;
2722
3959
          We have to reserve one byte here for NULL bits,
2723
3960
          as this is updated by 'end_update()'
2724
3961
        */
2725
 
        *pos++= '\0';                           // Null is stored here
2726
 
        recinfo->length= 1;
 
3962
        *pos++=0;                               // Null is stored here
 
3963
        recinfo->length=1;
2727
3964
        recinfo->type=FIELD_NORMAL;
2728
3965
        recinfo++;
2729
3966
        memset(recinfo, 0, sizeof(*recinfo));
2747
3984
    */
2748
3985
    if (default_field[i] && default_field[i]->ptr)
2749
3986
    {
2750
 
      /*
 
3987
      /* 
2751
3988
         default_field[i] is set only in the cases  when 'field' can
2752
3989
         inherit the default value that is defined for the field referred
2753
3990
         by the Item_field object from which 'field' has been created.
2754
3991
      */
2755
 
      ptrdiff_t diff;
 
3992
      my_ptrdiff_t diff;
2756
3993
      Field *orig_field= default_field[i];
2757
3994
      /* Get the value from default_values */
2758
 
      diff= (ptrdiff_t) (orig_field->table->s->default_values-
 
3995
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
2759
3996
                            orig_field->table->record[0]);
2760
3997
      orig_field->move_field_offset(diff);      // Points now at default_values
2761
3998
      if (orig_field->is_real_null())
2766
4003
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
2767
4004
      }
2768
4005
      orig_field->move_field_offset(-diff);     // Back to record[0]
2769
 
    }
 
4006
    } 
2770
4007
 
2771
4008
    if (from_field[i])
2772
4009
    {                                           /* Not a table Item */
2791
4028
 
2792
4029
  param->copy_field_end=copy;
2793
4030
  param->recinfo=recinfo;
2794
 
  table->storeRecordAsDefault();        // Make empty default record
 
4031
  store_record(table,s->default_values);        // Make empty default record
2795
4032
 
2796
 
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)              // No limit
2797
 
    max_rows= ~(uint64_t) 0;
 
4033
  if (thd->variables.tmp_table_size == ~ (uint64_t) 0)          // No limit
 
4034
    share->max_rows= ~(ha_rows) 0;
2798
4035
  else
2799
 
    max_rows= (uint64_t) (((share->db_type() == heap_engine) ?
2800
 
                          min(session->variables.tmp_table_size,
2801
 
                              session->variables.max_heap_table_size) :
2802
 
                          session->variables.tmp_table_size) /
2803
 
                         share->reclength);
2804
 
 
2805
 
  set_if_bigger(max_rows, (uint64_t)1); // For dummy start options
 
4036
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
 
4037
                                 cmin(thd->variables.tmp_table_size,
 
4038
                                     thd->variables.max_heap_table_size) :
 
4039
                                 thd->variables.tmp_table_size) /
 
4040
                                 share->reclength);
 
4041
  set_if_bigger(share->max_rows,1);             // For dummy start options
2806
4042
  /*
2807
4043
    Push the LIMIT clause to the temporary table creation, so that we
2808
4044
    materialize only up to 'rows_limit' records instead of all result records.
2809
4045
  */
2810
 
  set_if_smaller(max_rows, rows_limit);
2811
 
 
2812
 
  share->setMaxRows(max_rows);
2813
 
 
 
4046
  set_if_smaller(share->max_rows, rows_limit);
2814
4047
  param->end_write_records= rows_limit;
2815
4048
 
2816
4049
  keyinfo= param->keyinfo;
2825
4058
    keyinfo->key_part=key_part_info;
2826
4059
    keyinfo->flags=HA_NOSAME;
2827
4060
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
2828
 
    keyinfo->key_length= 0;
2829
 
    keyinfo->rec_per_key= 0;
 
4061
    keyinfo->key_length=0;
 
4062
    keyinfo->rec_per_key=0;
2830
4063
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
2831
4064
    keyinfo->name= (char*) "group_key";
2832
4065
    order_st *cur_group= group;
2834
4067
    {
2835
4068
      Field *field=(*cur_group->item)->get_tmp_table_field();
2836
4069
      bool maybe_null=(*cur_group->item)->maybe_null;
2837
 
      key_part_info->null_bit= 0;
 
4070
      key_part_info->null_bit=0;
2838
4071
      key_part_info->field=  field;
2839
4072
      key_part_info->offset= field->offset(table->record[0]);
2840
4073
      key_part_info->length= (uint16_t) field->key_length();
2841
4074
      key_part_info->type=   (uint8_t) field->key_type();
2842
 
      key_part_info->key_type= 
 
4075
      key_part_info->key_type =
2843
4076
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2844
4077
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2845
4078
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2846
 
        0 : 1;
 
4079
        0 : FIELDFLAG_BINARY;
2847
4080
      if (!using_unique_constraint)
2848
4081
      {
2849
4082
        cur_group->buff=(char*) group_buff;
2850
 
        if (!(cur_group->field= field->new_key_field(session->mem_root,table,
 
4083
        if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
2851
4084
                                                     group_buff +
2852
4085
                                                     test(maybe_null),
2853
4086
                                                     field->null_ptr,
2854
4087
                                                     field->null_bit)))
2855
 
          goto err;
 
4088
          goto err; /* purecov: inspected */
2856
4089
        if (maybe_null)
2857
4090
        {
2858
4091
          /*
2863
4096
          */
2864
4097
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
2865
4098
          key_part_info->null_bit=field->null_bit;
2866
 
          key_part_info->null_offset= (uint32_t) (field->null_ptr -
 
4099
          key_part_info->null_offset= (uint) (field->null_ptr -
2867
4100
                                              (unsigned char*) table->record[0]);
2868
4101
          cur_group->buff++;                        // Pointer to field data
2869
4102
          group_buff++;                         // Skipp null flag
2909
4142
    keyinfo->key_length=(uint16_t) reclength;
2910
4143
    keyinfo->name= (char*) "distinct_key";
2911
4144
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
2912
 
    keyinfo->rec_per_key= 0;
 
4145
    keyinfo->rec_per_key=0;
2913
4146
 
2914
4147
    /*
2915
4148
      Create an extra field to hold NULL bits so that unique indexes on
2918
4151
    */
2919
4152
    if (null_pack_length && share->uniques)
2920
4153
    {
2921
 
      key_part_info->null_bit= 0;
 
4154
      key_part_info->null_bit=0;
2922
4155
      key_part_info->offset=hidden_null_pack_length;
2923
4156
      key_part_info->length=null_pack_length;
2924
4157
      key_part_info->field= new Field_varstring(table->record[0],
2925
4158
                                                (uint32_t) key_part_info->length,
2926
4159
                                                0,
2927
4160
                                                (unsigned char*) 0,
2928
 
                                                (uint32_t) 0,
2929
 
                                                NULL,
 
4161
                                                (uint) 0,
 
4162
                                                Field::NONE,
 
4163
                                                NULL, 
2930
4164
                                                table->s,
2931
4165
                                                &my_charset_bin);
2932
4166
      if (!key_part_info->field)
2933
4167
        goto err;
2934
4168
      key_part_info->field->init(table);
2935
 
      key_part_info->key_type= 1; /* binary comparison */
 
4169
      key_part_info->key_type=FIELDFLAG_BINARY;
2936
4170
      key_part_info->type=    HA_KEYTYPE_BINARY;
2937
4171
      key_part_info++;
2938
4172
    }
2941
4175
         i < field_count;
2942
4176
         i++, reg_field++, key_part_info++)
2943
4177
    {
2944
 
      key_part_info->null_bit= 0;
 
4178
      key_part_info->null_bit=0;
2945
4179
      key_part_info->field=    *reg_field;
2946
4180
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
2947
4181
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
2948
4182
      /* TODO:
2949
4183
        The below method of computing the key format length of the
2950
 
        key part is a copy/paste from optimizer/range.cc, and table.cc.
 
4184
        key part is a copy/paste from opt_range.cc, and table.cc.
2951
4185
        This should be factored out, e.g. as a method of Field.
2952
4186
        In addition it is not clear if any of the Field::*_length
2953
4187
        methods is supposed to compute the same length. If so, it
2957
4191
 
2958
4192
      if ((*reg_field)->real_maybe_null())
2959
4193
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
2960
 
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB ||
 
4194
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB || 
2961
4195
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
2962
4196
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
2963
4197
 
2966
4200
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2967
4201
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2968
4202
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2969
 
        0 : 1;
 
4203
        0 : FIELDFLAG_BINARY;
2970
4204
    }
2971
4205
  }
2972
4206
 
2973
 
  if (session->is_fatal_error)                          // If end of memory
2974
 
    goto err;
 
4207
  if (thd->is_fatal_error)                              // If end of memory
 
4208
    goto err;                                    /* purecov: inspected */
2975
4209
  share->db_record_offset= 1;
2976
 
  if (share->db_type() == myisam_engine)
 
4210
  if (share->db_type() == myisam_hton)
2977
4211
  {
2978
4212
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
2979
4213
                                       &param->recinfo, select_options))
2982
4216
  if (table->open_tmp_table())
2983
4217
    goto err;
2984
4218
 
2985
 
  session->mem_root= mem_root_save;
 
4219
  thd->mem_root= mem_root_save;
2986
4220
 
2987
4221
  return(table);
2988
4222
 
2989
4223
err:
2990
 
  session->mem_root= mem_root_save;
2991
 
  table->free_tmp_table(session);
2992
 
  return NULL;
 
4224
  thd->mem_root= mem_root_save;
 
4225
  table->free_tmp_table(thd);                    /* purecov: inspected */
 
4226
  if (temp_pool_slot != MY_BIT_NONE)
 
4227
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
4228
  return(NULL);                         /* purecov: inspected */
2993
4229
}
2994
4230
 
2995
4231
/****************************************************************************/
2998
4234
  Create a reduced Table object with properly set up Field list from a
2999
4235
  list of field definitions.
3000
4236
 
3001
 
    The created table doesn't have a table Cursor associated with
 
4237
    The created table doesn't have a table handler associated with
3002
4238
    it, has no keys, no group/distinct, no copy_funcs array.
3003
4239
    The sole purpose of this Table object is to use the power of Field
3004
4240
    class to read/write data to/from table->record[0]. Then one can store
3005
4241
    the record in any container (RB tree, hash, etc).
3006
 
    The table is created in Session mem_root, so are the table's fields.
 
4242
    The table is created in THD mem_root, so are the table's fields.
3007
4243
    Consequently, if you don't BLOB fields, you don't need to free it.
3008
4244
 
3009
 
  @param session         connection handle
 
4245
  @param thd         connection handle
3010
4246
  @param field_list  list of column definitions
3011
4247
 
3012
4248
  @return
3013
4249
    0 if out of memory, Table object in case of success
3014
4250
*/
3015
4251
 
3016
 
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
 
4252
Table *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
3017
4253
{
3018
4254
  uint32_t field_count= field_list.elements;
3019
4255
  uint32_t blob_count= 0;
3020
4256
  Field **field;
3021
 
  CreateField *cdef;                           /* column definition */
 
4257
  Create_field *cdef;                           /* column definition */
3022
4258
  uint32_t record_length= 0;
3023
4259
  uint32_t null_count= 0;                 /* number of columns which may be null */
3024
4260
  uint32_t null_pack_length;              /* NULL representation array length */
3025
4261
  uint32_t *blob_field;
3026
4262
  unsigned char *bitmaps;
3027
4263
  Table *table;
3028
 
  TableShare *share;
 
4264
  TABLE_SHARE *share;
3029
4265
 
3030
 
  if (!multi_alloc_root(session->mem_root,
 
4266
  if (!multi_alloc_root(thd->mem_root,
3031
4267
                        &table, sizeof(*table),
3032
4268
                        &share, sizeof(*share),
3033
4269
                        &field, (field_count + 1) * sizeof(Field*),
3034
 
                        &blob_field, (field_count+1) *sizeof(uint32_t),
 
4270
                        &blob_field, (field_count+1) *sizeof(uint),
3035
4271
                        &bitmaps, bitmap_buffer_size(field_count)*2,
3036
4272
                        NULL))
3037
 
    return NULL;
 
4273
    return 0;
3038
4274
 
3039
4275
  memset(table, 0, sizeof(*table));
3040
4276
  memset(share, 0, sizeof(*share));
3046
4282
  table->setup_tmp_table_column_bitmaps(bitmaps);
3047
4283
 
3048
4284
  /* Create all fields and calculate the total length of record */
3049
 
  List_iterator_fast<CreateField> it(field_list);
 
4285
  List_iterator_fast<Create_field> it(field_list);
3050
4286
  while ((cdef= it++))
3051
4287
  {
3052
 
    *field= make_field(share,
3053
 
                       NULL,
3054
 
                       0,
3055
 
                       cdef->length,
3056
 
                       (cdef->flags & NOT_NULL_FLAG) ? false : true,
3057
 
                       (unsigned char *) ((cdef->flags & NOT_NULL_FLAG) ? 0 : ""),
3058
 
                       (cdef->flags & NOT_NULL_FLAG) ? 0 : 1,
3059
 
                       cdef->decimals,
3060
 
                       cdef->sql_type,
3061
 
                       cdef->charset,
 
4288
    *field= make_field(share, 0, cdef->length,
 
4289
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
 
4290
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
 
4291
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
3062
4292
                       cdef->unireg_check,
3063
 
                       cdef->interval,
3064
 
                       cdef->field_name);
 
4293
                       cdef->interval, cdef->field_name);
3065
4294
    if (!*field)
3066
4295
      goto error;
3067
4296
    (*field)->init(table);
3070
4299
      null_count++;
3071
4300
 
3072
4301
    if ((*field)->flags & BLOB_FLAG)
3073
 
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
 
4302
      share->blob_field[blob_count++]= (uint) (field - table->field);
3074
4303
 
3075
4304
    field++;
3076
4305
  }
3081
4310
  null_pack_length= (null_count + 7)/8;
3082
4311
  share->reclength= record_length + null_pack_length;
3083
4312
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
3084
 
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
 
4313
  table->record[0]= (unsigned char*) thd->alloc(share->rec_buff_length);
3085
4314
  if (!table->record[0])
3086
4315
    goto error;
3087
4316
 
3092
4321
    share->null_bytes= null_pack_length;
3093
4322
  }
3094
4323
 
3095
 
  table->in_use= session;           /* field->reset() may access table->in_use */
 
4324
  table->in_use= thd;           /* field->reset() may access table->in_use */
3096
4325
  {
3097
4326
    /* Set up field pointers */
3098
4327
    unsigned char *null_pos= table->record[0];
3126
4355
  return 0;
3127
4356
}
3128
4357
 
 
4358
 
3129
4359
bool Table::open_tmp_table()
3130
4360
{
3131
4361
  int error;
3132
 
  if ((error=cursor->ha_open(this, s->table_name.str,O_RDWR,
 
4362
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
3133
4363
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3134
4364
  {
3135
 
    print_error(error, MYF(0));
3136
 
    db_stat= 0;
3137
 
    return true;
 
4365
    file->print_error(error,MYF(0)); /* purecov: inspected */
 
4366
    db_stat=0;
 
4367
    return(1);
3138
4368
  }
3139
 
  (void) cursor->extra(HA_EXTRA_QUICK);         /* Faster */
3140
 
  return false;
 
4369
  (void) file->extra(HA_EXTRA_QUICK);           /* Faster */
 
4370
  return(0);
3141
4371
}
3142
4372
 
3143
4373
 
3150
4380
      start_recinfo   MyISAM's column descriptions
3151
4381
      recinfo INOUT   End of MyISAM's column descriptions
3152
4382
      options         Option bits
3153
 
 
 
4383
   
3154
4384
  DESCRIPTION
3155
4385
    Create a MyISAM temporary table according to passed description. The is
3156
4386
    assumed to have one unique index or constraint.
3161
4391
         when there are many nullable columns)
3162
4392
      2. Table columns
3163
4393
      3. One free MI_COLUMNDEF element (*recinfo points here)
3164
 
 
 
4394
   
3165
4395
    This function may use the free element to create hash column for unique
3166
4396
    constraint.
3167
4397
 
3170
4400
     true  - Error
3171
4401
*/
3172
4402
 
3173
 
bool Table::create_myisam_tmp_table(KEY *keyinfo,
 
4403
bool Table::create_myisam_tmp_table(KEY *keyinfo, 
3174
4404
                                    MI_COLUMNDEF *start_recinfo,
3175
 
                                    MI_COLUMNDEF **recinfo,
 
4405
                                    MI_COLUMNDEF **recinfo, 
3176
4406
                                    uint64_t options)
3177
4407
{
3178
4408
  int error;
3179
4409
  MI_KEYDEF keydef;
3180
4410
  MI_UNIQUEDEF uniquedef;
3181
 
  TableShare *share= s;
 
4411
  TABLE_SHARE *share= s;
3182
4412
 
3183
4413
  if (share->keys)
3184
4414
  {                                             // Get keys for ni_create
3185
 
    bool using_unique_constraint= false;
 
4415
    bool using_unique_constraint=0;
3186
4416
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3187
4417
                                            sizeof(*seg) * keyinfo->key_parts);
3188
4418
    if (!seg)
3189
4419
      goto err;
3190
4420
 
3191
4421
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
3192
 
    if (keyinfo->key_length >= cursor->getEngine()->max_key_length() ||
3193
 
        keyinfo->key_parts > cursor->getEngine()->max_key_parts() ||
 
4422
    if (keyinfo->key_length >= file->max_key_length() ||
 
4423
        keyinfo->key_parts > file->max_key_parts() ||
3194
4424
        share->uniques)
3195
4425
    {
3196
4426
      /* Can't create a key; Make a unique constraint instead of a key */
3197
4427
      share->keys=    0;
3198
4428
      share->uniques= 1;
3199
 
      using_unique_constraint= true;
 
4429
      using_unique_constraint=1;
3200
4430
      memset(&uniquedef, 0, sizeof(uniquedef));
3201
4431
      uniquedef.keysegs=keyinfo->key_parts;
3202
4432
      uniquedef.seg=seg;
3217
4447
      keydef.keysegs=  keyinfo->key_parts;
3218
4448
      keydef.seg= seg;
3219
4449
    }
3220
 
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
 
4450
    for (uint32_t i=0; i < keyinfo->key_parts ; i++,seg++)
3221
4451
    {
3222
 
      Field *key_field=keyinfo->key_part[i].field;
 
4452
      Field *field=keyinfo->key_part[i].field;
3223
4453
      seg->flag=     0;
3224
 
      seg->language= key_field->charset()->number;
 
4454
      seg->language= field->charset()->number;
3225
4455
      seg->length=   keyinfo->key_part[i].length;
3226
4456
      seg->start=    keyinfo->key_part[i].offset;
3227
 
      if (key_field->flags & BLOB_FLAG)
 
4457
      if (field->flags & BLOB_FLAG)
3228
4458
      {
3229
 
        seg->type= ((keyinfo->key_part[i].key_type & 1 /* binary */) ?
 
4459
        seg->type=
 
4460
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
3230
4461
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
3231
 
        seg->bit_start= (uint8_t)(key_field->pack_length()
3232
 
                                  - share->blob_ptr_size);
 
4462
        seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
3233
4463
        seg->flag= HA_BLOB_PART;
3234
 
        seg->length= 0;                 // Whole blob in unique constraint
 
4464
        seg->length=0;                  // Whole blob in unique constraint
3235
4465
      }
3236
4466
      else
3237
4467
      {
3238
4468
        seg->type= keyinfo->key_part[i].type;
3239
4469
      }
3240
 
      if (!(key_field->flags & NOT_NULL_FLAG))
 
4470
      if (!(field->flags & NOT_NULL_FLAG))
3241
4471
      {
3242
 
        seg->null_bit= key_field->null_bit;
3243
 
        seg->null_pos= (uint32_t) (key_field->null_ptr - (unsigned char*) record[0]);
 
4472
        seg->null_bit= field->null_bit;
 
4473
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) record[0]);
3244
4474
        /*
3245
4475
          We are using a GROUP BY on something that contains NULL
3246
4476
          In this case we have to tell MyISAM that two NULL should
3247
4477
          on INSERT be regarded at the same value
3248
4478
        */
3249
 
        if (! using_unique_constraint)
 
4479
        if (!using_unique_constraint)
3250
4480
          keydef.flag|= HA_NULL_ARE_EQUAL;
3251
4481
      }
3252
4482
    }
3259
4489
    create_info.data_file_length= ~(uint64_t) 0;
3260
4490
 
3261
4491
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
3262
 
                       (uint32_t) (*recinfo-start_recinfo),
 
4492
                       (uint) (*recinfo-start_recinfo),
3263
4493
                       start_recinfo,
3264
4494
                       share->uniques, &uniquedef,
3265
4495
                       &create_info,
3266
4496
                       HA_CREATE_TMP_TABLE)))
3267
4497
  {
3268
 
    print_error(error, MYF(0));
3269
 
    db_stat= 0;
 
4498
    file->print_error(error,MYF(0));    /* purecov: inspected */
 
4499
    db_stat=0;
3270
4500
    goto err;
3271
4501
  }
3272
4502
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
3277
4507
}
3278
4508
 
3279
4509
 
3280
 
void Table::free_tmp_table(Session *session)
 
4510
void Table::free_tmp_table(THD *thd)
3281
4511
{
3282
 
  memory::Root own_root= mem_root;
 
4512
  MEM_ROOT own_root= mem_root;
3283
4513
  const char *save_proc_info;
3284
4514
 
3285
 
  save_proc_info=session->get_proc_info();
3286
 
  session->set_proc_info("removing tmp table");
3287
 
 
3288
 
  // Release latches since this can take a long time
3289
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
3290
 
 
3291
 
  if (cursor)
 
4515
  save_proc_info=thd->get_proc_info();
 
4516
  thd_proc_info(thd, "removing tmp table");
 
4517
 
 
4518
  if (file)
3292
4519
  {
3293
4520
    if (db_stat)
3294
 
      cursor->closeMarkForDelete(s->table_name.str);
3295
 
 
3296
 
    TableIdentifier identifier(s->getSchemaName(), s->table_name.str, s->table_name.str);
3297
 
    s->db_type()->doDropTable(*session, identifier);
3298
 
 
3299
 
    delete cursor;
 
4521
      file->ha_drop_table(s->table_name.str);
 
4522
    else
 
4523
      file->ha_delete_table(s->table_name.str);
 
4524
    delete file;
3300
4525
  }
3301
4526
 
3302
4527
  /* free blobs */
3303
4528
  for (Field **ptr= field ; *ptr ; ptr++)
3304
4529
    (*ptr)->free();
3305
 
  free_io_cache();
 
4530
  free_io_cache(this);
 
4531
 
 
4532
  if (temp_pool_slot != MY_BIT_NONE)
 
4533
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
 
4534
 
 
4535
  plugin_unlock(0, s->db_plugin);
3306
4536
 
3307
4537
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
3308
 
  session->set_proc_info(save_proc_info);
 
4538
  thd_proc_info(thd, save_proc_info);
 
4539
 
 
4540
  return;
3309
4541
}
3310
4542
 
3311
4543
/**
3313
4545
  to this.
3314
4546
*/
3315
4547
 
3316
 
bool create_myisam_from_heap(Session *session, Table *table,
 
4548
bool create_myisam_from_heap(THD *thd, Table *table,
3317
4549
                             MI_COLUMNDEF *start_recinfo,
3318
 
                             MI_COLUMNDEF **recinfo,
 
4550
                             MI_COLUMNDEF **recinfo, 
3319
4551
                             int error, bool ignore_last_dupp_key_error)
3320
4552
{
3321
4553
  Table new_table;
3322
 
  TableShare share;
 
4554
  TABLE_SHARE share;
3323
4555
  const char *save_proc_info;
3324
4556
  int write_err;
3325
4557
 
3326
 
  if (table->s->db_type() != heap_engine ||
 
4558
  if (table->s->db_type() != heap_hton || 
3327
4559
      error != HA_ERR_RECORD_FILE_FULL)
3328
4560
  {
3329
 
    table->print_error(error, MYF(0));
3330
 
    return true;
 
4561
    table->file->print_error(error,MYF(0));
 
4562
    return(1);
3331
4563
  }
3332
 
 
3333
 
  // Release latches since this can take a long time
3334
 
  plugin::TransactionalStorageEngine::releaseTemporaryLatches(session);
3335
 
 
3336
4564
  new_table= *table;
3337
4565
  share= *table->s;
3338
4566
  new_table.s= &share;
3339
 
  new_table.s->storage_engine= myisam_engine;
3340
 
  if (not (new_table.cursor= new_table.s->db_type()->getCursor(share, &new_table.mem_root)))
3341
 
    return true;                                // End of memory
 
4567
  new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
 
4568
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
 
4569
                                        new_table.s->db_type())))
 
4570
    return(1);                          // End of memory
3342
4571
 
3343
 
  save_proc_info=session->get_proc_info();
3344
 
  session->set_proc_info("converting HEAP to MyISAM");
 
4572
  save_proc_info=thd->get_proc_info();
 
4573
  thd_proc_info(thd, "converting HEAP to MyISAM");
3345
4574
 
3346
4575
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
3347
 
                                        recinfo, session->lex->select_lex.options |
3348
 
                                        session->options))
 
4576
                                        recinfo, thd->lex->select_lex.options | 
 
4577
                                        thd->options))
3349
4578
    goto err2;
3350
4579
  if (new_table.open_tmp_table())
3351
4580
    goto err1;
3352
 
  if (table->cursor->indexes_are_disabled())
3353
 
    new_table.cursor->ha_disable_indexes(HA_KEY_SWITCH_ALL);
3354
 
  table->cursor->ha_index_or_rnd_end();
3355
 
  table->cursor->ha_rnd_init(1);
 
4581
  if (table->file->indexes_are_disabled())
 
4582
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
 
4583
  table->file->ha_index_or_rnd_end();
 
4584
  table->file->ha_rnd_init(1);
3356
4585
  if (table->no_rows)
3357
4586
  {
3358
 
    new_table.cursor->extra(HA_EXTRA_NO_ROWS);
 
4587
    new_table.file->extra(HA_EXTRA_NO_ROWS);
3359
4588
    new_table.no_rows=1;
3360
4589
  }
3361
4590
 
 
4591
#ifdef TO_BE_DONE_LATER_IN_4_1
 
4592
  /*
 
4593
    To use start_bulk_insert() (which is new in 4.1) we need to find
 
4594
    all places where a corresponding end_bulk_insert() should be put.
 
4595
  */
 
4596
  table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
 
4597
  new_table.file->ha_start_bulk_insert(table->file->stats.records);
 
4598
#else
3362
4599
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3363
 
  new_table.cursor->extra(HA_EXTRA_WRITE_CACHE);
 
4600
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
 
4601
#endif
3364
4602
 
3365
4603
  /*
3366
4604
    copy all old rows from heap table to MyISAM table
3367
4605
    This is the only code that uses record[1] to read/write but this
3368
4606
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3369
4607
  */
3370
 
  while (!table->cursor->rnd_next(new_table.record[1]))
 
4608
  while (!table->file->rnd_next(new_table.record[1]))
3371
4609
  {
3372
 
    write_err= new_table.cursor->ha_write_row(new_table.record[1]);
 
4610
    write_err= new_table.file->ha_write_row(new_table.record[1]);
3373
4611
    if (write_err)
3374
4612
      goto err;
3375
4613
  }
3376
4614
  /* copy row that filled HEAP table */
3377
 
  if ((write_err=new_table.cursor->ha_write_row(table->record[0])))
 
4615
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
3378
4616
  {
3379
 
    if (new_table.cursor->is_fatal_error(write_err, HA_CHECK_DUP) ||
 
4617
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
3380
4618
        !ignore_last_dupp_key_error)
3381
4619
      goto err;
3382
4620
  }
3383
4621
 
3384
4622
  /* remove heap table and change to use myisam table */
3385
 
  (void) table->cursor->ha_rnd_end();
3386
 
  (void) table->cursor->close();                  // This deletes the table !
3387
 
  delete table->cursor;
3388
 
  table->cursor= NULL;
 
4623
  (void) table->file->ha_rnd_end();
 
4624
  (void) table->file->close();                  // This deletes the table !
 
4625
  delete table->file;
 
4626
  table->file=0;
 
4627
  plugin_unlock(0, table->s->db_plugin);
 
4628
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
3389
4629
  new_table.s= table->s;                       // Keep old share
3390
4630
  *table= new_table;
3391
4631
  *table->s= share;
3392
 
 
3393
 
  table->cursor->change_table_ptr(table, table->s);
 
4632
  
 
4633
  table->file->change_table_ptr(table, table->s);
3394
4634
  table->use_all_columns();
3395
4635
  if (save_proc_info)
3396
4636
  {
3397
4637
    const char *new_proc_info=
3398
4638
      (!strcmp(save_proc_info,"Copying to tmp table") ?
3399
4639
      "Copying to tmp table on disk" : save_proc_info);
3400
 
    session->set_proc_info(new_proc_info);
 
4640
    thd_proc_info(thd, new_proc_info);
3401
4641
  }
3402
 
  return false;
 
4642
  return(0);
3403
4643
 
3404
4644
 err:
3405
 
  table->print_error(write_err, MYF(0));
3406
 
  (void) table->cursor->ha_rnd_end();
3407
 
  (void) new_table.cursor->close();
3408
 
 
 
4645
  table->file->print_error(write_err, MYF(0));
 
4646
  (void) table->file->ha_rnd_end();
 
4647
  (void) new_table.file->close();
3409
4648
 err1:
3410
 
  {
3411
 
    TableIdentifier identifier(new_table.s->getSchemaName(), new_table.s->table_name.str, new_table.s->table_name.str);
3412
 
    new_table.s->db_type()->doDropTable(*session, identifier);
3413
 
  }
3414
 
 
 
4649
  new_table.file->ha_delete_table(new_table.s->table_name.str);
3415
4650
 err2:
3416
 
  delete new_table.cursor;
3417
 
  session->set_proc_info(save_proc_info);
 
4651
  delete new_table.file;
 
4652
  thd_proc_info(thd, save_proc_info);
3418
4653
  table->mem_root= new_table.mem_root;
3419
 
  return true;
 
4654
  return(1);
3420
4655
}
3421
4656
 
3422
 
my_bitmap_map *Table::use_all_columns(MyBitmap *bitmap)
 
4657
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
3423
4658
{
3424
 
  my_bitmap_map *old= bitmap->getBitmap();
3425
 
  bitmap->setBitmap(s->all_set.getBitmap());
 
4659
  my_bitmap_map *old= bitmap->bitmap;
 
4660
  bitmap->bitmap= s->all_set.bitmap;
3426
4661
  return old;
3427
4662
}
3428
4663
 
3429
4664
void Table::restore_column_map(my_bitmap_map *old)
3430
4665
{
3431
 
  read_set->setBitmap(old);
 
4666
  read_set->bitmap= old;
3432
4667
}
3433
4668
 
3434
4669
uint32_t Table::find_shortest_key(const key_map *usable_keys)
3435
4670
{
3436
4671
  uint32_t min_length= UINT32_MAX;
3437
4672
  uint32_t best= MAX_KEY;
3438
 
  if (usable_keys->any())
 
4673
  if (!usable_keys->is_clear_all())
3439
4674
  {
3440
 
    for (uint32_t nr= 0; nr < s->keys ; nr++)
 
4675
    for (uint32_t nr=0; nr < s->keys ; nr++)
3441
4676
    {
3442
 
      if (usable_keys->test(nr))
 
4677
      if (usable_keys->is_set(nr))
3443
4678
      {
3444
4679
        if (key_info[nr].key_length < min_length)
3445
4680
        {
3475
4710
bool Table::compare_record()
3476
4711
{
3477
4712
  if (s->blob_fields + s->varchar_fields == 0)
3478
 
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
3479
 
  
 
4713
    return cmp_record(this, record[1]);
3480
4714
  /* Compare null bits */
3481
 
  if (memcmp(null_flags, null_flags + s->rec_buff_length, s->null_bytes))
3482
 
    return true; /* Diff in NULL value */
3483
 
 
 
4715
  if (memcmp(null_flags,
 
4716
             null_flags + s->rec_buff_length,
 
4717
             s->null_bytes))
 
4718
    return true;                                // Diff in NULL value
3484
4719
  /* Compare updated fields */
3485
4720
  for (Field **ptr= field ; *ptr ; ptr++)
3486
4721
  {
3487
 
    if (isWriteSet((*ptr)->field_index) &&
 
4722
    if (bitmap_is_set(write_set, (*ptr)->field_index) &&
3488
4723
        (*ptr)->cmp_binary_offset(s->rec_buff_length))
3489
4724
      return true;
3490
4725
  }
3491
4726
  return false;
3492
4727
}
3493
4728
 
3494
 
/*
3495
 
 * Store a record from previous record into next
3496
 
 *
3497
 
 */
3498
 
void Table::storeRecord()
3499
 
{
3500
 
  memcpy(record[1], record[0], (size_t) s->reclength);
3501
 
}
3502
 
 
3503
 
/*
3504
 
 * Store a record as an insert
3505
 
 *
3506
 
 */
3507
 
void Table::storeRecordAsInsert()
3508
 
{
3509
 
  memcpy(insert_values, record[0], (size_t) s->reclength);
3510
 
}
3511
 
 
3512
 
/*
3513
 
 * Store a record with default values
3514
 
 *
3515
 
 */
3516
 
void Table::storeRecordAsDefault()
3517
 
{
3518
 
  memcpy(s->default_values, record[0], (size_t) s->reclength);
3519
 
}
3520
 
 
3521
 
/*
3522
 
 * Restore a record from previous record into next
3523
 
 *
3524
 
 */
3525
 
void Table::restoreRecord()
3526
 
{
3527
 
  memcpy(record[0], record[1], (size_t) s->reclength);
3528
 
}
3529
 
 
3530
 
/*
3531
 
 * Restore a record with default values
3532
 
 *
3533
 
 */
3534
 
void Table::restoreRecordAsDefault()
3535
 
{
3536
 
  memcpy(record[0], s->default_values, (size_t) s->reclength);
3537
 
}
3538
 
 
3539
 
/*
3540
 
 * Empty a record
3541
 
 *
3542
 
 */
3543
 
void Table::emptyRecord()
3544
 
{
3545
 
  restoreRecordAsDefault();
3546
 
  memset(null_flags, 255, s->null_bytes);
3547
 
}
3548
 
 
3549
 
Table::Table()
3550
 
  : s(NULL),
3551
 
    field(NULL),
3552
 
    cursor(NULL),
3553
 
    next(NULL),
3554
 
    prev(NULL),
3555
 
    read_set(NULL),
3556
 
    write_set(NULL),
3557
 
    tablenr(0),
3558
 
    db_stat(0),
3559
 
    in_use(NULL),
3560
 
    insert_values(NULL),
3561
 
    key_info(NULL),
3562
 
    next_number_field(NULL),
3563
 
    found_next_number_field(NULL),
3564
 
    timestamp_field(NULL),
3565
 
    pos_in_table_list(NULL),
3566
 
    group(NULL),
3567
 
    alias(NULL),
3568
 
    null_flags(NULL),
3569
 
    lock_position(0),
3570
 
    lock_data_start(0),
3571
 
    lock_count(0),
3572
 
    used_fields(0),
3573
 
    status(0),
3574
 
    derived_select_number(0),
3575
 
    current_lock(F_UNLCK),
3576
 
    copy_blobs(false),
3577
 
    maybe_null(false),
3578
 
    null_row(false),
3579
 
    force_index(false),
3580
 
    distinct(false),
3581
 
    const_table(false),
3582
 
    no_rows(false),
3583
 
    key_read(false),
3584
 
    no_keyread(false),
3585
 
    open_placeholder(false),
3586
 
    locked_by_name(false),
3587
 
    no_cache(false),
3588
 
    auto_increment_field_not_null(false),
3589
 
    alias_name_used(false),
3590
 
    query_id(0),
3591
 
    quick_condition_rows(0),
3592
 
    timestamp_field_type(TIMESTAMP_NO_AUTO_SET),
3593
 
    map(0)
3594
 
{
3595
 
  record[0]= (unsigned char *) 0;
3596
 
  record[1]= (unsigned char *) 0;
3597
 
 
3598
 
  covering_keys.reset();
3599
 
 
3600
 
  quick_keys.reset();
3601
 
  merge_keys.reset();
3602
 
 
3603
 
  keys_in_use_for_query.reset();
3604
 
  keys_in_use_for_group_by.reset();
3605
 
  keys_in_use_for_order_by.reset();
3606
 
 
3607
 
  memset(quick_rows, 0, sizeof(ha_rows) * MAX_KEY);
3608
 
  memset(const_key_parts, 0, sizeof(ha_rows) * MAX_KEY);
3609
 
 
3610
 
  memset(quick_key_parts, 0, sizeof(unsigned int) * MAX_KEY);
3611
 
  memset(quick_n_ranges, 0, sizeof(unsigned int) * MAX_KEY);
3612
 
 
3613
 
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
3614
 
  memset(&sort, 0, sizeof(filesort_info_st));
3615
 
}
 
4729
 
 
4730
 
 
4731
 
3616
4732
 
3617
4733
/*****************************************************************************
3618
4734
  The different ways to read a record
3619
4735
  Returns -1 if row was not found, 0 if row was found and 1 on errors
3620
4736
*****************************************************************************/
3621
4737
 
3622
 
/** Help function when we get some an error from the table Cursor. */
 
4738
/** Help function when we get some an error from the table handler. */
3623
4739
 
3624
4740
int Table::report_error(int error)
3625
4741
{
3633
4749
    print them to the .err log
3634
4750
  */
3635
4751
  if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
3636
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
 
4752
    sql_print_error(_("Got error %d when reading table '%s'"),
3637
4753
                    error, s->path.str);
3638
 
  print_error(error, MYF(0));
 
4754
  file->print_error(error,MYF(0));
3639
4755
 
3640
4756
  return 1;
3641
4757
}
3642
4758
 
3643
4759
 
3644
 
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
3645
 
{
3646
 
  used_fields= 0;
3647
 
  const_table= 0;
3648
 
  null_row= 0;
3649
 
  status= STATUS_NO_RECORD;
3650
 
  maybe_null= table_list->outer_join;
3651
 
  TableList *embedding= table_list->embedding;
3652
 
  while (!maybe_null && embedding)
3653
 
  {
3654
 
    maybe_null= embedding->outer_join;
3655
 
    embedding= embedding->embedding;
3656
 
  }
3657
 
  tablenr= table_number;
3658
 
  map= (table_map) 1 << table_number;
3659
 
  force_index= table_list->force_index;
3660
 
  covering_keys= s->keys_for_keyread;
3661
 
  merge_keys.reset();
3662
 
}
3663
 
 
3664
 
 
3665
 
/*
3666
 
  Used by ALTER Table when the table is a temporary one. It changes something
3667
 
  only if the ALTER contained a RENAME clause (otherwise, table_name is the old
3668
 
  name).
3669
 
  Prepares a table cache key, which is the concatenation of db, table_name and
3670
 
  session->slave_proxy_id, separated by '\0'.
3671
 
*/
3672
 
 
3673
 
bool Table::renameAlterTemporaryTable(TableIdentifier &identifier)
3674
 
{
3675
 
  char *key;
3676
 
  uint32_t key_length;
3677
 
  TableShare *share= s;
3678
 
 
3679
 
  if (not (key=(char*) alloc_root(&share->mem_root, MAX_DBKEY_LENGTH)))
3680
 
    return true;
3681
 
 
3682
 
  key_length= TableShare::createKey(key, identifier);
3683
 
  share->set_table_cache_key(key, key_length);
3684
 
 
3685
 
  message::Table *message= share->getTableProto();
3686
 
 
3687
 
  message->set_name(identifier.getTableName());
3688
 
  message->set_schema(identifier.getSchemaName());
3689
 
 
3690
 
  return false;
3691
 
}
3692
 
 
3693
 
} /* namespace drizzled */
 
4760
/*****************************************************************************
 
4761
** Instansiate templates
 
4762
*****************************************************************************/
 
4763
 
 
4764
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 
4765
template class List<String>;
 
4766
template class List_iterator<String>;
 
4767
#endif