~drizzle-trunk/drizzle/development

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