~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/nested_join.h>
520.8.2 by Monty Taylor
Moved sql_parse.h and sql_error.h out of common_includes.
24
#include <drizzled/sql_parse.h>
584.4.7 by Monty Taylor
Removed a big bank of includes from item.h.
25
#include <drizzled/item/sum.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.
26
#include <drizzled/table_list.h>
27
#include <drizzled/session.h>
28
#include <drizzled/sql_base.h>
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
29
#include <drizzled/sql_select.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
30
#include <drizzled/field/blob.h>
31
#include <drizzled/field/varstring.h>
32
#include <drizzled/field/double.h>
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
33
#include <drizzled/unireg.h>
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
34
#include <drizzled/message/table.pb.h>
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
35
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
36
#include <drizzled/item/string.h>
37
#include <drizzled/item/int.h>
38
#include <drizzled/item/decimal.h>
39
#include <drizzled/item/float.h>
40
#include <drizzled/item/null.h>
982.1.11 by Padraig O'Sullivan
Reverted my changes for replacing Bitmap<> for the moment. Going to fix up
41
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
42
#include <string>
43
#include <vector>
44
#include <algorithm>
45
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
46
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
47
using namespace std;
48
1 by brian
clean slate
49
/* Functions defined in this file */
50
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
51
void open_table_error(TableShare *share, int error, int db_errno,
1 by brian
clean slate
52
                      myf errortype, int errarg);
53
54
/*************************************************************************/
55
56
/* Get column name from column hash */
57
575.1.2 by Monty Taylor
Changed a bunch of __attribute__((unused)) to removing the parameter name instead.
58
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
1 by brian
clean slate
59
{
895 by Brian Aker
Completion (?) of uint conversion.
60
  *length= (uint32_t) strlen((*buff)->field_name);
481 by Brian Aker
Remove all of uchar.
61
  return (unsigned char*) (*buff)->field_name;
1 by brian
clean slate
62
}
63
64
65
/*
66
  Returns pointer to '.frm' extension of the file name.
67
68
  SYNOPSIS
69
    fn_rext()
70
    name       file name
71
72
  DESCRIPTION
73
    Checks file name part starting with the rightmost '.' character,
1039.1.16 by Brian Aker
A lot of little cleanups (most based off lcov)
74
    and returns it if it is equal to '.dfe'.
1 by brian
clean slate
75
76
  TODO
77
    It is a good idea to get rid of this function modifying the code
78
    to garantee that the functions presently calling fn_rext() always
79
    get arguments in the same format: either with '.frm' or without '.frm'.
80
81
  RETURN VALUES
82
    Pointer to the '.frm' extension. If there is no extension,
83
    or extension is not '.frm', pointer at the end of file name.
84
*/
85
86
char *fn_rext(char *name)
87
{
88
  char *res= strrchr(name, '.');
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
89
  if (res && !strcmp(res, ".dfe"))
1 by brian
clean slate
90
    return res;
91
  return name + strlen(name);
92
}
93
94
TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name)
95
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
96
  assert(db != NULL);
97
  assert(name != NULL);
1 by brian
clean slate
98
575.4.7 by Monty Taylor
More header cleanup.
99
  if ((db->length == INFORMATION_SCHEMA_NAME.length()) &&
1 by brian
clean slate
100
      (my_strcasecmp(system_charset_info,
575.4.7 by Monty Taylor
More header cleanup.
101
                    INFORMATION_SCHEMA_NAME.c_str(),
1 by brian
clean slate
102
                    db->str) == 0))
103
  {
104
    return TABLE_CATEGORY_INFORMATION;
105
  }
106
107
  return TABLE_CATEGORY_USER;
108
}
109
110
111
/*
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
112
  Allocate a setup TableShare structure
1 by brian
clean slate
113
114
  SYNOPSIS
115
    alloc_table_share()
327.2.4 by Brian Aker
Refactoring table.h
116
    TableList		Take database and table name from there
1 by brian
clean slate
117
    key			Table cache key (db \0 table_name \0...)
118
    key_length		Length of key
119
120
  RETURN
121
    0  Error (out of memory)
122
    #  Share
123
*/
124
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
125
TableShare *alloc_table_share(TableList *table_list, char *key,
482 by Brian Aker
Remove uint.
126
                               uint32_t key_length)
1 by brian
clean slate
127
{
128
  MEM_ROOT mem_root;
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
129
  TableShare *share;
1 by brian
clean slate
130
  char *key_buff, *path_buff;
131
  char path[FN_REFLEN];
482 by Brian Aker
Remove uint.
132
  uint32_t path_length;
1 by brian
clean slate
133
134
  path_length= build_table_filename(path, sizeof(path) - 1,
135
                                    table_list->db,
1039.1.6 by Brian Aker
Refactor for build_table_filename()
136
                                    table_list->table_name, false);
1 by brian
clean slate
137
  init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
138
  if (multi_alloc_root(&mem_root,
139
                       &share, sizeof(*share),
140
                       &key_buff, key_length,
141
                       &path_buff, path_length + 1,
142
                       NULL))
143
  {
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
144
    memset(share, 0, sizeof(*share));
1 by brian
clean slate
145
146
    share->set_table_cache_key(key_buff, key, key_length);
147
148
    share->path.str= path_buff;
149
    share->path.length= path_length;
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
150
    strcpy(share->path.str, path);
1 by brian
clean slate
151
    share->normalized_path.str=    share->path.str;
152
    share->normalized_path.length= path_length;
153
154
    share->version=       refresh_version;
155
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
156
    memcpy(&share->mem_root, &mem_root, sizeof(mem_root));
1 by brian
clean slate
157
    pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
158
    pthread_cond_init(&share->cond, NULL);
159
  }
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
160
  return(share);
1 by brian
clean slate
161
}
162
163
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
164
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
165
{
166
  enum_field_types field_type;
167
168
  switch(proto_field_type)
169
  {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
170
  case drizzled::message::Table::Field::TINYINT:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
171
    field_type= DRIZZLE_TYPE_TINY;
172
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
173
  case drizzled::message::Table::Field::INTEGER:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
174
    field_type= DRIZZLE_TYPE_LONG;
175
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
176
  case drizzled::message::Table::Field::DOUBLE:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
177
    field_type= DRIZZLE_TYPE_DOUBLE;
178
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
179
  case drizzled::message::Table::Field::TIMESTAMP:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
180
    field_type= DRIZZLE_TYPE_TIMESTAMP;
181
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
182
  case drizzled::message::Table::Field::BIGINT:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
183
    field_type= DRIZZLE_TYPE_LONGLONG;
184
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
185
  case drizzled::message::Table::Field::DATETIME:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
186
    field_type= DRIZZLE_TYPE_DATETIME;
187
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
188
  case drizzled::message::Table::Field::DATE:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
189
    field_type= DRIZZLE_TYPE_DATE;
190
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
191
  case drizzled::message::Table::Field::VARCHAR:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
192
    field_type= DRIZZLE_TYPE_VARCHAR;
193
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
194
  case drizzled::message::Table::Field::DECIMAL:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
195
    field_type= DRIZZLE_TYPE_NEWDECIMAL;
196
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
197
  case drizzled::message::Table::Field::ENUM:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
198
    field_type= DRIZZLE_TYPE_ENUM;
199
    break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
200
  case drizzled::message::Table::Field::BLOB:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
201
    field_type= DRIZZLE_TYPE_BLOB;
202
    break;
203
  default:
901 by Brian Aker
Merge of Mine, Jay's and Stewart's
204
    field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
899.1.1 by brian
Merge of Stewart + Jay's fix.
205
    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.
206
  }
207
208
  return field_type;
209
}
210
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
211
static Item *default_value_item(enum_field_types field_type,
212
	                        const CHARSET_INFO *charset,
213
                                bool default_null, const string *default_value,
214
                                const 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.
215
{
216
  Item *default_item= NULL;
217
  int error= 0;
218
1034.1.2 by Brian Aker
Correct if() style
219
  if (default_null)
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
220
  {
221
    return new Item_null();
222
  }
223
224
  switch(field_type)
225
  {
226
  case DRIZZLE_TYPE_TINY:
227
  case DRIZZLE_TYPE_LONG:
228
  case DRIZZLE_TYPE_LONGLONG:
910.4.11 by Stewart Smith
fix default value Item generation. (spotted on Solaris)
229
    default_item= new Item_int(default_value->c_str(),
230
			       (int64_t) my_strtoll10(default_value->c_str(),
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
231
						      NULL,
232
						      &error),
910.4.11 by Stewart Smith
fix default value Item generation. (spotted on Solaris)
233
			       default_value->length());
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
234
    break;
235
  case DRIZZLE_TYPE_DOUBLE:
910.4.11 by Stewart Smith
fix default value Item generation. (spotted on Solaris)
236
    default_item= new Item_float(default_value->c_str(),
237
				 default_value->length());
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
238
    break;
239
  case DRIZZLE_TYPE_NULL:
896.4.15 by Stewart Smith
should be assert, not creating Item_null as default null is set up before the type switch
240
    assert(false);
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
241
  case DRIZZLE_TYPE_TIMESTAMP:
242
  case DRIZZLE_TYPE_DATETIME:
243
  case DRIZZLE_TYPE_DATE:
1000.1.1 by Brian Aker
Remove dead table bits from old replication for ROW
244
    if (default_value->compare("NOW()") == 0)
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
245
      break;
246
  case DRIZZLE_TYPE_ENUM:
910.4.11 by Stewart Smith
fix default value Item generation. (spotted on Solaris)
247
    default_item= new Item_string(default_value->c_str(),
248
				  default_value->length(),
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
249
				  system_charset_info);
250
    break;
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
251
  case DRIZZLE_TYPE_VARCHAR:
252
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
1034.1.2 by Brian Aker
Correct if() style
253
    if (charset==&my_charset_bin)
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
254
    {
910.4.11 by Stewart Smith
fix default value Item generation. (spotted on Solaris)
255
      default_item= new Item_string(default_bin_value->c_str(),
256
				    default_bin_value->length(),
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
257
				    &my_charset_bin);
258
    }
259
    else
260
    {
910.4.11 by Stewart Smith
fix default value Item generation. (spotted on Solaris)
261
      default_item= new Item_string(default_value->c_str(),
262
				    default_value->length(),
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
263
				    system_charset_info);
264
    }
265
    break;
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
266
  case DRIZZLE_TYPE_NEWDECIMAL:
910.4.11 by Stewart Smith
fix default value Item generation. (spotted on Solaris)
267
    default_item= new Item_decimal(default_value->c_str(),
268
				   default_value->length(),
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
269
				   system_charset_info);
270
    break;
271
  }
272
273
  return default_item;
274
}
275
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
276
static int parse_table_proto(Session *session,
277
                             drizzled::message::Table &table,
278
                             TableShare *share)
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.
279
{
896.4.6 by Stewart Smith
move fixing auto_inc and blobs from FRM code path to table_proto code path
280
  int error= 0;
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
281
  handler *handler_file= NULL;
896.4.6 by Stewart Smith
move fixing auto_inc and blobs from FRM code path to table_proto code path
282
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.
283
  {
284
    LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
285
			      strlen(table.engine().name().c_str()) };
971.1.21 by Monty Taylor
Store StorageEngine in system variables, rather than storage engine plugin.
286
    share->storage_engine= ha_resolve_by_name(session, &engine_name);
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.
287
  }
288
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
289
  drizzled::message::Table::TableOptions table_options;
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.
290
1034.1.2 by Brian Aker
Correct if() style
291
  if (table.has_options())
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.
292
    table_options= table.options();
293
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
294
  uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
295
1034.1.2 by Brian Aker
Correct if() style
296
  if (table_options.has_pack_keys())
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
297
  {
1034.1.2 by Brian Aker
Correct if() style
298
    if (table_options.pack_keys())
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
299
      db_create_options|= HA_OPTION_PACK_KEYS;
300
    else
301
      db_create_options|= HA_OPTION_NO_PACK_KEYS;
302
  }
303
1034.1.2 by Brian Aker
Correct if() style
304
  if (table_options.pack_record())
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
305
    db_create_options|= HA_OPTION_PACK_RECORD;
306
1034.1.2 by Brian Aker
Correct if() style
307
  if (table_options.has_checksum())
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
308
  {
1034.1.2 by Brian Aker
Correct if() style
309
    if (table_options.checksum())
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
310
      db_create_options|= HA_OPTION_CHECKSUM;
311
    else
312
      db_create_options|= HA_OPTION_NO_CHECKSUM;
313
  }
314
1034.1.2 by Brian Aker
Correct if() style
315
  if (table_options.has_delay_key_write())
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
316
  {
1034.1.2 by Brian Aker
Correct if() style
317
    if (table_options.delay_key_write())
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
318
      db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
319
    else
320
      db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
321
  }
322
896.4.2 by Stewart Smith
db_create_option is silently truncated to 16bits in FRM write path.
323
  /* db_create_options was stored as 2 bytes in FRM
324
     Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
325
   */
326
  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
327
  share->db_options_in_use= share->db_create_options;
328
329
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.
330
  share->avg_row_length= table_options.has_avg_row_length() ?
331
    table_options.avg_row_length() : 0;
332
333
  share->page_checksum= table_options.has_page_checksum() ?
334
    (table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
335
    : HA_CHOICE_UNDEF;
336
337
  share->row_type= table_options.has_row_type() ?
338
    (enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
339
340
  share->block_size= table_options.has_block_size() ?
341
    table_options.block_size() : 0;
342
343
  share->table_charset= get_charset(table_options.has_collation_id()?
344
				    table_options.collation_id() : 0);
345
346
  if (!share->table_charset)
347
  {
348
    /* unknown charset in head[38] or pre-3.23 frm */
349
    if (use_mb(default_charset_info))
350
    {
351
      /* Warn that we may be changing the size of character columns */
352
      errmsg_printf(ERRMSG_LVL_WARN,
353
		    _("'%s' had no or invalid character set, "
354
		      "and default character set is multi-byte, "
355
		      "so character column sizes may have changed"),
356
		    share->path.str);
357
    }
358
    share->table_charset= default_charset_info;
359
  }
360
361
  share->db_record_offset= 1;
362
363
  share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
364
365
  share->db_low_byte_first= true;
366
367
  share->max_rows= table_options.has_max_rows() ?
368
    table_options.max_rows() : 0;
369
370
  share->min_rows= table_options.has_min_rows() ?
371
    table_options.min_rows() : 0;
372
373
  share->keys= table.indexes_size();
374
375
  share->key_parts= 0;
1046.1.6 by Brian Aker
Formatting/style cleanup.
376
  for (int indx= 0; indx < table.indexes_size(); indx++)
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.
377
    share->key_parts+= table.indexes(indx).index_part_size();
378
379
  share->key_info= (KEY*) alloc_root(&share->mem_root,
380
				     table.indexes_size() * sizeof(KEY)
381
				     +share->key_parts*sizeof(KEY_PART_INFO));
382
383
  KEY_PART_INFO *key_part;
384
385
  key_part= reinterpret_cast<KEY_PART_INFO*>
386
    (share->key_info+table.indexes_size());
387
388
389
  ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
390
					    sizeof(ulong*)*share->key_parts);
391
392
  share->keynames.count= table.indexes_size();
393
  share->keynames.name= NULL;
394
  share->keynames.type_names= (const char**)
395
    alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
396
397
  share->keynames.type_lengths= (unsigned int*)
398
    alloc_root(&share->mem_root,
399
	       sizeof(unsigned int) * (table.indexes_size()+1));
400
401
  share->keynames.type_names[share->keynames.count]= NULL;
402
  share->keynames.type_lengths[share->keynames.count]= 0;
403
404
  KEY* keyinfo= share->key_info;
1046.1.6 by Brian Aker
Formatting/style cleanup.
405
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
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
  {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
407
    drizzled::message::Table::Index indx= table.indexes(keynr);
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.
408
409
    keyinfo->table= 0;
410
    keyinfo->flags= 0;
411
1034.1.2 by Brian Aker
Correct if() style
412
    if (indx.is_unique())
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.
413
      keyinfo->flags|= HA_NOSAME;
414
1034.1.2 by Brian Aker
Correct if() style
415
    if (indx.has_options())
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.
416
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
417
      drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
1034.1.2 by Brian Aker
Correct if() style
418
      if (indx_options.pack_key())
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.
419
	keyinfo->flags|= HA_PACK_KEY;
420
1034.1.2 by Brian Aker
Correct if() style
421
      if (indx_options.var_length_key())
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.
422
	keyinfo->flags|= HA_VAR_LENGTH_PART;
423
1034.1.2 by Brian Aker
Correct if() style
424
      if (indx_options.null_part_key())
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.
425
	keyinfo->flags|= HA_NULL_PART_KEY;
426
1034.1.2 by Brian Aker
Correct if() style
427
      if (indx_options.binary_pack_key())
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.
428
	keyinfo->flags|= HA_BINARY_PACK_KEY;
429
1034.1.2 by Brian Aker
Correct if() style
430
      if (indx_options.has_partial_segments())
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.
431
	keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
432
1034.1.2 by Brian Aker
Correct if() style
433
      if (indx_options.auto_generated_key())
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.
434
	keyinfo->flags|= HA_GENERATED_KEY;
435
1034.1.2 by Brian Aker
Correct if() style
436
      if (indx_options.has_key_block_size())
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.
437
      {
438
	keyinfo->flags|= HA_USES_BLOCK_SIZE;
439
	keyinfo->block_size= indx_options.key_block_size();
440
      }
441
      else
442
      {
443
	keyinfo->block_size= 0;
444
      }
445
446
    }
447
448
    switch(indx.type())
449
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
450
    case drizzled::message::Table::Index::UNKNOWN_INDEX:
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.
451
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
452
      break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
453
    case drizzled::message::Table::Index::BTREE:
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.
454
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
455
      break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
456
    case drizzled::message::Table::Index::RTREE:
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.
457
      keyinfo->algorithm= HA_KEY_ALG_RTREE;
458
      break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
459
    case drizzled::message::Table::Index::HASH:
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.
460
      keyinfo->algorithm= HA_KEY_ALG_HASH;
461
      break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
462
    case drizzled::message::Table::Index::FULLTEXT:
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.
463
      keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
464
465
    default:
466
      /* TODO: suitable warning ? */
467
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
468
      break;
469
    }
470
471
    keyinfo->key_length= indx.key_length();
472
473
    keyinfo->key_parts= indx.index_part_size();
474
475
    keyinfo->key_part= key_part;
476
    keyinfo->rec_per_key= rec_per_key;
477
1046.1.6 by Brian Aker
Formatting/style cleanup.
478
    for (unsigned int partnr= 0;
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.
479
	partnr < keyinfo->key_parts;
480
	partnr++, key_part++)
481
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
482
      drizzled::message::Table::Index::IndexPart part;
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.
483
      part= indx.index_part(partnr);
484
1046.1.6 by Brian Aker
Formatting/style cleanup.
485
      *rec_per_key++= 0;
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.
486
487
      key_part->field= NULL;
896.3.13 by Stewart Smith
compute key_part->offset instead of storing in proto.
488
      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.
489
      key_part->null_bit= 0;
490
      /* key_part->null_offset is only set if null_bit (see later) */
491
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
492
      /* key_part->type ???? */
493
      key_part->key_part_flag= 0;
1034.1.2 by Brian Aker
Correct if() style
494
      if (part.has_in_reverse_order())
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.
495
	key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
496
497
      key_part->length= part.compare_length();
498
499
      key_part->store_length= key_part->length;
896.3.1 by Stewart Smith
removal final 2 values in indexes from being read from FRM.
500
896.3.13 by Stewart Smith
compute key_part->offset instead of storing in proto.
501
      /* key_part->offset is set later */
896.3.1 by Stewart Smith
removal final 2 values in indexes from being read from FRM.
502
      key_part->key_type= part.key_type();
503
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.
504
    }
505
1034.1.2 by Brian Aker
Correct if() style
506
    if (!indx.has_comment())
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.
507
    {
508
      keyinfo->comment.length= 0;
509
      keyinfo->comment.str= NULL;
510
    }
511
    else
512
    {
513
      keyinfo->flags|= HA_USES_COMMENT;
514
      keyinfo->comment.length= indx.comment().length();
515
      keyinfo->comment.str= strmake_root(&share->mem_root,
516
					 indx.comment().c_str(),
517
					 keyinfo->comment.length);
518
    }
519
520
    keyinfo->name= strmake_root(&share->mem_root,
521
				indx.name().c_str(),
522
				indx.name().length());
523
524
    share->keynames.type_names[keynr]= keyinfo->name;
525
    share->keynames.type_lengths[keynr]= indx.name().length();
526
  }
527
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
528
  share->keys_for_keyread.reset();
529
  set_prefix(share->keys_in_use, share->keys);
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.
530
1034.1.2 by Brian Aker
Correct if() style
531
  if (table_options.has_connect_string())
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.
532
  {
533
    size_t len= table_options.connect_string().length();
534
    const char* str= table_options.connect_string().c_str();
535
536
    share->connect_string.length= len;
537
    share->connect_string.str= strmake_root(&share->mem_root, str, len);
538
  }
539
1034.1.2 by Brian Aker
Correct if() style
540
  if (table_options.has_comment())
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.
541
  {
542
    size_t len= table_options.comment().length();
543
    const char* str= table_options.comment().c_str();
544
545
    share->comment.length= len;
546
    share->comment.str= strmake_root(&share->mem_root, str, len);
547
  }
548
549
  share->key_block_size= table_options.has_key_block_size() ?
550
    table_options.key_block_size() : 0;
551
869.1.4 by Stewart Smith
read number of fields from proto instead of frm
552
  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.
553
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
554
  share->field= (Field**) alloc_root(&share->mem_root,
555
				     ((share->fields+1) * sizeof(Field*)));
556
  share->field[share->fields]= NULL;
557
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
558
  uint32_t null_fields= 0;
559
  share->reclength= 0;
560
561
  uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
562
  uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
563
564
  assert(field_offsets && field_pack_length); // TODO: fixme
565
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
566
  uint32_t interval_count= 0;
567
  uint32_t interval_parts= 0;
568
896.3.11 by Stewart Smith
properly calculate field offsets in record buffer in parse_table_proto.
569
  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.
570
1046.1.6 by Brian Aker
Formatting/style cleanup.
571
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
572
  {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
573
    drizzled::message::Table::Field pfield= table.field(fieldnr);
1034.1.2 by Brian Aker
Correct if() style
574
    if (pfield.has_constraints() && pfield.constraints().is_nullable())
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
575
      null_fields++;
576
577
    enum_field_types drizzle_field_type=
578
      proto_field_type_to_drizzle_type(pfield.type());
579
896.3.11 by Stewart Smith
properly calculate field offsets in record buffer in parse_table_proto.
580
    field_offsets[fieldnr]= stored_columns_reclength;
581
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
582
    /* the below switch is very similar to
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
583
       CreateField::create_length_to_internal_length in field.cc
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
584
       (which should one day be replace by just this code)
585
    */
586
    switch(drizzle_field_type)
587
    {
588
    case DRIZZLE_TYPE_BLOB:
589
    case DRIZZLE_TYPE_VARCHAR:
590
      {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
591
	drizzled::message::Table::Field::StringFieldOptions field_options=
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
592
	  pfield.string_options();
593
594
	const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
595
					    field_options.collation_id() : 0);
596
597
	if (!cs)
598
	  cs= default_charset_info;
599
600
	field_pack_length[fieldnr]=
601
	  calc_pack_length(drizzle_field_type,
602
			   field_options.length() * cs->mbmaxlen);
603
604
      }
605
      break;
606
    case DRIZZLE_TYPE_ENUM:
607
      {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
608
	drizzled::message::Table::Field::SetFieldOptions field_options=
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
609
	  pfield.set_options();
610
611
	field_pack_length[fieldnr]=
612
	  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.
613
614
	interval_count++;
615
	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.
616
      }
617
      break;
618
    case DRIZZLE_TYPE_NEWDECIMAL:
619
      {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
620
	drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
621
622
	field_pack_length[fieldnr]=
623
	  my_decimal_get_binary_size(fo.precision(), fo.scale());
624
      }
625
      break;
626
    default:
627
      /* Zero is okay here as length is fixed for other types. */
628
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
629
    }
630
631
    share->reclength+= field_pack_length[fieldnr];
1005.2.7 by Monty Taylor
Removed is_stored - was only used for VCOL.
632
    stored_columns_reclength+= field_pack_length[fieldnr];
896.3.11 by Stewart Smith
properly calculate field offsets in record buffer in parse_table_proto.
633
634
  }
635
896.3.14 by Stewart Smith
stored_rec_length should include data_offset.
636
  /* 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.
637
  share->stored_rec_length= stored_columns_reclength;
638
896.4.5 by Stewart Smith
share->null_fields computed from proto. assert that same as FRM
639
  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.
640
641
  ulong null_bits= null_fields;
1034.1.2 by Brian Aker
Correct if() style
642
  if (!table_options.pack_record())
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
643
    null_bits++;
644
  ulong data_offset= (null_bits + 7)/8;
645
896.3.1 by Stewart Smith
removal final 2 values in indexes from being read from FRM.
646
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
647
  share->reclength+= data_offset;
896.3.14 by Stewart Smith
stored_rec_length should include data_offset.
648
  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.
649
650
  ulong rec_buff_length;
651
652
  rec_buff_length= ALIGN_SIZE(share->reclength + 1);
653
  share->rec_buff_length= rec_buff_length;
654
655
  unsigned char* record= NULL;
656
657
  if (!(record= (unsigned char *) alloc_root(&share->mem_root,
658
                                     rec_buff_length)))
659
    abort();
660
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
661
  memset(record, 0, rec_buff_length);
662
663
  int null_count= 0;
664
1034.1.2 by Brian Aker
Correct if() style
665
  if (!table_options.pack_record())
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
666
  {
667
    null_count++; // one bit for delete mark.
668
    *record|= 1;
669
  }
670
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
671
  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.
672
1034.1.2 by Brian Aker
Correct if() style
673
  if (interval_count)
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
674
  {
675
    share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
676
					   interval_count*sizeof(TYPELIB));
677
  }
678
  else
679
    share->intervals= NULL;
680
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
681
  share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
682
			          (share->fields+1)*sizeof(char*));
683
684
  share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
685
				  (share->fields+1)*sizeof(unsigned int));
686
687
  share->fieldnames.type_names[share->fields]= NULL;
688
  share->fieldnames.type_lengths[share->fields]= 0;
689
  share->fieldnames.count= share->fields;
690
691
692
  /* Now fix the TYPELIBs for the intervals (enum values)
693
     and field names.
694
   */
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
695
696
  uint32_t interval_nr= 0;
697
1046.1.6 by Brian Aker
Formatting/style cleanup.
698
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
699
  {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
700
    drizzled::message::Table::Field pfield= table.field(fieldnr);
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
701
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
702
    /* field names */
703
    share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
704
							pfield.name().c_str(),
705
							pfield.name().length());
706
707
    share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
708
709
    /* enum typelibs */
1034.1.2 by Brian Aker
Correct if() style
710
    if (pfield.type() != drizzled::message::Table::Field::ENUM)
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
711
      continue;
712
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
713
    drizzled::message::Table::Field::SetFieldOptions field_options=
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
714
      pfield.set_options();
715
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
716
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
717
					     field_options.collation_id() : 0);
718
719
    if (!charset)
720
      charset= default_charset_info;
721
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
722
    TYPELIB *t= &(share->intervals[interval_nr]);
723
724
    t->type_names= (const char**)alloc_root(&share->mem_root,
725
			   (field_options.field_value_size()+1)*sizeof(char*));
726
727
    t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
728
		     (field_options.field_value_size()+1)*sizeof(unsigned int));
729
730
    t->type_names[field_options.field_value_size()]= NULL;
731
    t->type_lengths[field_options.field_value_size()]= 0;
732
733
    t->count= field_options.field_value_size();
734
    t->name= NULL;
735
1046.1.6 by Brian Aker
Formatting/style cleanup.
736
    for (int n= 0; n < field_options.field_value_size(); n++)
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
737
    {
738
      t->type_names[n]= strmake_root(&share->mem_root,
739
				     field_options.field_value(n).c_str(),
740
				     field_options.field_value(n).length());
741
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
742
      /* Go ask the charset what the length is as for "" length=1
743
	 and there's stripping spaces or some other crack going on.
744
       */
745
      uint32_t lengthsp;
746
      lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
747
					field_options.field_value(n).length());
748
      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.
749
    }
750
    interval_nr++;
751
  }
752
753
754
  /* and read the fields */
755
  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.
756
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
757
  bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
758
1034.1.2 by Brian Aker
Correct if() style
759
  if (use_hash)
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
760
    use_hash= !hash_init(&share->name_hash,
761
			 system_charset_info,
762
			 share->fields, 0, 0,
763
			 (hash_get_key) get_field_name, 0, 0);
764
765
  unsigned char* null_pos= record;;
766
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
767
1046.1.6 by Brian Aker
Formatting/style cleanup.
768
  for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
769
  {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
770
    drizzled::message::Table::Field pfield= table.field(fieldnr);
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
771
772
    enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
773
774
    switch(pfield.format())
775
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
776
    case drizzled::message::Table::Field::DefaultFormat:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
777
      column_format= COLUMN_FORMAT_TYPE_DEFAULT;
778
      break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
779
    case drizzled::message::Table::Field::FixedFormat:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
780
      column_format= COLUMN_FORMAT_TYPE_FIXED;
781
      break;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
782
    case drizzled::message::Table::Field::DynamicFormat:
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
783
      column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
784
      break;
785
    default:
899.1.1 by brian
Merge of Stewart + Jay's fix.
786
      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.
787
    }
788
789
    Field::utype unireg_type= Field::NONE;
790
1034.1.2 by Brian Aker
Correct if() style
791
    if (pfield.has_numeric_options()
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
792
       && pfield.numeric_options().is_autoincrement())
793
    {
794
      unireg_type= Field::NEXT_NUMBER;
795
    }
796
1034.1.2 by Brian Aker
Correct if() style
797
    if (pfield.has_options()
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
798
       && pfield.options().has_default_value()
1046.1.6 by Brian Aker
Formatting/style cleanup.
799
       && pfield.options().default_value().compare("NOW()") == 0)
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
800
    {
1034.1.2 by Brian Aker
Correct if() style
801
      if (pfield.options().has_update_value()
1046.1.6 by Brian Aker
Formatting/style cleanup.
802
	 && pfield.options().update_value().compare("NOW()") == 0)
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
803
      {
804
	unireg_type= Field::TIMESTAMP_DNUN_FIELD;
805
      }
806
      else if (!pfield.options().has_update_value())
807
      {
808
	unireg_type= Field::TIMESTAMP_DN_FIELD;
809
      }
810
      else
899.1.1 by brian
Merge of Stewart + Jay's fix.
811
	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.
812
    }
813
    else if (pfield.has_options()
814
	     && pfield.options().has_update_value()
1046.1.6 by Brian Aker
Formatting/style cleanup.
815
	     && pfield.options().update_value().compare("NOW()") == 0)
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
816
    {
817
      unireg_type= Field::TIMESTAMP_UN_FIELD;
818
    }
819
820
    LEX_STRING comment;
1034.1.2 by Brian Aker
Correct if() style
821
    if (!pfield.has_comment())
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
822
    {
823
      comment.str= (char*)"";
824
      comment.length= 0;
825
    }
826
    else
827
    {
828
      size_t len= pfield.comment().length();
829
      const char* str= pfield.comment().c_str();
830
831
      comment.str= strmake_root(&share->mem_root, str, len);
832
      comment.length= len;
833
    }
834
835
    enum_field_types field_type;
836
837
    field_type= proto_field_type_to_drizzle_type(pfield.type());
838
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
839
    const CHARSET_INFO *charset= &my_charset_bin;
840
1034.1.2 by Brian Aker
Correct if() style
841
    if (field_type==DRIZZLE_TYPE_BLOB
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
842
       || field_type==DRIZZLE_TYPE_VARCHAR)
843
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
844
      drizzled::message::Table::Field::StringFieldOptions field_options=
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
845
	pfield.string_options();
846
847
      charset= get_charset(field_options.has_collation_id()?
848
			   field_options.collation_id() : 0);
849
850
      if (!charset)
851
	charset= default_charset_info;
852
853
    }
854
1034.1.2 by Brian Aker
Correct if() style
855
    if (field_type==DRIZZLE_TYPE_ENUM)
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
856
    {
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
857
      drizzled::message::Table::Field::SetFieldOptions field_options=
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
858
	pfield.set_options();
859
860
      charset= get_charset(field_options.has_collation_id()?
861
			   field_options.collation_id() : 0);
862
863
      if (!charset)
864
	charset= default_charset_info;
865
866
    }
867
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
868
    Item *default_value= NULL;
869
1034.1.2 by Brian Aker
Correct if() style
870
    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.
871
       || pfield.options().has_default_null()
872
       || 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.
873
    {
874
      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.
875
					charset,
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
876
					pfield.options().default_null(),
910.4.11 by Stewart Smith
fix default value Item generation. (spotted on Solaris)
877
					&pfield.options().default_value(),
878
					&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.
879
    }
880
881
    uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
882
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
883
    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.
884
    memset(&temp_table, 0, sizeof(temp_table));
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
885
    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.
886
    temp_table.in_use= session;
887
    temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
888
    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.
889
896.3.11 by Stewart Smith
properly calculate field offsets in record buffer in parse_table_proto.
890
    Field* f= make_field(share, &share->mem_root,
891
			 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.
892
			 pfield.options().length(),
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
893
			 null_pos,
894
			 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.
895
			 pack_flag,
896
			 field_type,
897
			 charset,
898
			 (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.
899
			 ((field_type==DRIZZLE_TYPE_ENUM)?
900
			 share->intervals+(interval_nr++)
901
			 : (TYPELIB*) 0),
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
902
			share->fieldnames.type_names[fieldnr]);
903
904
    share->field[fieldnr]= f;
905
906
    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.
907
1034.1.2 by Brian Aker
Correct if() style
908
    if (!(f->flags & NOT_NULL_FLAG))
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
909
    {
910
      *f->null_ptr|= f->null_bit;
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
911
      if (!(null_bit_pos= (null_bit_pos + 1) & 7))
912
	null_pos++;
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
913
      null_count++;
914
    }
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
915
1034.1.2 by Brian Aker
Correct if() style
916
    if (default_value)
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
917
    {
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
918
      enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
919
      session->count_cuted_fields= CHECK_FIELD_WARN;
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
920
      int res= default_value->save_in_field(f, 1);
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
921
      session->count_cuted_fields= old_count_cuted_fields;
922
      if (res != 0 && res != 3)
923
      {
924
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
925
        error= 1;
926
	goto err;
927
      }
896.3.3 by Stewart Smith
Start generating a record buffer with default values in proto read path instead of FRM write path.
928
    }
1034.1.2 by Brian Aker
Correct if() style
929
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
930
	    (f->flags & NOT_NULL_FLAG))
931
    {
932
      f->set_notnull();
933
      f->store((int64_t) 1, true);
934
    }
935
    else
936
      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.
937
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
938
    /* hack to undo f->init() */
939
    f->table= NULL;
940
    f->orig_table= NULL;
941
942
    f->field_index= fieldnr;
943
    f->comment= comment;
1034.1.2 by Brian Aker
Correct if() style
944
    if (!default_value
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
945
       && !(f->unireg_check==Field::NEXT_NUMBER)
946
       && (f->flags & NOT_NULL_FLAG)
947
       && (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
948
      f->flags|= NO_DEFAULT_VALUE_FLAG;
949
1034.1.2 by Brian Aker
Correct if() style
950
    if (f->unireg_check == Field::NEXT_NUMBER)
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
951
      share->found_next_number_field= &(share->field[fieldnr]);
952
1034.1.2 by Brian Aker
Correct if() style
953
    if (share->timestamp_field == f)
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
954
      share->timestamp_field_offset= fieldnr;
955
956
    if (use_hash) /* supposedly this never fails... but comments lie */
957
      (void) my_hash_insert(&share->name_hash,
958
			    (unsigned char*)&(share->field[fieldnr]));
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
959
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
960
  }
961
896.3.13 by Stewart Smith
compute key_part->offset instead of storing in proto.
962
  keyinfo= share->key_info;
1046.1.6 by Brian Aker
Formatting/style cleanup.
963
  for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
896.3.13 by Stewart Smith
compute key_part->offset instead of storing in proto.
964
  {
965
    key_part= keyinfo->key_part;
966
1046.1.6 by Brian Aker
Formatting/style cleanup.
967
    for (unsigned int partnr= 0;
968
         partnr < keyinfo->key_parts;
969
         partnr++, key_part++)
896.3.13 by Stewart Smith
compute key_part->offset instead of storing in proto.
970
    {
971
      /* Fix up key_part->offset by adding data_offset.
972
	 We really should compute offset as well.
973
	 But at least this way we are a little better. */
974
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
975
    }
976
  }
977
896.3.4 by Stewart Smith
Create default_values record from proto instead of reading from FRM. assert if different to FRM.
978
  /*
979
    We need to set the unused bits to 1. If the number of bits is a multiple
980
    of 8 there are no unused bits.
981
  */
982
983
  if (null_count & 7)
984
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
985
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
986
  share->null_bytes= (null_pos - (unsigned char*) record +
987
		      (null_bit_pos + 7) / 8);
988
989
  share->last_null_bit_pos= null_bit_pos;
990
869.1.24 by Stewart Smith
Generate all the info needed to get a record size on proto read instead of FRM create time.
991
  free(field_offsets);
992
  free(field_pack_length);
869.1.4 by Stewart Smith
read number of fields from proto instead of frm
993
1034.1.2 by Brian Aker
Correct if() style
994
  if (!(handler_file= get_new_handler(share, session->mem_root,
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
995
				     share->db_type())))
996
    abort(); // FIXME
997
998
  /* Fix key stuff */
999
  if (share->key_parts)
1000
  {
1001
    uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
1002
				       &share->keynames, 3) - 1);
1003
1004
    int64_t ha_option= handler_file->ha_table_flags();
1005
1006
    keyinfo= share->key_info;
1007
    key_part= keyinfo->key_part;
1008
1046.1.6 by Brian Aker
Formatting/style cleanup.
1009
    for (uint32_t key= 0 ; key < share->keys ; key++,keyinfo++)
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
1010
    {
1011
      uint32_t usable_parts= 0;
1012
1013
      if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1014
      {
1015
	/*
1016
	  If the UNIQUE key doesn't have NULL columns and is not a part key
1017
	  declare this as a primary key.
1018
	*/
1019
	primary_key=key;
1046.1.6 by Brian Aker
Formatting/style cleanup.
1020
	for (uint32_t i= 0 ; i < keyinfo->key_parts ;i++)
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
1021
	{
1022
	  uint32_t fieldnr= key_part[i].fieldnr;
1023
	  if (!fieldnr ||
1024
	      share->field[fieldnr-1]->null_ptr ||
1025
	      share->field[fieldnr-1]->key_length() !=
1026
	      key_part[i].length)
1027
	  {
1028
	    primary_key=MAX_KEY;                // Can't be used
1029
	    break;
1030
	  }
1031
	}
1032
      }
1033
1046.1.6 by Brian Aker
Formatting/style cleanup.
1034
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
1035
      {
1036
        Field *field;
1037
	if (!key_part->fieldnr)
1038
        {
1039
//          error= 4;                             // Wrong file
1040
	  abort(); // goto err;
1041
        }
1042
        field= key_part->field= share->field[key_part->fieldnr-1];
1043
        key_part->type= field->key_type();
1044
        if (field->null_ptr)
1045
        {
1046
          key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1047
                                        share->default_values);
1048
          key_part->null_bit= field->null_bit;
1049
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1050
          keyinfo->flags|=HA_NULL_PART_KEY;
1051
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1052
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1053
        }
1054
        if (field->type() == DRIZZLE_TYPE_BLOB ||
1055
            field->real_type() == DRIZZLE_TYPE_VARCHAR)
1056
        {
1057
          if (field->type() == DRIZZLE_TYPE_BLOB)
1058
            key_part->key_part_flag|= HA_BLOB_PART;
1059
          else
1060
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1061
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1062
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
1063
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1064
        }
1065
        if (i == 0 && key != primary_key)
1066
          field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1067
                           (keyinfo->key_parts == 1)) ?
1068
                           UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1069
        if (i == 0)
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1070
          field->key_start.set(key);
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
1071
        if (field->key_length() == key_part->length &&
1072
            !(field->flags & BLOB_FLAG))
1073
        {
1074
          if (handler_file->index_flags(key, i, 0) & HA_KEYREAD_ONLY)
1075
          {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1076
            share->keys_for_keyread.set(key);
1077
            field->part_of_key.set(key);
1078
            field->part_of_key_not_clustered.set(key);
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
1079
          }
1080
          if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1081
            field->part_of_sortkey.set(key);
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
1082
        }
1083
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1084
            usable_parts == i)
1085
          usable_parts++;			// For FILESORT
1086
        field->flags|= PART_KEY_FLAG;
1087
        if (key == primary_key)
1088
        {
1089
          field->flags|= PRI_KEY_FLAG;
1090
          /*
1091
            If this field is part of the primary key and all keys contains
1092
            the primary key, then we can use any key to find this column
1093
          */
1094
          if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
1095
          {
1096
            field->part_of_key= share->keys_in_use;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1097
            if (field->part_of_sortkey.test(key))
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
1098
              field->part_of_sortkey= share->keys_in_use;
1099
          }
1100
        }
1101
        if (field->key_length() != key_part->length)
1102
        {
1103
          key_part->key_part_flag|= HA_PART_KEY_SEG;
1104
        }
1105
      }
1106
      keyinfo->usable_key_parts= usable_parts; // Filesort
1107
1108
      set_if_bigger(share->max_key_length,keyinfo->key_length+
1109
                    keyinfo->key_parts);
1110
      share->total_key_length+= keyinfo->key_length;
1111
      /*
1112
        MERGE tables do not have unique indexes. But every key could be
1113
        an unique index on the underlying MyISAM table. (Bug #10400)
1114
      */
1115
      if ((keyinfo->flags & HA_NOSAME) ||
1116
          (ha_option & HA_ANY_INDEX_MAY_BE_UNIQUE))
1117
        set_if_bigger(share->max_unique_length,keyinfo->key_length);
1118
    }
1119
    if (primary_key < MAX_KEY &&
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
1120
	(share->keys_in_use.test(primary_key)))
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
1121
    {
1122
      share->primary_key= primary_key;
1123
      /*
1124
	If we are using an integer as the primary key then allow the user to
1125
	refer to it as '_rowid'
1126
      */
1127
      if (share->key_info[primary_key].key_parts == 1)
1128
      {
1129
	Field *field= share->key_info[primary_key].key_part[0].field;
1130
	if (field && field->result_type() == INT_RESULT)
1131
        {
1132
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1133
	  share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
1134
                                      fieldnr);
1135
        }
1136
      }
1137
1138
    }
1139
    else
1140
      share->primary_key = MAX_KEY; // we do not have a primary key
1141
  }
1142
  else
1143
    share->primary_key= MAX_KEY;
1144
896.4.6 by Stewart Smith
move fixing auto_inc and blobs from FRM code path to table_proto code path
1145
  if (share->found_next_number_field)
1146
  {
1147
    Field *reg_field= *share->found_next_number_field;
1148
    if ((int) (share->next_number_index= (uint32_t)
1149
	       find_ref_key(share->key_info, share->keys,
1150
                            share->default_values, reg_field,
1151
			    &share->next_number_key_offset,
1152
                            &share->next_number_keypart)) < 0)
1153
    {
1154
      /* Wrong field definition */
1155
      error= 4;
1156
      goto err;
1157
    }
1158
    else
1159
      reg_field->flags |= AUTO_INCREMENT_FLAG;
1160
  }
1161
1162
  if (share->blob_fields)
1163
  {
1164
    Field **ptr;
1165
    uint32_t k, *save;
1166
1167
    /* Store offsets to blob fields to find them fast */
1168
    if (!(share->blob_field= save=
1169
	  (uint*) alloc_root(&share->mem_root,
1170
                             (uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1171
      goto err;
1046.1.6 by Brian Aker
Formatting/style cleanup.
1172
    for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
896.4.6 by Stewart Smith
move fixing auto_inc and blobs from FRM code path to table_proto code path
1173
    {
1174
      if ((*ptr)->flags & BLOB_FLAG)
1175
	(*save++)= k;
1176
    }
1177
  }
1178
896.4.7 by Stewart Smith
last bit of bitmap logic from FRM path to proto path
1179
  share->db_low_byte_first= handler_file->low_byte_first();
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
1180
  share->column_bitmap_size= bitmap_buffer_size(share->fields);
1181
1182
  my_bitmap_map *bitmaps;
1183
1184
  if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1185
                                             share->column_bitmap_size)))
1186
    goto err;
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
1187
  bitmap_init(&share->all_set, bitmaps, share->fields);
1005.2.3 by Monty Taylor
Further reversion of P.
1188
  bitmap_set_all(&share->all_set);
896.4.7 by Stewart Smith
last bit of bitmap logic from FRM path to proto path
1189
1034.1.2 by Brian Aker
Correct if() style
1190
  if (handler_file)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
1191
    delete handler_file;
896.4.7 by Stewart Smith
last bit of bitmap logic from FRM path to proto path
1192
  return (0);
1193
896.4.6 by Stewart Smith
move fixing auto_inc and blobs from FRM code path to table_proto code path
1194
err:
896.4.7 by Stewart Smith
last bit of bitmap logic from FRM path to proto path
1195
  share->error= error;
1196
  share->open_errno= my_errno;
1197
  share->errarg= 0;
1198
  hash_free(&share->name_hash);
1034.1.2 by Brian Aker
Correct if() style
1199
  if (handler_file)
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
1200
    delete handler_file;
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1201
  share->open_table_error(error, share->open_errno, 0);
1202
896.4.6 by Stewart Smith
move fixing auto_inc and blobs from FRM code path to table_proto code path
1203
  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.
1204
}
1205
1 by brian
clean slate
1206
/*
1207
  Read table definition from a binary / text based .frm file
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1208
1 by brian
clean slate
1209
  SYNOPSIS
1210
  open_table_def()
520.1.22 by Brian Aker
Second pass of thd cleanup
1211
  session		Thread handler
1 by brian
clean slate
1212
  share		Fill this with table definition
1213
1214
  NOTES
1215
    This function is called when the table definition is not cached in
1216
    table_def_cache
1217
    The data is returned in 'share', which is alloced by
1218
    alloc_table_share().. The code assumes that share is initialized.
1219
1220
  RETURN VALUES
1221
   0	ok
1222
   1	Error (see open_table_error)
1223
   2    Error (see open_table_error)
1224
   3    Wrong data in .frm file
1225
   4    Error (see open_table_error)
1226
   5    Error (see open_table_error: charset unavailable)
1227
   6    Unknown .frm version
1228
*/
1229
1000.1.5 by Brian Aker
More refactoring back to TableShare object.
1230
int open_table_def(Session *session, TableShare *share)
1 by brian
clean slate
1231
{
896.4.8 by Stewart Smith
Just read table proto. Remove open_binary_frm. FRM is not read anymore.
1232
  int error;
1 by brian
clean slate
1233
  bool error_given;
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
1234
  string proto_path("");
534 by Monty Taylor
Removed stxnmov. Also deleted strstr which had already been removed.
1235
1 by brian
clean slate
1236
  error= 1;
1237
  error_given= 0;
1238
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
1239
  proto_path.reserve(FN_REFLEN);
1240
  proto_path.append(share->normalized_path.str);
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
1241
1242
  proto_path.append(".dfe");
1243
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
1244
  drizzled::message::Table table;
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
1245
1034.1.2 by Brian Aker
Correct if() style
1246
  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.
1247
  {
1034.1.2 by Brian Aker
Correct if() style
1248
    if (error>0)
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.
1249
    {
1250
      my_errno= error;
1251
      error= 1;
1252
    }
1253
    else
1254
    {
1034.1.2 by Brian Aker
Correct if() style
1255
      if (!table.IsInitialized())
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.
1256
      {
1257
	error= 4;
1258
      }
1259
    }
1260
    goto err_not_open;
820.1.8 by Stewart Smith
start reading table definition from proto instead of FRM.
1261
  }
1262
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
1263
  error= parse_table_proto(session, table, share);
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.
1264
1 by brian
clean slate
1265
  share->table_category= get_table_category(& share->db, & share->table_name);
1266
1267
  if (!error)
520.1.22 by Brian Aker
Second pass of thd cleanup
1268
    session->status_var.opened_shares++;
1 by brian
clean slate
1269
1270
err_not_open:
1271
  if (error && !error_given)
1272
  {
1273
    share->error= error;
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1274
    share->open_table_error(error, (share->open_errno= my_errno), 0);
1 by brian
clean slate
1275
  }
1276
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
1277
  return(error);
1 by brian
clean slate
1278
}
1279
383.7.1 by Andrey Zhakov
Initial submit of code and tests
1280
1281
/*
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
1282
  Open a table based on a TableShare
1 by brian
clean slate
1283
1284
  SYNOPSIS
1285
    open_table_from_share()
520.1.22 by Brian Aker
Second pass of thd cleanup
1286
    session			Thread handler
1 by brian
clean slate
1287
    share		Table definition
1288
    alias       	Alias for table
1289
    db_stat		open flags (for example HA_OPEN_KEYFILE|
1290
    			HA_OPEN_RNDFILE..) can be 0 (example in
1291
                        ha_example_table)
1292
    prgflag   		READ_ALL etc..
1293
    ha_open_flags	HA_OPEN_ABORT_IF_LOCKED etc..
1294
    outparam       	result table
1295
    open_mode           One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1296
                        if OTM_CREATE some errors are ignore
1297
                        if OTM_ALTER HA_OPEN is not called
1298
1299
  RETURN VALUES
1300
   0	ok
1301
   1	Error (see open_table_error)
1302
   2    Error (see open_table_error)
1303
   3    Wrong data in .frm file
1304
   4    Error (see open_table_error)
1305
   5    Error (see open_table_error: charset unavailable)
1306
   7    Table definition has changed in engine
1307
*/
1308
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
1309
int open_table_from_share(Session *session, TableShare *share, const char *alias,
482 by Brian Aker
Remove uint.
1310
                          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
1311
                          Table *outparam, open_table_mode open_mode)
1 by brian
clean slate
1312
{
1313
  int error;
1005.2.4 by Monty Taylor
Patch cleaning.
1314
  uint32_t records, i, bitmap_size;
51.1.70 by Jay Pipes
Removed/replaced DBUG symbols and removed sql_test.cc from Makefile
1315
  bool error_reported= false;
1005.2.4 by Monty Taylor
Patch cleaning.
1316
  unsigned char *record, *bitmaps;
998.1.2 by Brian Aker
First pass on removing virt columns
1317
  Field **field_ptr;
1 by brian
clean slate
1318
520.1.22 by Brian Aker
Second pass of thd cleanup
1319
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1320
  assert(session->lex->is_lex_started);
1 by brian
clean slate
1321
1322
  error= 1;
1039.1.10 by Brian Aker
Minor formating, change of one name to make grep easier :)
1323
  outparam->resetTable(session, share, db_stat);
1 by brian
clean slate
1324
1325
656.1.19 by Monty Taylor
Removed my_strdup from drizzled/
1326
  if (!(outparam->alias= strdup(alias)))
1 by brian
clean slate
1327
    goto err;
1328
1329
  /* Allocate handler */
1330
  if (!(prgflag & OPEN_FRM_FILE_ONLY))
1331
  {
1332
    if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1333
                                          share->db_type())))
1334
      goto err;
1335
  }
1336
  else
1337
  {
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
1338
    assert(!db_stat);
1 by brian
clean slate
1339
  }
1340
1341
  error= 4;
1046.1.6 by Brian Aker
Formatting/style cleanup.
1342
  records= 0;
1 by brian
clean slate
1343
  if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1344
    records=1;
1345
  if (prgflag & (READ_ALL+EXTRA_RECORD))
1346
    records++;
1347
481 by Brian Aker
Remove all of uchar.
1348
  if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1 by brian
clean slate
1349
                                   share->rec_buff_length * records)))
1350
    goto err;                                   /* purecov: inspected */
1351
1352
  if (records == 0)
1353
  {
1354
    /* We are probably in hard repair, and the buffers should not be used */
1355
    outparam->record[0]= outparam->record[1]= share->default_values;
1356
  }
1357
  else
1358
  {
1359
    outparam->record[0]= record;
1360
    if (records > 1)
1361
      outparam->record[1]= record+ share->rec_buff_length;
1362
    else
1363
      outparam->record[1]= outparam->record[0];   // Safety
1364
  }
1365
1366
#ifdef HAVE_purify
1367
  /*
1368
    We need this because when we read var-length rows, we are not updating
1369
    bytes after end of varchar
1370
  */
1371
  if (records > 1)
1372
  {
1373
    memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
1374
    memcpy(outparam->record[1], share->default_values, share->null_bytes);
1375
    if (records > 2)
1376
      memcpy(outparam->record[1], share->default_values,
1377
             share->rec_buff_length);
1378
  }
1379
#endif
1380
1381
  if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
895 by Brian Aker
Completion (?) of uint conversion.
1382
                                          (uint32_t) ((share->fields+1)*
1 by brian
clean slate
1383
                                                  sizeof(Field*)))))
1384
    goto err;                                   /* purecov: inspected */
1385
1386
  outparam->field= field_ptr;
1387
481 by Brian Aker
Remove all of uchar.
1388
  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
1389
1390
  outparam->null_flags= (unsigned char*) record+1;
1 by brian
clean slate
1391
1392
  /* Setup copy of fields from share, but use the right alias and record */
1046.1.6 by Brian Aker
Formatting/style cleanup.
1393
  for (i= 0 ; i < share->fields; i++, field_ptr++)
1 by brian
clean slate
1394
  {
1395
    if (!((*field_ptr)= share->field[i]->clone(&outparam->mem_root, outparam)))
1396
      goto err;
1397
  }
1398
  (*field_ptr)= 0;                              // End marker
1399
1400
  if (share->found_next_number_field)
1401
    outparam->found_next_number_field=
895 by Brian Aker
Completion (?) of uint conversion.
1402
      outparam->field[(uint32_t) (share->found_next_number_field - share->field)];
1 by brian
clean slate
1403
  if (share->timestamp_field)
1404
    outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
1405
1406
1407
  /* Fix key->name and key_part->field */
1408
  if (share->key_parts)
1409
  {
1410
    KEY	*key_info, *key_info_end;
1411
    KEY_PART_INFO *key_part;
482 by Brian Aker
Remove uint.
1412
    uint32_t n_length;
1 by brian
clean slate
1413
    n_length= share->keys*sizeof(KEY) + share->key_parts*sizeof(KEY_PART_INFO);
1414
    if (!(key_info= (KEY*) alloc_root(&outparam->mem_root, n_length)))
1415
      goto err;
1416
    outparam->key_info= key_info;
451 by Monty Taylor
Removed my_reinterpret_cast. It's not GNU specific.
1417
    key_part= (reinterpret_cast<KEY_PART_INFO*> (key_info+share->keys));
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1418
1 by brian
clean slate
1419
    memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
1420
    memcpy(key_part, share->key_info[0].key_part, (sizeof(*key_part) *
1421
                                                   share->key_parts));
1422
1423
    for (key_info_end= key_info + share->keys ;
1424
         key_info < key_info_end ;
1425
         key_info++)
1426
    {
1427
      KEY_PART_INFO *key_part_end;
1428
1429
      key_info->table= outparam;
1430
      key_info->key_part= key_part;
1431
1432
      for (key_part_end= key_part+ key_info->key_parts ;
1433
           key_part < key_part_end ;
1434
           key_part++)
1435
      {
1436
        Field *field= key_part->field= outparam->field[key_part->fieldnr-1];
1437
1438
        if (field->key_length() != key_part->length &&
1439
            !(field->flags & BLOB_FLAG))
1440
        {
1441
          /*
1442
            We are using only a prefix of the column as a key:
1443
            Create a new field for the key part that matches the index
1444
          */
1445
          field= key_part->field=field->new_field(&outparam->mem_root,
1446
                                                  outparam, 0);
1447
          field->field_length= key_part->length;
1448
        }
1449
      }
1450
    }
1451
  }
1452
1453
  /* Allocate bitmaps */
1005.2.3 by Monty Taylor
Further reversion of P.
1454
1455
  bitmap_size= share->column_bitmap_size;
1456
  if (!(bitmaps= (unsigned char*) alloc_root(&outparam->mem_root, bitmap_size*3)))
1457
    goto err;
1458
  bitmap_init(&outparam->def_read_set,
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
1459
              (my_bitmap_map*) bitmaps, share->fields);
1005.2.3 by Monty Taylor
Further reversion of P.
1460
  bitmap_init(&outparam->def_write_set,
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
1461
              (my_bitmap_map*) (bitmaps+bitmap_size), share->fields);
1005.2.3 by Monty Taylor
Further reversion of P.
1462
  bitmap_init(&outparam->tmp_set,
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
1463
              (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields);
1 by brian
clean slate
1464
  outparam->default_column_bitmaps();
1465
1466
  /* The table struct is now initialized;  Open the table */
1467
  error= 2;
1468
  if (db_stat && open_mode != OTM_ALTER)
1469
  {
1470
    int ha_err;
1471
    if ((ha_err= (outparam->file->
1472
                  ha_open(outparam, share->normalized_path.str,
1473
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1474
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
362 by Brian Aker
No more dead special flags...
1475
                           (db_stat & HA_WAIT_IF_LOCKED) ?  HA_OPEN_WAIT_IF_LOCKED :
1 by brian
clean slate
1476
                           (db_stat & (HA_ABORT_IF_LOCKED | HA_GET_INFO)) ?
1477
                          HA_OPEN_ABORT_IF_LOCKED :
1478
                           HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1479
    {
1480
      /* Set a flag if the table is crashed and it can be auto. repaired */
1481
      share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
1482
                       outparam->file->auto_repair() &&
1483
                       !(ha_open_flags & HA_OPEN_FOR_REPAIR));
1484
1485
      switch (ha_err)
1486
      {
1487
        case HA_ERR_NO_SUCH_TABLE:
1488
	  /*
1489
            The table did not exists in storage engine, use same error message
1490
            as if the .frm file didn't exist
1491
          */
1492
	  error= 1;
1493
	  my_errno= ENOENT;
1494
          break;
1495
        case EMFILE:
1496
	  /*
1497
            Too many files opened, use same error message as if the .frm
1498
            file can't open
1499
           */
1500
	  error= 1;
1501
	  my_errno= EMFILE;
1502
          break;
1503
        default:
1504
          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
1505
          error_reported= true;
1 by brian
clean slate
1506
          if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
1507
            error= 7;
1508
          break;
1509
      }
1510
      goto err;                                 /* purecov: inspected */
1511
    }
1512
  }
1513
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1514
#if defined(HAVE_purify)
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
1515
  memset(bitmaps, 0, bitmap_size*3);
1 by brian
clean slate
1516
#endif
1517
520.1.22 by Brian Aker
Second pass of thd cleanup
1518
  session->status_var.opened_tables++;
1 by brian
clean slate
1519
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
1520
  return (0);
1 by brian
clean slate
1521
1522
 err:
1523
  if (!error_reported && !(prgflag & DONT_GIVE_ERROR))
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1524
    share->open_table_error(error, my_errno, 0);
1 by brian
clean slate
1525
  delete outparam->file;
1526
  outparam->file= 0;				// For easier error checking
1046.1.6 by Brian Aker
Formatting/style cleanup.
1527
  outparam->db_stat= 0;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
1528
  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.
1529
  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
1530
  return (error);
1 by brian
clean slate
1531
}
1532
1533
/*
1534
  Free information allocated by openfrm
1535
1536
  SYNOPSIS
1537
    closefrm()
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1538
    table		Table object to free
1 by brian
clean slate
1539
    free_share		Is 1 if we also want to free table_share
1540
*/
1541
793 by Brian Aker
Pass through on refactoring functions to clases.
1542
int Table::closefrm(bool free_share)
1 by brian
clean slate
1543
{
1046.1.6 by Brian Aker
Formatting/style cleanup.
1544
  int error= 0;
1 by brian
clean slate
1545
793 by Brian Aker
Pass through on refactoring functions to clases.
1546
  if (db_stat)
1547
    error= file->close();
1548
  free((char*) alias);
1549
  alias= NULL;
1550
  if (field)
1 by brian
clean slate
1551
  {
793 by Brian Aker
Pass through on refactoring functions to clases.
1552
    for (Field **ptr=field ; *ptr ; ptr++)
1 by brian
clean slate
1553
      delete *ptr;
793 by Brian Aker
Pass through on refactoring functions to clases.
1554
    field= 0;
1 by brian
clean slate
1555
  }
793 by Brian Aker
Pass through on refactoring functions to clases.
1556
  delete file;
1557
  file= 0;				/* For easier errorchecking */
1 by brian
clean slate
1558
  if (free_share)
1559
  {
793 by Brian Aker
Pass through on refactoring functions to clases.
1560
    if (s->tmp_table == NO_TMP_TABLE)
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
1561
      TableShare::release(s);
1 by brian
clean slate
1562
    else
1000.1.5 by Brian Aker
More refactoring back to TableShare object.
1563
      s->free_table_share();
1 by brian
clean slate
1564
  }
793 by Brian Aker
Pass through on refactoring functions to clases.
1565
  free_root(&mem_root, MYF(0));
1566
1567
  return error;
1 by brian
clean slate
1568
}
1569
1570
1571
/* Deallocate temporary blob storage */
1572
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
1573
void free_blobs(register Table *table)
1 by brian
clean slate
1574
{
482 by Brian Aker
Remove uint.
1575
  uint32_t *ptr, *end;
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
1576
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
1 by brian
clean slate
1577
       ptr != end ;
1578
       ptr++)
1579
    ((Field_blob*) table->field[*ptr])->free();
1580
}
1581
1582
1583
	/* error message when opening a form file */
1584
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1585
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
1 by brian
clean slate
1586
{
1587
  int err_no;
1588
  char buff[FN_REFLEN];
1589
  myf errortype= ME_ERROR+ME_WAITTANG;
1590
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1591
  switch (pass_error) {
1 by brian
clean slate
1592
  case 7:
1593
  case 1:
1594
    if (db_errno == ENOENT)
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1595
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
1 by brian
clean slate
1596
    else
1597
    {
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1598
      sprintf(buff,"%s",normalized_path.str);
1 by brian
clean slate
1599
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
1600
               errortype, buff, db_errno);
1601
    }
1602
    break;
1603
  case 2:
1604
  {
1605
    handler *file= 0;
1606
    const char *datext= "";
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1607
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1608
    if (db_type() != NULL)
1 by brian
clean slate
1609
    {
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1610
      if ((file= get_new_handler(this, current_session->mem_root,
1611
                                 db_type())))
1 by brian
clean slate
1612
      {
1039.3.4 by Stewart Smith
merge mainline
1613
        if (!(datext= *db_type()->bas_ext()))
1 by brian
clean slate
1614
          datext= "";
1615
      }
1616
    }
1617
    err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
1618
      ER_FILE_USED : ER_CANT_OPEN_FILE;
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1619
    sprintf(buff,"%s%s", normalized_path.str,datext);
1 by brian
clean slate
1620
    my_error(err_no,errortype, buff, db_errno);
1621
    delete file;
1622
    break;
1623
  }
1624
  case 5:
1625
  {
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1626
    const char *csname= get_charset_name((uint32_t) pass_errarg);
1 by brian
clean slate
1627
    char tmp[10];
1628
    if (!csname || csname[0] =='?')
1629
    {
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1630
      snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
1 by brian
clean slate
1631
      csname= tmp;
1632
    }
1633
    my_printf_error(ER_UNKNOWN_COLLATION,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1634
                    _("Unknown collation '%s' in table '%-.64s' definition"),
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1635
                    MYF(0), csname, table_name.str);
1 by brian
clean slate
1636
    break;
1637
  }
1638
  case 6:
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1639
    sprintf(buff,"%s", normalized_path.str);
1 by brian
clean slate
1640
    my_printf_error(ER_NOT_FORM_FILE,
261.3.8 by Monty Taylor
Added strings from table.cc.
1641
                    _("Table '%-.64s' was created with a different version "
672.1.3 by Andrew Hutchings
Minor string fixes (mainly US English spelling and typos)
1642
                    "of Drizzle and cannot be read"),
1 by brian
clean slate
1643
                    MYF(0), buff);
1644
    break;
1645
  case 8:
1646
    break;
1647
  default:				/* Better wrong error than none */
1648
  case 4:
1039.1.9 by Brian Aker
Partial Refactor of TableShare
1649
    sprintf(buff,"%s", normalized_path.str);
1 by brian
clean slate
1650
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
1651
    break;
1652
  }
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
1653
  return;
1 by brian
clean slate
1654
} /* open_table_error */
1655
1656
1052.2.5 by Nathan Williams
Changed container from list to vector for CreateField::interval_list. There is never inserts into the middle of the container, only push_back. Per jaypipes suggestion.
1657
TYPELIB *typelib(MEM_ROOT *mem_root, vector<String*> &strings)
1 by brian
clean slate
1658
{
1659
  TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
1660
  if (!result)
1661
    return 0;
1052.2.1 by Nathan Williams
Converted Create_field::interval_list to a std::list<String*>.
1662
  result->count= strings.size();
1663
  result->name= "";
895 by Brian Aker
Completion (?) of uint conversion.
1664
  uint32_t nbytes= (sizeof(char*) + sizeof(uint32_t)) * (result->count + 1);
1052.2.1 by Nathan Williams
Converted Create_field::interval_list to a std::list<String*>.
1665
  
1 by brian
clean slate
1666
  if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes)))
1667
    return 0;
1052.2.1 by Nathan Williams
Converted Create_field::interval_list to a std::list<String*>.
1668
    
1 by brian
clean slate
1669
  result->type_lengths= (uint*) (result->type_names + result->count + 1);
1052.2.1 by Nathan Williams
Converted Create_field::interval_list to a std::list<String*>.
1670
1052.2.5 by Nathan Williams
Changed container from list to vector for CreateField::interval_list. There is never inserts into the middle of the container, only push_back. Per jaypipes suggestion.
1671
  vector<String*>::iterator it= strings.begin();
1052.2.1 by Nathan Williams
Converted Create_field::interval_list to a std::list<String*>.
1672
  for (int i= 0; it != strings.end(); ++it, ++i )
1 by brian
clean slate
1673
  {
1052.2.1 by Nathan Williams
Converted Create_field::interval_list to a std::list<String*>.
1674
    result->type_names[i]= (*it)->c_ptr();
1675
    result->type_lengths[i]= (*it)->length();
1 by brian
clean slate
1676
  }
1052.2.1 by Nathan Williams
Converted Create_field::interval_list to a std::list<String*>.
1677
1678
  result->type_names[result->count]= 0;   // End marker
1 by brian
clean slate
1679
  result->type_lengths[result->count]= 0;
1052.2.1 by Nathan Williams
Converted Create_field::interval_list to a std::list<String*>.
1680
1 by brian
clean slate
1681
  return result;
1682
}
1683
1684
	/* Check that the integer is in the internal */
1685
1686
int set_zone(register int nr, int min_zone, int max_zone)
1687
{
1688
  if (nr<=min_zone)
1689
    return (min_zone);
1690
  if (nr>=max_zone)
1691
    return (max_zone);
1692
  return (nr);
1693
} /* set_zone */
1694
1695
	/* Adjust number to next larger disk buffer */
1696
1697
ulong next_io_size(register ulong pos)
1698
{
1699
  register ulong offset;
1700
  if ((offset= pos & (IO_SIZE-1)))
1701
    return pos-offset+IO_SIZE;
1702
  return pos;
1703
} /* next_io_size */
1704
1705
1706
/*
1707
  Store an SQL quoted string.
1708
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1709
  SYNOPSIS
1 by brian
clean slate
1710
    append_unescaped()
1711
    res		result String
1712
    pos		string to be quoted
1713
    length	it's length
1714
1715
  NOTE
1716
    This function works correctly with utf8 or single-byte charset strings.
1717
    May fail with some multibyte charsets though.
1718
*/
1719
482 by Brian Aker
Remove uint.
1720
void append_unescaped(String *res, const char *pos, uint32_t length)
1 by brian
clean slate
1721
{
1722
  const char *end= pos+length;
1723
  res->append('\'');
1724
1725
  for (; pos != end ; pos++)
1726
  {
482 by Brian Aker
Remove uint.
1727
    uint32_t mblen;
1 by brian
clean slate
1728
    if (use_mb(default_charset_info) &&
1729
        (mblen= my_ismbchar(default_charset_info, pos, end)))
1730
    {
1731
      res->append(pos, mblen);
1732
      pos+= mblen;
814.1.1 by Jay Pipes
Fix for Bug 314502 "show create table crashes with multi-byte character in enum description"
1733
      if (pos >= end)
1734
        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.
1735
      continue;
1 by brian
clean slate
1736
    }
1737
1738
    switch (*pos) {
1739
    case 0:				/* Must be escaped for 'mysql' */
1740
      res->append('\\');
1741
      res->append('0');
1742
      break;
1743
    case '\n':				/* Must be escaped for logs */
1744
      res->append('\\');
1745
      res->append('n');
1746
      break;
1747
    case '\r':
1748
      res->append('\\');		/* This gives better readability */
1749
      res->append('r');
1750
      break;
1751
    case '\\':
1752
      res->append('\\');		/* Because of the sql syntax */
1753
      res->append('\\');
1754
      break;
1755
    case '\'':
1756
      res->append('\'');		/* Because of the sql syntax */
1757
      res->append('\'');
1758
      break;
1759
    default:
1760
      res->append(*pos);
1761
      break;
1762
    }
1763
  }
1764
  res->append('\'');
1765
}
1766
1767
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
1768
/*
1769
  Set up column usage bitmaps for a temporary table
1770
1771
  IMPLEMENTATION
1772
    For temporary tables, we need one bitmap with all columns set and
1773
    a tmp_set bitmap to be used by things like filesort.
1774
*/
1775
1005.2.3 by Monty Taylor
Further reversion of P.
1776
void Table::setup_tmp_table_column_bitmaps(unsigned char *bitmaps)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
1777
{
1005.2.3 by Monty Taylor
Further reversion of P.
1778
  uint32_t field_count= s->fields;
1779
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
1780
  bitmap_init(&this->def_read_set, (my_bitmap_map*) bitmaps, field_count);
1781
  bitmap_init(&this->tmp_set, (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)), field_count);
1005.2.3 by Monty Taylor
Further reversion of P.
1782
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
1783
  /* write_set and all_set are copies of read_set */
1784
  def_write_set= def_read_set;
1785
  s->all_set= def_read_set;
1005.2.3 by Monty Taylor
Further reversion of P.
1786
  bitmap_set_all(&this->s->all_set);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
1787
  default_column_bitmaps();
1788
}
1789
1790
1791
1792
void Table::updateCreateInfo(HA_CREATE_INFO *create_info)
1793
{
1794
  create_info->max_rows= s->max_rows;
1795
  create_info->min_rows= s->min_rows;
1796
  create_info->table_options= s->db_create_options;
1797
  create_info->avg_row_length= s->avg_row_length;
1798
  create_info->block_size= s->block_size;
1799
  create_info->row_type= s->row_type;
1800
  create_info->default_table_charset= s->table_charset;
1 by brian
clean slate
1801
  create_info->table_charset= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
1802
  create_info->comment= s->comment;
1 by brian
clean slate
1803
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
1804
  return;
1 by brian
clean slate
1805
}
1806
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
1807
int rename_file_ext(const char * from,const char * to,const char * ext)
1 by brian
clean slate
1808
{
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
1809
  string from_s, to_s;
1810
1811
  from_s.append(from);
1812
  from_s.append(ext);
1813
  to_s.append(to);
1814
  to_s.append(ext);
1815
  return (my_rename(from_s.c_str(),to_s.c_str(),MYF(MY_WME)));
1 by brian
clean slate
1816
}
1817
1818
/*
1819
  DESCRIPTION
1820
    given a buffer with a key value, and a map of keyparts
1821
    that are present in this value, returns the length of the value
1822
*/
482 by Brian Aker
Remove uint.
1823
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.
1824
                       const unsigned char *,
1 by brian
clean slate
1825
                       key_part_map keypart_map)
1826
{
1827
  /* works only with key prefixes */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
1828
  assert(((keypart_map + 1) & keypart_map) == 0);
1 by brian
clean slate
1829
1830
  KEY *key_info= table->s->key_info+key;
1831
  KEY_PART_INFO *key_part= key_info->key_part;
1832
  KEY_PART_INFO *end_key_part= key_part + key_info->key_parts;
482 by Brian Aker
Remove uint.
1833
  uint32_t length= 0;
1 by brian
clean slate
1834
1835
  while (key_part < end_key_part && keypart_map)
1836
  {
1837
    length+= key_part->store_length;
1838
    keypart_map >>= 1;
1839
    key_part++;
1840
  }
1841
  return length;
1842
}
1843
1844
/*
1845
  Check if database name is valid
1846
1847
  SYNPOSIS
1848
    check_db_name()
1849
    org_name		Name of database and length
1850
1851
  RETURN
1852
    0	ok
1853
    1   error
1854
*/
1855
1856
bool check_db_name(LEX_STRING *org_name)
1857
{
1858
  char *name= org_name->str;
482 by Brian Aker
Remove uint.
1859
  uint32_t name_length= org_name->length;
1 by brian
clean slate
1860
1861
  if (!name_length || name_length > NAME_LEN || name[name_length - 1] == ' ')
1862
    return 1;
1863
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
1864
  if (name != any_db)
1 by brian
clean slate
1865
    my_casedn_str(files_charset_info, name);
1866
1867
  return check_identifier_name(org_name);
1868
}
1869
1870
1871
/*
1872
  Allow anything as a table name, as long as it doesn't contain an
1873
  ' ' at the end
1874
  returns 1 on error
1875
*/
482 by Brian Aker
Remove uint.
1876
bool check_table_name(const char *name, uint32_t length)
1 by brian
clean slate
1877
{
1878
  if (!length || length > NAME_LEN || name[length - 1] == ' ')
1879
    return 1;
1880
  LEX_STRING ident;
1881
  ident.str= (char*) name;
1882
  ident.length= length;
1883
  return check_identifier_name(&ident);
1884
}
1885
1886
1887
/*
1888
  Eventually, a "length" argument should be added
1889
  to this function, and the inner loop changed to
1890
  check_identifier_name() call.
1891
*/
1892
bool check_column_name(const char *name)
1893
{
482 by Brian Aker
Remove uint.
1894
  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
1895
  bool last_char_is_space= true;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1896
1 by brian
clean slate
1897
  while (*name)
1898
  {
1899
    last_char_is_space= my_isspace(system_charset_info, *name);
1900
    if (use_mb(system_charset_info))
1901
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1902
      int len=my_ismbchar(system_charset_info, name,
1 by brian
clean slate
1903
                          name+system_charset_info->mbmaxlen);
1904
      if (len)
1905
      {
1906
        if (len > 3) /* Disallow non-BMP characters */
1907
          return 1;
1908
        name += len;
1909
        name_length++;
1910
        continue;
1911
      }
1912
    }
1913
    /*
1914
      NAMES_SEP_CHAR is used in FRM format to separate SET and ENUM values.
1915
      It is defined as 0xFF, which is a not valid byte in utf8.
1916
      This assert is to catch use of this byte if we decide to
1917
      use non-utf8 as system_character_set.
1918
    */
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
1919
    assert(*name != NAMES_SEP_CHAR);
1 by brian
clean slate
1920
    name++;
1921
    name_length++;
1922
  }
1923
  /* Error if empty or too long column name */
895 by Brian Aker
Completion (?) of uint conversion.
1924
  return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
1 by brian
clean slate
1925
}
1926
1927
1928
/*****************************************************************************
1929
  Functions to handle column usage bitmaps (read_set, write_set etc...)
1930
*****************************************************************************/
1931
1932
/* Reset all columns bitmaps */
1933
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
1934
void Table::clear_column_bitmaps()
1 by brian
clean slate
1935
{
1936
  /*
1005.2.3 by Monty Taylor
Further reversion of P.
1937
    Reset column read/write usage. It's identical to:
1938
    bitmap_clear_all(&table->def_read_set);
1939
    bitmap_clear_all(&table->def_write_set);
1 by brian
clean slate
1940
  */
1005.2.3 by Monty Taylor
Further reversion of P.
1941
  memset(def_read_set.bitmap, 0, s->column_bitmap_size*2);
1 by brian
clean slate
1942
  column_bitmaps_set(&def_read_set, &def_write_set);
1943
}
1944
1945
1946
/*
1947
  Tell handler we are going to call position() and rnd_pos() later.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
1948
1 by brian
clean slate
1949
  NOTES:
1950
  This is needed for handlers that uses the primary key to find the
1951
  row. In this case we have to extend the read bitmap with the primary
1952
  key fields.
1953
*/
1954
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
1955
void Table::prepare_for_position()
1 by brian
clean slate
1956
{
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
1957
1 by brian
clean slate
1958
  if ((file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
1959
      s->primary_key < MAX_KEY)
1960
  {
1003.1.7 by Brian Aker
Add mark_columns_used_by_index_no_reset() with just index (assumes read_set
1961
    mark_columns_used_by_index_no_reset(s->primary_key);
1 by brian
clean slate
1962
  }
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
1963
  return;
1 by brian
clean slate
1964
}
1965
1966
1967
/*
1968
  Mark that only fields from one key is used
1969
1970
  NOTE:
1971
    This changes the bitmap to use the tmp bitmap
1972
    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).
1973
    bitmaps are reset, for example with Table::clear_column_bitmaps()
1974
    or Table::restore_column_maps_after_mark_index()
1 by brian
clean slate
1975
*/
1976
482 by Brian Aker
Remove uint.
1977
void Table::mark_columns_used_by_index(uint32_t index)
1 by brian
clean slate
1978
{
1005.2.3 by Monty Taylor
Further reversion of P.
1979
  MY_BITMAP *bitmap= &tmp_set;
1 by brian
clean slate
1980
1981
  (void) file->extra(HA_EXTRA_KEYREAD);
1005.2.3 by Monty Taylor
Further reversion of P.
1982
  bitmap_clear_all(bitmap);
1 by brian
clean slate
1983
  mark_columns_used_by_index_no_reset(index, bitmap);
1984
  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
1985
  return;
1 by brian
clean slate
1986
}
1987
1988
1989
/*
1990
  Restore to use normal column maps after key read
1991
1992
  NOTES
1993
    This reverse the change done by mark_columns_used_by_index
1994
1995
  WARNING
1996
    For this to work, one must have the normal table maps in place
1997
    when calling mark_columns_used_by_index
1998
*/
1999
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2000
void Table::restore_column_maps_after_mark_index()
1 by brian
clean slate
2001
{
2002
2003
  key_read= 0;
2004
  (void) file->extra(HA_EXTRA_NO_KEYREAD);
2005
  default_column_bitmaps();
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
2006
  return;
1 by brian
clean slate
2007
}
2008
2009
2010
/*
2011
  mark columns used by key, but don't reset other fields
2012
*/
2013
1003.1.7 by Brian Aker
Add mark_columns_used_by_index_no_reset() with just index (assumes read_set
2014
void Table::mark_columns_used_by_index_no_reset(uint32_t index)
2015
{
2016
    mark_columns_used_by_index_no_reset(index, read_set);
2017
}
2018
482 by Brian Aker
Remove uint.
2019
void Table::mark_columns_used_by_index_no_reset(uint32_t index,
1005.2.4 by Monty Taylor
Patch cleaning.
2020
                                                MY_BITMAP *bitmap)
1 by brian
clean slate
2021
{
2022
  KEY_PART_INFO *key_part= key_info[index].key_part;
2023
  KEY_PART_INFO *key_part_end= (key_part +
2024
                                key_info[index].key_parts);
2025
  for (;key_part != key_part_end; key_part++)
1005.2.4 by Monty Taylor
Patch cleaning.
2026
    bitmap_set_bit(bitmap, key_part->fieldnr-1);
1 by brian
clean slate
2027
}
2028
2029
2030
/*
2031
  Mark auto-increment fields as used fields in both read and write maps
2032
2033
  NOTES
2034
    This is needed in insert & update as the auto-increment field is
2035
    always set and sometimes read.
2036
*/
2037
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2038
void Table::mark_auto_increment_column()
1 by brian
clean slate
2039
{
51.2.1 by Patrick Galbraith
Removed DBUG_PRINTs, DBUG_ASSERTs, DBUG_EXECUTE_IFs from
2040
  assert(found_next_number_field);
1 by brian
clean slate
2041
  /*
2042
    We must set bit in read set as update_auto_increment() is using the
2043
    store() to check overflow of auto_increment values
2044
  */
1005.2.12 by Monty Taylor
Moved some things to the API.
2045
  setReadSet(found_next_number_field->field_index);
2046
  setWriteSet(found_next_number_field->field_index);
1 by brian
clean slate
2047
  if (s->next_number_keypart)
1003.1.7 by Brian Aker
Add mark_columns_used_by_index_no_reset() with just index (assumes read_set
2048
    mark_columns_used_by_index_no_reset(s->next_number_index);
1 by brian
clean slate
2049
}
2050
2051
2052
/*
2053
  Mark columns needed for doing an delete of a row
2054
2055
  DESCRIPTON
2056
    Some table engines don't have a cursor on the retrieve rows
2057
    so they need either to use the primary key or all columns to
2058
    be able to delete a row.
2059
2060
    If the engine needs this, the function works as follows:
2061
    - If primary key exits, mark the primary key columns to be read.
2062
    - If not, mark all columns to be read
2063
2064
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
2065
    mark all key columns as 'to-be-read'. This allows the engine to
2066
    loop over the given record to find all keys and doesn't have to
2067
    retrieve the row again.
2068
*/
2069
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2070
void Table::mark_columns_needed_for_delete()
1 by brian
clean slate
2071
{
1003.1.8 by Brian Aker
The call for setting columns was backwards (engines with certain callers
2072
  /*
2073
    If the handler has no cursor capabilites, or we have row-based
2074
    replication active for the current statement, we have to read
2075
    either the primary key, the hidden primary key or all columns to
2076
    be able to do an delete
2077
2078
  */
2079
  if (s->primary_key == MAX_KEY)
2080
  {
2081
    /* fallback to use all columns in the table to identify row */
2082
    use_all_columns();
2083
    return;
2084
  }
2085
  else
2086
    mark_columns_used_by_index_no_reset(s->primary_key);
2087
2088
  /* If we the engine wants all predicates we mark all keys */
1 by brian
clean slate
2089
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2090
  {
2091
    Field **reg_field;
2092
    for (reg_field= field ; *reg_field ; reg_field++)
2093
    {
2094
      if ((*reg_field)->flags & PART_KEY_FLAG)
1005.2.12 by Monty Taylor
Moved some things to the API.
2095
        setReadSet((*reg_field)->field_index);
1 by brian
clean slate
2096
    }
2097
  }
2098
}
2099
2100
2101
/*
2102
  Mark columns needed for doing an update of a row
2103
2104
  DESCRIPTON
2105
    Some engines needs to have all columns in an update (to be able to
2106
    build a complete row). If this is the case, we mark all not
2107
    updated columns to be read.
2108
2109
    If this is no the case, we do like in the delete case and mark
2110
    if neeed, either the primary key column or all columns to be read.
2111
    (see mark_columns_needed_for_delete() for details)
2112
2113
    If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will
2114
    mark all USED key columns as 'to-be-read'. This allows the engine to
2115
    loop over the given record to find all changed keys and doesn't have to
2116
    retrieve the row again.
2117
*/
2118
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2119
void Table::mark_columns_needed_for_update()
1 by brian
clean slate
2120
{
1003.1.8 by Brian Aker
The call for setting columns was backwards (engines with certain callers
2121
  /*
2122
    If the handler has no cursor capabilites, or we have row-based
2123
    logging active for the current statement, we have to read either
2124
    the primary key, the hidden primary key or all columns to be
2125
    able to do an update
2126
  */
2127
  if (s->primary_key == MAX_KEY)
2128
  {
2129
    /* fallback to use all columns in the table to identify row */
2130
    use_all_columns();
2131
    return;
2132
  }
2133
  else
2134
    mark_columns_used_by_index_no_reset(s->primary_key);
2135
1 by brian
clean slate
2136
  if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
2137
  {
2138
    /* Mark all used key columns for read */
2139
    Field **reg_field;
2140
    for (reg_field= field ; *reg_field ; reg_field++)
2141
    {
2142
      /* Merge keys is all keys that had a column refered to in the query */
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2143
      if (is_overlapping(merge_keys, (*reg_field)->part_of_key))
1005.2.12 by Monty Taylor
Moved some things to the API.
2144
        setReadSet((*reg_field)->field_index);
1 by brian
clean slate
2145
    }
2146
  }
798.2.21 by Brian Aker
More work on binlog.poen
2147
1 by brian
clean slate
2148
}
2149
2150
2151
/*
2152
  Mark columns the handler needs for doing an insert
2153
2154
  For now, this is used to mark fields used by the trigger
2155
  as changed.
2156
*/
2157
327.1.1 by Brian Aker
First pass in encapsulating table (it is now an object, no longer a structure).
2158
void Table::mark_columns_needed_for_insert()
1 by brian
clean slate
2159
{
2160
  if (found_next_number_field)
2161
    mark_auto_increment_column();
383.7.1 by Andrey Zhakov
Initial submit of code and tests
2162
}
2163
1 by brian
clean slate
2164
2165
481 by Brian Aker
Remove all of uchar.
2166
size_t Table::max_row_length(const unsigned char *data)
1 by brian
clean slate
2167
{
354 by Brian Aker
Refactor of Table methods.
2168
  size_t length= getRecordLength() + 2 * sizeFields();
482 by Brian Aker
Remove uint.
2169
  uint32_t *const beg= getBlobField();
2170
  uint32_t *const end= beg + sizeBlobFields();
1 by brian
clean slate
2171
482 by Brian Aker
Remove uint.
2172
  for (uint32_t *ptr= beg ; ptr != end ; ++ptr)
1 by brian
clean slate
2173
  {
354 by Brian Aker
Refactor of Table methods.
2174
    Field_blob* const blob= (Field_blob*) field[*ptr];
481 by Brian Aker
Remove all of uchar.
2175
    length+= blob->get_length((const unsigned char*)
354 by Brian Aker
Refactor of Table methods.
2176
                              (data + blob->offset(record[0]))) +
1 by brian
clean slate
2177
      HA_KEY_BLOB_LENGTH;
2178
  }
2179
  return length;
2180
}
2181
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2182
/****************************************************************************
2183
 Functions for creating temporary tables.
2184
****************************************************************************/
2185
2186
2187
/* Prototypes */
520.1.22 by Brian Aker
Second pass of thd cleanup
2188
void free_tmp_table(Session *session, Table *entry);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2189
2190
/**
2191
  Create field for temporary table from given field.
2192
520.1.22 by Brian Aker
Second pass of thd cleanup
2193
  @param session	       Thread handler
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2194
  @param org_field    field from which new field will be created
2195
  @param name         New field name
2196
  @param table	       Temporary table
2197
  @param item	       !=NULL if item->result_field should point to new field.
2198
                      This is relevant for how fill_record() is going to work:
2199
                      If item != NULL then fill_record() will update
2200
                      the record in the original table.
2201
                      If item == NULL then fill_record() will update
2202
                      the temporary table
2203
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
2204
                               field instead of blob.
2205
2206
  @retval
2207
    NULL		on error
2208
  @retval
2209
    new_created field
2210
*/
2211
520.1.22 by Brian Aker
Second pass of thd cleanup
2212
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
2213
                                   const char *name, Table *table,
482 by Brian Aker
Remove uint.
2214
                                   Item_field *item, uint32_t convert_blob_length)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2215
{
2216
  Field *new_field;
2217
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2218
  /*
2219
    Make sure that the blob fits into a Field_varstring which has
2220
    2-byte lenght.
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2221
  */
2222
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
2223
      (org_field->flags & BLOB_FLAG))
2224
    new_field= new Field_varstring(convert_blob_length,
2225
                                   org_field->maybe_null(),
2226
                                   org_field->field_name, table->s,
2227
                                   org_field->charset());
2228
  else
520.1.22 by Brian Aker
Second pass of thd cleanup
2229
    new_field= org_field->new_field(session->mem_root, table,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2230
                                    table == org_field->table);
2231
  if (new_field)
2232
  {
2233
    new_field->init(table);
2234
    new_field->orig_table= org_field->orig_table;
2235
    if (item)
2236
      item->result_field= new_field;
2237
    else
2238
      new_field->field_name= name;
2239
    new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
2240
    if (org_field->maybe_null() || (item && item->maybe_null))
2241
      new_field->flags&= ~NOT_NULL_FLAG;	// Because of outer join
2242
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
2243
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
2244
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
2245
      ((Field_double *) new_field)->not_fixed= true;
2246
  }
2247
  return new_field;
2248
}
2249
2250
2251
/**
2252
  Create field for information schema table.
2253
520.1.22 by Brian Aker
Second pass of thd cleanup
2254
  @param session		Thread handler
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2255
  @param table		Temporary table
2256
  @param item		Item to create a field for
2257
2258
  @retval
2259
    0			on error
2260
  @retval
2261
    new_created field
2262
*/
2263
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
2264
static Field *create_tmp_field_for_schema(Item *item, Table *table)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2265
{
2266
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
2267
  {
2268
    Field *field;
2269
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
2270
      field= new Field_blob(item->max_length, item->maybe_null,
2271
                            item->name, item->collation.collation);
2272
    else
2273
      field= new Field_varstring(item->max_length, item->maybe_null,
2274
                                 item->name,
2275
                                 table->s, item->collation.collation);
2276
    if (field)
2277
      field->init(table);
2278
    return field;
2279
  }
2280
  return item->tmp_table_field_from_field_type(table, 0);
2281
}
2282
2283
2284
/**
2285
  Create a temp table according to a field list.
2286
2287
  Given field pointers are changed to point at tmp_table for
2288
  send_fields. The table object is self contained: it's
2289
  allocated in its own memory root, as well as Field objects
2290
  created for table columns.
2291
  This function will replace Item_sum items in 'fields' list with
2292
  corresponding Item_field items, pointing at the fields in the
2293
  temporary table, unless this was prohibited by true
2294
  value of argument save_sum_fields. The Item_field objects
520.1.21 by Brian Aker
THD -> Session rename
2295
  are created in Session memory root.
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2296
520.1.22 by Brian Aker
Second pass of thd cleanup
2297
  @param session                  thread handle
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2298
  @param param                a description used as input to create the table
2299
  @param fields               list of items that will be used to define
2300
                              column types of the table (also see NOTES)
2301
  @param group                TODO document
2302
  @param distinct             should table rows be distinct
2303
  @param save_sum_fields      see NOTES
2304
  @param select_options
2305
  @param rows_limit
2306
  @param table_alias          possible name of the temporary table that can
2307
                              be used for name resolving; can be "".
2308
*/
2309
2310
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
2311
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
2312
#define RATIO_TO_PACK_ROWS	       2
2313
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2314
Table *
851 by Brian Aker
Class rewrite of Session (aka get all of the junk out)
2315
create_tmp_table(Session *session,Tmp_Table_Param *param,List<Item> &fields,
327.2.3 by Brian Aker
Refactoring of class Table
2316
		 order_st *group, bool distinct, bool save_sum_fields,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2317
		 uint64_t select_options, ha_rows rows_limit,
1039.1.4 by Brian Aker
Modified alias to being const.
2318
		 const char *table_alias)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2319
{
2320
  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
2321
  Table *table;
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
2322
  TableShare *share;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2323
  uint	i,field_count,null_count,null_pack_length;
482 by Brian Aker
Remove uint.
2324
  uint32_t  copy_func_count= param->func_count;
2325
  uint32_t  hidden_null_count, hidden_null_pack_length, hidden_field_count;
2326
  uint32_t  blob_count,group_null_items, string_count;
2327
  uint32_t fieldnr= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2328
  ulong reclength, string_total_length;
2329
  bool  using_unique_constraint= 0;
2330
  bool  use_packed_rows= 0;
2331
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
2332
  char  *tmpname,path[FN_REFLEN];
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
2333
  unsigned char	*pos, *group_buff, *bitmaps;
481 by Brian Aker
Remove all of uchar.
2334
  unsigned char *null_flags;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2335
  Field **reg_field, **from_field, **default_field;
482 by Brian Aker
Remove uint.
2336
  uint32_t *blob_field;
1052.2.2 by Nathan Williams
No actual code changes. Changed Copy_field to CopyField, to reflect the coding standards.
2337
  CopyField *copy= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2338
  KEY *keyinfo;
2339
  KEY_PART_INFO *key_part_info;
2340
  Item **copy_func;
2341
  MI_COLUMNDEF *recinfo;
482 by Brian Aker
Remove uint.
2342
  uint32_t total_uneven_bit_length= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2343
  bool force_copy_fields= param->force_copy_fields;
2344
520.1.22 by Brian Aker
Second pass of thd cleanup
2345
  status_var_increment(session->status_var.created_tmp_tables);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2346
1014.2.12 by Monty Taylor
Removed the thread-safe crap in MY_BITMAP. Also remove the temp-pool option for
2347
  /* if we run out of slots or we are not using tempool */
2348
  sprintf(path,"%s%lx_%"PRIx64"_%x", TMP_FILE_PREFIX, (unsigned long)current_pid,
2349
          session->thread_id, session->tmp_table++);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2350
2351
  /*
2352
    No need to change table name to lower case as we are only creating
2353
    MyISAM or HEAP tables here
2354
  */
575.4.3 by ysano
Rename mysql to drizzle.
2355
  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.
2356
2357
2358
  if (group)
2359
  {
2360
    if (!param->quick_group)
1046.1.6 by Brian Aker
Formatting/style cleanup.
2361
      group= 0;					// Can't use group key
327.2.3 by Brian Aker
Refactoring of class Table
2362
    else for (order_st *tmp=group ; tmp ; tmp=tmp->next)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2363
    {
2364
      /*
2365
        marker == 4 means two things:
2366
        - store NULLs in the key, and
2367
        - convert BIT fields to 64-bit long, needed because MEMORY tables
2368
          can't index BIT fields.
2369
      */
2370
      (*tmp->item)->marker= 4;
2371
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
2372
	using_unique_constraint=1;
2373
    }
2374
    if (param->group_length >= MAX_BLOB_WIDTH)
2375
      using_unique_constraint=1;
2376
    if (group)
1046.1.6 by Brian Aker
Formatting/style cleanup.
2377
      distinct= 0;				// Can't use distinct
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2378
  }
2379
2380
  field_count=param->field_count+param->func_count+param->sum_func_count;
2381
  hidden_field_count=param->hidden_field_count;
2382
2383
  /*
2384
    When loose index scan is employed as access method, it already
2385
    computes all groups and the result of all aggregate functions. We
2386
    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)
2387
    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.
2388
    these items are stored in the temporary table.
2389
  */
2390
  if (param->precomputed_group_by)
2391
    copy_func_count+= param->sum_func_count;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2392
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2393
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
2394
2395
  if (!multi_alloc_root(&own_root,
2396
                        &table, sizeof(*table),
2397
                        &share, sizeof(*share),
2398
                        &reg_field, sizeof(Field*) * (field_count+1),
2399
                        &default_field, sizeof(Field*) * (field_count),
895 by Brian Aker
Completion (?) of uint conversion.
2400
                        &blob_field, sizeof(uint32_t)*(field_count+1),
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2401
                        &from_field, sizeof(Field*)*field_count,
2402
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
2403
                        &param->keyinfo, sizeof(*param->keyinfo),
2404
                        &key_part_info,
2405
                        sizeof(*key_part_info)*(param->group_parts+1),
2406
                        &param->start_recinfo,
2407
                        sizeof(*param->recinfo)*(field_count*2+4),
895 by Brian Aker
Completion (?) of uint conversion.
2408
                        &tmpname, (uint32_t) strlen(path)+1,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2409
                        &group_buff, (group && ! using_unique_constraint ?
2410
                                      param->group_length : 0),
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
2411
                        &bitmaps, bitmap_buffer_size(field_count)*2,
461 by Monty Taylor
Removed NullS. bu-bye.
2412
                        NULL))
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2413
  {
1019.1.6 by Brian Aker
A number of random cleanups.
2414
    return NULL;				/* purecov: inspected */
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2415
  }
1052.2.2 by Nathan Williams
No actual code changes. Changed Copy_field to CopyField, to reflect the coding standards.
2416
  /* CopyField belongs to Tmp_Table_Param, allocate it in Session mem_root */
2417
  if (!(param->copy_field= copy= new (session->mem_root) CopyField[field_count]))
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2418
  {
2419
    free_root(&own_root, MYF(0));               /* purecov: inspected */
1019.1.6 by Brian Aker
A number of random cleanups.
2420
    return NULL;				/* purecov: inspected */
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2421
  }
2422
  param->items_to_copy= copy_func;
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
2423
  strcpy(tmpname,path);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2424
  /* make table according to fields */
2425
2426
  memset(table, 0, sizeof(*table));
2427
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
2428
  memset(default_field, 0, sizeof(Field*) * (field_count));
2429
  memset(from_field, 0, sizeof(Field*)*field_count);
2430
2431
  table->mem_root= own_root;
520.1.22 by Brian Aker
Second pass of thd cleanup
2432
  mem_root_save= session->mem_root;
2433
  session->mem_root= &table->mem_root;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2434
2435
  table->field=reg_field;
2436
  table->alias= table_alias;
2437
  table->reginfo.lock_type=TL_WRITE;	/* Will be updated */
2438
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
2439
  table->map=1;
2440
  table->copy_blobs= 1;
520.1.22 by Brian Aker
Second pass of thd cleanup
2441
  table->in_use= session;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2442
  table->quick_keys.reset();
2443
  table->covering_keys.reset();
2444
  table->keys_in_use_for_query.reset();
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2445
2446
  table->setShare(share);
1000.1.5 by Brian Aker
More refactoring back to TableShare object.
2447
  share->init(tmpname, tmpname);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2448
  share->blob_field= blob_field;
2449
  share->blob_ptr_size= portable_sizeof_char_ptr;
2450
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
2451
  share->table_charset= param->table_charset;
2452
  share->primary_key= MAX_KEY;               // Indicate no primary key
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
2453
  share->keys_for_keyread.reset();
2454
  share->keys_in_use.reset();
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2455
2456
  /* Calculate which type of fields we will store in the temporary table */
2457
2458
  reclength= string_total_length= 0;
2459
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
1046.1.6 by Brian Aker
Formatting/style cleanup.
2460
  param->using_indirect_summary_function= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2461
2462
  List_iterator_fast<Item> li(fields);
2463
  Item *item;
2464
  Field **tmp_from_field=from_field;
2465
  while ((item=li++))
2466
  {
2467
    Item::Type type=item->type();
2468
    if (not_all_columns)
2469
    {
2470
      if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
2471
      {
2472
        if (item->used_tables() & OUTER_REF_TABLE_BIT)
2473
          item->update_used_tables();
2474
        if (type == Item::SUBSELECT_ITEM ||
2475
            (item->used_tables() & ~OUTER_REF_TABLE_BIT))
2476
        {
2477
	  /*
2478
	    Mark that the we have ignored an item that refers to a summary
2479
	    function. We need to know this if someone is going to use
2480
	    DISTINCT on the result.
2481
	  */
2482
	  param->using_indirect_summary_function=1;
2483
	  continue;
2484
        }
2485
      }
2486
      if (item->const_item() && (int) hidden_field_count <= 0)
2487
        continue; // We don't have to store this
2488
    }
2489
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
2490
    {						/* Can't calc group yet */
1046.1.6 by Brian Aker
Formatting/style cleanup.
2491
      ((Item_sum*) item)->result_field= 0;
2492
      for (i= 0 ; i < ((Item_sum*) item)->arg_count ; i++)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2493
      {
2494
	Item **argp= ((Item_sum*) item)->args + i;
2495
	Item *arg= *argp;
2496
	if (!arg->const_item())
2497
	{
2498
	  Field *new_field=
520.1.22 by Brian Aker
Second pass of thd cleanup
2499
            create_tmp_field(session, table, arg, arg->type(), &copy_func,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2500
                             tmp_from_field, &default_field[fieldnr],
2501
                             group != 0,not_all_columns,
2502
                             distinct, 0,
2503
                             param->convert_blob_length);
2504
	  if (!new_field)
2505
	    goto err;					// Should be OOM
2506
	  tmp_from_field++;
2507
	  reclength+=new_field->pack_length();
2508
	  if (new_field->flags & BLOB_FLAG)
2509
	  {
2510
	    *blob_field++= fieldnr;
2511
	    blob_count++;
2512
	  }
2513
	  *(reg_field++)= new_field;
2514
          if (new_field->real_type() == DRIZZLE_TYPE_VARCHAR)
2515
          {
2516
            string_count++;
2517
            string_total_length+= new_field->pack_length();
2518
          }
520.1.22 by Brian Aker
Second pass of thd cleanup
2519
          session->mem_root= mem_root_save;
2520
          session->change_item_tree(argp, new Item_field(new_field));
2521
          session->mem_root= &table->mem_root;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2522
	  if (!(new_field->flags & NOT_NULL_FLAG))
2523
          {
2524
	    null_count++;
2525
            /*
2526
              new_field->maybe_null() is still false, it will be
2527
              changed below. But we have to setup Item_field correctly
2528
            */
2529
            (*argp)->maybe_null=1;
2530
          }
2531
          new_field->field_index= fieldnr++;
2532
	}
2533
      }
2534
    }
2535
    else
2536
    {
2537
      /*
2538
	The last parameter to create_tmp_field() is a bit tricky:
2539
2540
	We need to set it to 0 in union, to get fill_record() to modify the
2541
	temporary table.
2542
	We need to set it to 1 on multi-table-update and in select to
2543
	write rows to the temporary table.
2544
	We here distinguish between UNION and multi-table-updates by the fact
2545
	that in the later case group is set to the row pointer.
2546
      */
2547
      Field *new_field= (param->schema_table) ?
1014.3.4 by Brian Aker
Remove dead session calls.
2548
        create_tmp_field_for_schema(item, table) :
520.1.22 by Brian Aker
Second pass of thd cleanup
2549
        create_tmp_field(session, table, item, type, &copy_func,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2550
                         tmp_from_field, &default_field[fieldnr],
2551
                         group != 0,
2552
                         !force_copy_fields &&
1046.1.6 by Brian Aker
Formatting/style cleanup.
2553
                           (not_all_columns || group != 0),
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2554
                         /*
2555
                           If item->marker == 4 then we force create_tmp_field
2556
                           to create a 64-bit longs for BIT fields because HEAP
2557
                           tables can't index BIT fields directly. We do the same
2558
                           for distinct, as we want the distinct index to be
2559
                           usable in this case too.
2560
                         */
2561
                         item->marker == 4 || param->bit_fields_as_long,
2562
                         force_copy_fields,
2563
                         param->convert_blob_length);
2564
2565
      if (!new_field)
2566
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
2567
	if (session->is_fatal_error)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2568
	  goto err;				// Got OOM
2569
	continue;				// Some kindf of const item
2570
      }
2571
      if (type == Item::SUM_FUNC_ITEM)
2572
	((Item_sum *) item)->result_field= new_field;
2573
      tmp_from_field++;
2574
      reclength+=new_field->pack_length();
2575
      if (!(new_field->flags & NOT_NULL_FLAG))
2576
	null_count++;
2577
      if (new_field->flags & BLOB_FLAG)
2578
      {
2579
        *blob_field++= fieldnr;
2580
	blob_count++;
2581
      }
2582
      if (item->marker == 4 && item->maybe_null)
2583
      {
2584
	group_null_items++;
2585
	new_field->flags|= GROUP_FLAG;
2586
      }
2587
      new_field->field_index= fieldnr++;
2588
      *(reg_field++)= new_field;
2589
    }
2590
    if (!--hidden_field_count)
2591
    {
2592
      /*
2593
        This was the last hidden field; Remember how many hidden fields could
2594
        have null
2595
      */
2596
      hidden_null_count=null_count;
2597
      /*
2598
	We need to update hidden_field_count as we may have stored group
2599
	functions with constant arguments
2600
      */
2601
      param->hidden_field_count= fieldnr;
2602
      null_count= 0;
2603
    }
2604
  }
895 by Brian Aker
Completion (?) of uint conversion.
2605
  assert(fieldnr == (uint32_t) (reg_field - table->field));
2606
  assert(field_count >= (uint32_t) (reg_field - table->field));
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2607
  field_count= fieldnr;
2608
  *reg_field= 0;
2609
  *blob_field= 0;				// End marker
2610
  share->fields= field_count;
2611
2612
  /* If result table is small; use a heap */
2613
  /* future: storage engine selection can be made dynamic? */
2614
  if (blob_count || using_unique_constraint ||
2615
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
2616
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
2617
  {
971.1.21 by Monty Taylor
Store StorageEngine in system variables, rather than storage engine plugin.
2618
    share->storage_engine= myisam_engine;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2619
    table->file= get_new_handler(share, &table->mem_root,
2620
                                 share->db_type());
2621
    if (group &&
2622
	(param->group_parts > table->file->max_key_parts() ||
2623
	 param->group_length > table->file->max_key_length()))
2624
      using_unique_constraint=1;
2625
  }
2626
  else
2627
  {
971.1.21 by Monty Taylor
Store StorageEngine in system variables, rather than storage engine plugin.
2628
    share->storage_engine= heap_engine;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2629
    table->file= get_new_handler(share, &table->mem_root,
2630
                                 share->db_type());
2631
  }
2632
  if (!table->file)
2633
    goto err;
2634
2635
2636
  if (!using_unique_constraint)
2637
    reclength+= group_null_items;	// null flag is stored separately
2638
2639
  share->blob_fields= blob_count;
2640
  if (blob_count == 0)
2641
  {
2642
    /* We need to ensure that first byte is not 0 for the delete link */
2643
    if (param->hidden_field_count)
2644
      hidden_null_count++;
2645
    else
2646
      null_count++;
2647
  }
2648
  hidden_null_pack_length=(hidden_null_count+7)/8;
2649
  null_pack_length= (hidden_null_pack_length +
2650
                     (null_count + total_uneven_bit_length + 7) / 8);
2651
  reclength+=null_pack_length;
2652
  if (!reclength)
2653
    reclength=1;				// Dummy select
2654
  /* Use packed rows if there is blobs or a lot of space to gain */
2655
  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)))
2656
    use_packed_rows= 1;
2657
2658
  share->reclength= reclength;
2659
  {
482 by Brian Aker
Remove uint.
2660
    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.
2661
    share->rec_buff_length= alloc_length;
481 by Brian Aker
Remove all of uchar.
2662
    if (!(table->record[0]= (unsigned char*)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2663
                            alloc_root(&table->mem_root, alloc_length*3)))
2664
      goto err;
2665
    table->record[1]= table->record[0]+alloc_length;
2666
    share->default_values= table->record[1]+alloc_length;
2667
  }
1046.1.6 by Brian Aker
Formatting/style cleanup.
2668
  copy_func[0]= 0;				// End marker
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2669
  param->func_count= copy_func - param->items_to_copy;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2670
1005.2.3 by Monty Taylor
Further reversion of P.
2671
  table->setup_tmp_table_column_bitmaps(bitmaps);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2672
2673
  recinfo=param->start_recinfo;
481 by Brian Aker
Remove all of uchar.
2674
  null_flags=(unsigned char*) table->record[0];
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2675
  pos=table->record[0]+ null_pack_length;
2676
  if (null_pack_length)
2677
  {
2678
    memset(recinfo, 0, sizeof(*recinfo));
2679
    recinfo->type=FIELD_NORMAL;
2680
    recinfo->length=null_pack_length;
2681
    recinfo++;
2682
    memset(null_flags, 255, null_pack_length);	// Set null fields
2683
481 by Brian Aker
Remove all of uchar.
2684
    table->null_flags= (unsigned char*) table->record[0];
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2685
    share->null_fields= null_count+ hidden_null_count;
2686
    share->null_bytes= null_pack_length;
2687
  }
2688
  null_count= (blob_count == 0) ? 1 : 0;
2689
  hidden_field_count=param->hidden_field_count;
1046.1.6 by Brian Aker
Formatting/style cleanup.
2690
  for (i= 0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2691
  {
2692
    Field *field= *reg_field;
482 by Brian Aker
Remove uint.
2693
    uint32_t length;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2694
    memset(recinfo, 0, sizeof(*recinfo));
2695
2696
    if (!(field->flags & NOT_NULL_FLAG))
2697
    {
2698
      if (field->flags & GROUP_FLAG && !using_unique_constraint)
2699
      {
2700
	/*
2701
	  We have to reserve one byte here for NULL bits,
2702
	  as this is updated by 'end_update()'
2703
	*/
1063.5.1 by Patrick
Fix for Centos 5.2
2704
	*pos++= '\0';				// Null is stored here
1046.1.6 by Brian Aker
Formatting/style cleanup.
2705
	recinfo->length= 1;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2706
	recinfo->type=FIELD_NORMAL;
2707
	recinfo++;
2708
	memset(recinfo, 0, sizeof(*recinfo));
2709
      }
2710
      else
2711
      {
2712
	recinfo->null_bit= 1 << (null_count & 7);
2713
	recinfo->null_pos= null_count/8;
2714
      }
2715
      field->move_field(pos,null_flags+null_count/8,
2716
			1 << (null_count & 7));
2717
      null_count++;
2718
    }
2719
    else
481 by Brian Aker
Remove all of uchar.
2720
      field->move_field(pos,(unsigned char*) 0,0);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2721
    field->reset();
2722
2723
    /*
2724
      Test if there is a default field value. The test for ->ptr is to skip
2725
      'offset' fields generated by initalize_tables
2726
    */
2727
    if (default_field[i] && default_field[i]->ptr)
2728
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2729
      /*
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2730
         default_field[i] is set only in the cases  when 'field' can
2731
         inherit the default value that is defined for the field referred
2732
         by the Item_field object from which 'field' has been created.
2733
      */
2734
      my_ptrdiff_t diff;
2735
      Field *orig_field= default_field[i];
2736
      /* Get the value from default_values */
2737
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
2738
                            orig_field->table->record[0]);
2739
      orig_field->move_field_offset(diff);      // Points now at default_values
2740
      if (orig_field->is_real_null())
2741
        field->set_null();
2742
      else
2743
      {
2744
        field->set_notnull();
2745
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
2746
      }
2747
      orig_field->move_field_offset(-diff);     // Back to record[0]
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2748
    }
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2749
2750
    if (from_field[i])
2751
    {						/* Not a table Item */
2752
      copy->set(field,from_field[i],save_sum_fields);
2753
      copy++;
2754
    }
2755
    length=field->pack_length();
2756
    pos+= length;
2757
2758
    /* Make entry for create table */
2759
    recinfo->length=length;
2760
    if (field->flags & BLOB_FLAG)
2761
      recinfo->type= (int) FIELD_BLOB;
2762
    else
2763
      recinfo->type=FIELD_NORMAL;
2764
    if (!--hidden_field_count)
2765
      null_count=(null_count+7) & ~7;		// move to next byte
2766
2767
    // fix table name in field entry
2768
    field->table_name= &table->alias;
2769
  }
2770
2771
  param->copy_field_end=copy;
2772
  param->recinfo=recinfo;
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
2773
  table->storeRecordAsDefault();        // Make empty default record
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2774
520.1.22 by Brian Aker
Second pass of thd cleanup
2775
  if (session->variables.tmp_table_size == ~ (uint64_t) 0)		// No limit
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2776
    share->max_rows= ~(ha_rows) 0;
2777
  else
960.2.25 by Monty Taylor
First step of hton rename.
2778
    share->max_rows= (ha_rows) (((share->db_type() == heap_engine) ?
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
2779
                                 min(session->variables.tmp_table_size,
520.1.22 by Brian Aker
Second pass of thd cleanup
2780
                                     session->variables.max_heap_table_size) :
2781
                                 session->variables.tmp_table_size) /
1067.4.1 by Nathan Williams
First few changes at converting cmin to std::min.
2782
                                 share->reclength);
2783
937.2.6 by Stewart Smith
make set_if_bigger typesafe for C and C++. Fix up everywhere.
2784
  set_if_bigger(share->max_rows,(ha_rows)1);	// For dummy start options
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2785
  /*
2786
    Push the LIMIT clause to the temporary table creation, so that we
2787
    materialize only up to 'rows_limit' records instead of all result records.
2788
  */
2789
  set_if_smaller(share->max_rows, rows_limit);
2790
  param->end_write_records= rows_limit;
2791
2792
  keyinfo= param->keyinfo;
2793
2794
  if (group)
2795
  {
2796
    table->group=group;				/* Table is grouped by key */
2797
    param->group_buff=group_buff;
2798
    share->keys=1;
2799
    share->uniques= test(using_unique_constraint);
2800
    table->key_info=keyinfo;
2801
    keyinfo->key_part=key_part_info;
2802
    keyinfo->flags=HA_NOSAME;
2803
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
1046.1.6 by Brian Aker
Formatting/style cleanup.
2804
    keyinfo->key_length= 0;
2805
    keyinfo->rec_per_key= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2806
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
2807
    keyinfo->name= (char*) "group_key";
327.2.3 by Brian Aker
Refactoring of class Table
2808
    order_st *cur_group= group;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2809
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
2810
    {
2811
      Field *field=(*cur_group->item)->get_tmp_table_field();
2812
      bool maybe_null=(*cur_group->item)->maybe_null;
1046.1.6 by Brian Aker
Formatting/style cleanup.
2813
      key_part_info->null_bit= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2814
      key_part_info->field=  field;
2815
      key_part_info->offset= field->offset(table->record[0]);
2816
      key_part_info->length= (uint16_t) field->key_length();
2817
      key_part_info->type=   (uint8_t) field->key_type();
2818
      key_part_info->key_type =
2819
	((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2820
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2821
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2822
	0 : FIELDFLAG_BINARY;
2823
      if (!using_unique_constraint)
2824
      {
2825
	cur_group->buff=(char*) group_buff;
520.1.22 by Brian Aker
Second pass of thd cleanup
2826
	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.
2827
                                                     group_buff +
2828
                                                     test(maybe_null),
2829
                                                     field->null_ptr,
2830
                                                     field->null_bit)))
2831
	  goto err; /* purecov: inspected */
2832
	if (maybe_null)
2833
	{
2834
	  /*
2835
	    To be able to group on NULL, we reserved place in group_buff
2836
	    for the NULL flag just before the column. (see above).
2837
	    The field data is after this flag.
2838
	    The NULL flag is updated in 'end_update()' and 'end_write()'
2839
	  */
2840
	  keyinfo->flags|= HA_NULL_ARE_EQUAL;	// def. that NULL == NULL
2841
	  key_part_info->null_bit=field->null_bit;
895 by Brian Aker
Completion (?) of uint conversion.
2842
	  key_part_info->null_offset= (uint32_t) (field->null_ptr -
481 by Brian Aker
Remove all of uchar.
2843
					      (unsigned char*) table->record[0]);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2844
          cur_group->buff++;                        // Pointer to field data
2845
	  group_buff++;                         // Skipp null flag
2846
	}
2847
        /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
2848
        key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
2849
	group_buff+= cur_group->field->pack_length();
2850
      }
2851
      keyinfo->key_length+=  key_part_info->length;
2852
    }
2853
  }
2854
2855
  if (distinct && field_count != param->hidden_field_count)
2856
  {
2857
    /*
2858
      Create an unique key or an unique constraint over all columns
2859
      that should be in the result.  In the temporary table, there are
2860
      'param->hidden_field_count' extra columns, whose null bits are stored
2861
      in the first 'hidden_null_pack_length' bytes of the row.
2862
    */
2863
    if (blob_count)
2864
    {
2865
      /*
2866
        Special mode for index creation in MyISAM used to support unique
2867
        indexes on blobs with arbitrary length. Such indexes cannot be
2868
        used for lookups.
2869
      */
2870
      share->uniques= 1;
2871
    }
2872
    null_pack_length-=hidden_null_pack_length;
2873
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
2874
			 (share->uniques ? test(null_pack_length) : 0));
2875
    table->distinct= 1;
2876
    share->keys= 1;
2877
    if (!(key_part_info= (KEY_PART_INFO*)
2878
          alloc_root(&table->mem_root,
2879
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
2880
      goto err;
2881
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
2882
    table->key_info=keyinfo;
2883
    keyinfo->key_part=key_part_info;
2884
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
2885
    keyinfo->key_length=(uint16_t) reclength;
2886
    keyinfo->name= (char*) "distinct_key";
2887
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
1046.1.6 by Brian Aker
Formatting/style cleanup.
2888
    keyinfo->rec_per_key= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2889
2890
    /*
2891
      Create an extra field to hold NULL bits so that unique indexes on
2892
      blobs can distinguish NULL from 0. This extra field is not needed
2893
      when we do not use UNIQUE indexes for blobs.
2894
    */
2895
    if (null_pack_length && share->uniques)
2896
    {
1046.1.6 by Brian Aker
Formatting/style cleanup.
2897
      key_part_info->null_bit= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2898
      key_part_info->offset=hidden_null_pack_length;
2899
      key_part_info->length=null_pack_length;
2900
      key_part_info->field= new Field_varstring(table->record[0],
2901
                                                (uint32_t) key_part_info->length,
2902
                                                0,
481 by Brian Aker
Remove all of uchar.
2903
                                                (unsigned char*) 0,
895 by Brian Aker
Completion (?) of uint conversion.
2904
                                                (uint32_t) 0,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2905
                                                Field::NONE,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2906
                                                NULL,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2907
                                                table->s,
2908
                                                &my_charset_bin);
2909
      if (!key_part_info->field)
2910
        goto err;
2911
      key_part_info->field->init(table);
2912
      key_part_info->key_type=FIELDFLAG_BINARY;
2913
      key_part_info->type=    HA_KEYTYPE_BINARY;
2914
      key_part_info++;
2915
    }
2916
    /* Create a distinct key over the columns we are going to return */
2917
    for (i=param->hidden_field_count, reg_field=table->field + i ;
2918
	 i < field_count;
2919
	 i++, reg_field++, key_part_info++)
2920
    {
1046.1.6 by Brian Aker
Formatting/style cleanup.
2921
      key_part_info->null_bit= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2922
      key_part_info->field=    *reg_field;
2923
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
2924
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
2925
      /* TODO:
2926
        The below method of computing the key format length of the
2927
        key part is a copy/paste from opt_range.cc, and table.cc.
2928
        This should be factored out, e.g. as a method of Field.
2929
        In addition it is not clear if any of the Field::*_length
2930
        methods is supposed to compute the same length. If so, it
2931
        might be reused.
2932
      */
2933
      key_part_info->store_length= key_part_info->length;
2934
2935
      if ((*reg_field)->real_maybe_null())
2936
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
2937
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB ||
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2938
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
2939
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
2940
2941
      key_part_info->type=     (uint8_t) (*reg_field)->key_type();
2942
      key_part_info->key_type =
2943
	((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
2944
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
2945
	 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
2946
	0 : FIELDFLAG_BINARY;
2947
    }
2948
  }
2949
520.1.22 by Brian Aker
Second pass of thd cleanup
2950
  if (session->is_fatal_error)				// If end of memory
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2951
    goto err;					 /* purecov: inspected */
2952
  share->db_record_offset= 1;
960.2.25 by Monty Taylor
First step of hton rename.
2953
  if (share->db_type() == myisam_engine)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2954
  {
2955
    if (table->create_myisam_tmp_table(param->keyinfo, param->start_recinfo,
2956
				       &param->recinfo, select_options))
2957
      goto err;
2958
  }
2959
  if (table->open_tmp_table())
2960
    goto err;
2961
520.1.22 by Brian Aker
Second pass of thd cleanup
2962
  session->mem_root= mem_root_save;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2963
2964
  return(table);
2965
2966
err:
520.1.22 by Brian Aker
Second pass of thd cleanup
2967
  session->mem_root= mem_root_save;
2968
  table->free_tmp_table(session);                    /* purecov: inspected */
1019.1.6 by Brian Aker
A number of random cleanups.
2969
  return NULL;				/* purecov: inspected */
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2970
}
2971
2972
/****************************************************************************/
2973
2974
/**
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2975
  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.
2976
  list of field definitions.
2977
2978
    The created table doesn't have a table handler associated with
2979
    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
2980
    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.
2981
    class to read/write data to/from table->record[0]. Then one can store
2982
    the record in any container (RB tree, hash, etc).
520.1.21 by Brian Aker
THD -> Session rename
2983
    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.
2984
    Consequently, if you don't BLOB fields, you don't need to free it.
2985
520.1.22 by Brian Aker
Second pass of thd cleanup
2986
  @param session         connection handle
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2987
  @param field_list  list of column definitions
2988
2989
  @return
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
2990
    0 if out of memory, Table object in case of success
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2991
*/
2992
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
2993
Table *create_virtual_tmp_table(Session *session, List<CreateField> &field_list)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2994
{
482 by Brian Aker
Remove uint.
2995
  uint32_t field_count= field_list.elements;
2996
  uint32_t blob_count= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
2997
  Field **field;
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
2998
  CreateField *cdef;                           /* column definition */
482 by Brian Aker
Remove uint.
2999
  uint32_t record_length= 0;
3000
  uint32_t null_count= 0;                 /* number of columns which may be null */
3001
  uint32_t null_pack_length;              /* NULL representation array length */
3002
  uint32_t *blob_field;
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
3003
  unsigned char *bitmaps;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3004
  Table *table;
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
3005
  TableShare *share;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3006
520.1.22 by Brian Aker
Second pass of thd cleanup
3007
  if (!multi_alloc_root(session->mem_root,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3008
                        &table, sizeof(*table),
3009
                        &share, sizeof(*share),
3010
                        &field, (field_count + 1) * sizeof(Field*),
895 by Brian Aker
Completion (?) of uint conversion.
3011
                        &blob_field, (field_count+1) *sizeof(uint32_t),
1005.2.1 by Monty Taylor
Reverted a crap-ton of padraig's work.
3012
                        &bitmaps, bitmap_buffer_size(field_count)*2,
461 by Monty Taylor
Removed NullS. bu-bye.
3013
                        NULL))
1046.1.7 by Brian Aker
Style cleanup.
3014
    return NULL;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3015
3016
  memset(table, 0, sizeof(*table));
3017
  memset(share, 0, sizeof(*share));
3018
  table->field= field;
3019
  table->s= share;
3020
  share->blob_field= blob_field;
3021
  share->fields= field_count;
3022
  share->blob_ptr_size= portable_sizeof_char_ptr;
1005.2.3 by Monty Taylor
Further reversion of P.
3023
  table->setup_tmp_table_column_bitmaps(bitmaps);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3024
3025
  /* Create all fields and calculate the total length of record */
1052.2.3 by Nathan Williams
No actual code changes. Changed Create_field to CreateField to be consistent with coding standards.
3026
  List_iterator_fast<CreateField> it(field_list);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3027
  while ((cdef= it++))
3028
  {
896.3.6 by Stewart Smith
Read Fields out of proto instead of FRM.
3029
    *field= make_field(share, NULL, 0, cdef->length,
481 by Brian Aker
Remove all of uchar.
3030
                       (unsigned char*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3031
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
3032
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
3033
                       cdef->unireg_check,
3034
                       cdef->interval, cdef->field_name);
3035
    if (!*field)
3036
      goto error;
3037
    (*field)->init(table);
3038
    record_length+= (*field)->pack_length();
3039
    if (! ((*field)->flags & NOT_NULL_FLAG))
3040
      null_count++;
3041
3042
    if ((*field)->flags & BLOB_FLAG)
895 by Brian Aker
Completion (?) of uint conversion.
3043
      share->blob_field[blob_count++]= (uint32_t) (field - table->field);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3044
3045
    field++;
3046
  }
3047
  *field= NULL;                             /* mark the end of the list */
3048
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
3049
  share->blob_fields= blob_count;
3050
3051
  null_pack_length= (null_count + 7)/8;
3052
  share->reclength= record_length + null_pack_length;
3053
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
520.1.22 by Brian Aker
Second pass of thd cleanup
3054
  table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3055
  if (!table->record[0])
3056
    goto error;
3057
3058
  if (null_pack_length)
3059
  {
481 by Brian Aker
Remove all of uchar.
3060
    table->null_flags= (unsigned char*) table->record[0];
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3061
    share->null_fields= null_count;
3062
    share->null_bytes= null_pack_length;
3063
  }
3064
520.1.22 by Brian Aker
Second pass of thd cleanup
3065
  table->in_use= session;           /* field->reset() may access table->in_use */
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3066
  {
3067
    /* Set up field pointers */
481 by Brian Aker
Remove all of uchar.
3068
    unsigned char *null_pos= table->record[0];
3069
    unsigned char *field_pos= null_pos + share->null_bytes;
482 by Brian Aker
Remove uint.
3070
    uint32_t null_bit= 1;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3071
3072
    for (field= table->field; *field; ++field)
3073
    {
3074
      Field *cur_field= *field;
3075
      if ((cur_field->flags & NOT_NULL_FLAG))
3076
        cur_field->move_field(field_pos);
3077
      else
3078
      {
481 by Brian Aker
Remove all of uchar.
3079
        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.
3080
        null_bit<<= 1;
3081
        if (null_bit == (1 << 8))
3082
        {
3083
          ++null_pos;
3084
          null_bit= 1;
3085
        }
3086
      }
3087
      cur_field->reset();
3088
3089
      field_pos+= cur_field->pack_length();
3090
    }
3091
  }
3092
  return table;
3093
error:
3094
  for (field= table->field; *field; ++field)
3095
    delete *field;                         /* just invokes field destructor */
3096
  return 0;
3097
}
3098
3099
bool Table::open_tmp_table()
3100
{
3101
  int error;
3102
  if ((error=file->ha_open(this, s->table_name.str,O_RDWR,
3103
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
3104
  {
3105
    file->print_error(error,MYF(0)); /* purecov: inspected */
1046.1.6 by Brian Aker
Formatting/style cleanup.
3106
    db_stat= 0;
3107
    return true;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3108
  }
3109
  (void) file->extra(HA_EXTRA_QUICK);		/* Faster */
1046.1.6 by Brian Aker
Formatting/style cleanup.
3110
  return false;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3111
}
3112
3113
3114
/*
3115
  Create MyISAM temporary table
3116
3117
  SYNOPSIS
3118
    create_myisam_tmp_table()
3119
      keyinfo         Description of the index (there is always one index)
3120
      start_recinfo   MyISAM's column descriptions
3121
      recinfo INOUT   End of MyISAM's column descriptions
3122
      options         Option bits
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3123
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3124
  DESCRIPTION
3125
    Create a MyISAM temporary table according to passed description. The is
3126
    assumed to have one unique index or constraint.
3127
3128
    The passed array or MI_COLUMNDEF structures must have this form:
3129
3130
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
3131
         when there are many nullable columns)
3132
      2. Table columns
3133
      3. One free MI_COLUMNDEF element (*recinfo points here)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3134
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3135
    This function may use the free element to create hash column for unique
3136
    constraint.
3137
3138
   RETURN
3139
     false - OK
3140
     true  - Error
3141
*/
3142
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3143
bool Table::create_myisam_tmp_table(KEY *keyinfo,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3144
                                    MI_COLUMNDEF *start_recinfo,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3145
                                    MI_COLUMNDEF **recinfo,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3146
				    uint64_t options)
3147
{
3148
  int error;
3149
  MI_KEYDEF keydef;
3150
  MI_UNIQUEDEF uniquedef;
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
3151
  TableShare *share= s;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3152
3153
  if (share->keys)
3154
  {						// Get keys for ni_create
1046.1.6 by Brian Aker
Formatting/style cleanup.
3155
    bool using_unique_constraint= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3156
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&this->mem_root,
3157
                                            sizeof(*seg) * keyinfo->key_parts);
3158
    if (!seg)
3159
      goto err;
3160
3161
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
3162
    if (keyinfo->key_length >= file->max_key_length() ||
3163
	keyinfo->key_parts > file->max_key_parts() ||
3164
	share->uniques)
3165
    {
3166
      /* Can't create a key; Make a unique constraint instead of a key */
3167
      share->keys=    0;
3168
      share->uniques= 1;
3169
      using_unique_constraint=1;
3170
      memset(&uniquedef, 0, sizeof(uniquedef));
3171
      uniquedef.keysegs=keyinfo->key_parts;
3172
      uniquedef.seg=seg;
3173
      uniquedef.null_are_equal=1;
3174
3175
      /* Create extra column for hash value */
3176
      memset(*recinfo, 0, sizeof(**recinfo));
3177
      (*recinfo)->type= FIELD_CHECK;
3178
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
3179
      (*recinfo)++;
3180
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
3181
    }
3182
    else
3183
    {
3184
      /* Create an unique key */
3185
      memset(&keydef, 0, sizeof(keydef));
3186
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
3187
      keydef.keysegs=  keyinfo->key_parts;
3188
      keydef.seg= seg;
3189
    }
1046.1.6 by Brian Aker
Formatting/style cleanup.
3190
    for (uint32_t i= 0; i < keyinfo->key_parts ; i++,seg++)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3191
    {
779.3.10 by Monty Taylor
Turned on -Wshadow.
3192
      Field *key_field=keyinfo->key_part[i].field;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3193
      seg->flag=     0;
779.3.10 by Monty Taylor
Turned on -Wshadow.
3194
      seg->language= key_field->charset()->number;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3195
      seg->length=   keyinfo->key_part[i].length;
3196
      seg->start=    keyinfo->key_part[i].offset;
779.3.10 by Monty Taylor
Turned on -Wshadow.
3197
      if (key_field->flags & BLOB_FLAG)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3198
      {
3199
	seg->type=
3200
	((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
3201
	 HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
779.3.10 by Monty Taylor
Turned on -Wshadow.
3202
	seg->bit_start= (uint8_t)(key_field->pack_length()
3203
                                  - share->blob_ptr_size);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3204
	seg->flag= HA_BLOB_PART;
1046.1.6 by Brian Aker
Formatting/style cleanup.
3205
	seg->length= 0;			// Whole blob in unique constraint
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3206
      }
3207
      else
3208
      {
3209
	seg->type= keyinfo->key_part[i].type;
3210
      }
779.3.10 by Monty Taylor
Turned on -Wshadow.
3211
      if (!(key_field->flags & NOT_NULL_FLAG))
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3212
      {
779.3.10 by Monty Taylor
Turned on -Wshadow.
3213
	seg->null_bit= key_field->null_bit;
895 by Brian Aker
Completion (?) of uint conversion.
3214
	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.
3215
	/*
3216
	  We are using a GROUP BY on something that contains NULL
3217
	  In this case we have to tell MyISAM that two NULL should
3218
	  on INSERT be regarded at the same value
3219
	*/
3220
	if (!using_unique_constraint)
3221
	  keydef.flag|= HA_NULL_ARE_EQUAL;
3222
      }
3223
    }
3224
  }
3225
  MI_CREATE_INFO create_info;
3226
  memset(&create_info, 0, sizeof(create_info));
3227
3228
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
3229
      OPTION_BIG_TABLES)
3230
    create_info.data_file_length= ~(uint64_t) 0;
3231
3232
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
895 by Brian Aker
Completion (?) of uint conversion.
3233
		       (uint32_t) (*recinfo-start_recinfo),
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3234
		       start_recinfo,
3235
		       share->uniques, &uniquedef,
3236
		       &create_info,
3237
		       HA_CREATE_TMP_TABLE)))
3238
  {
3239
    file->print_error(error,MYF(0));	/* purecov: inspected */
1046.1.6 by Brian Aker
Formatting/style cleanup.
3240
    db_stat= 0;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3241
    goto err;
3242
  }
3243
  status_var_increment(in_use->status_var.created_tmp_disk_tables);
3244
  share->db_record_offset= 1;
3245
  return false;
3246
 err:
3247
  return true;
3248
}
3249
3250
520.1.22 by Brian Aker
Second pass of thd cleanup
3251
void Table::free_tmp_table(Session *session)
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3252
{
3253
  MEM_ROOT own_root= mem_root;
3254
  const char *save_proc_info;
3255
520.1.22 by Brian Aker
Second pass of thd cleanup
3256
  save_proc_info=session->get_proc_info();
3257
  session->set_proc_info("removing tmp table");
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3258
873.2.11 by Monty Taylor
call ha_release_temporary_latches
3259
  // Release latches since this can take a long time
3260
  ha_release_temporary_latches(session);
3261
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3262
  if (file)
3263
  {
3264
    if (db_stat)
3265
      file->ha_drop_table(s->table_name.str);
3266
    else
1039.3.12 by Stewart Smith
remove handler::ha_delete_table and have StorageEngine::deleteTable instead
3267
      s->db_type()->deleteTable(session, s->table_name.str);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3268
    delete file;
3269
  }
3270
3271
  /* free blobs */
3272
  for (Field **ptr= field ; *ptr ; ptr++)
3273
    (*ptr)->free();
3274
  free_io_cache(this);
3275
3276
  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
3277
  session->set_proc_info(save_proc_info);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3278
}
3279
3280
/**
3281
  If a HEAP table gets full, create a MyISAM table and copy all rows
3282
  to this.
3283
*/
3284
520.1.22 by Brian Aker
Second pass of thd cleanup
3285
bool create_myisam_from_heap(Session *session, Table *table,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3286
                             MI_COLUMNDEF *start_recinfo,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3287
                             MI_COLUMNDEF **recinfo,
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3288
			     int error, bool ignore_last_dupp_key_error)
3289
{
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
3290
  Table new_table;
1000.1.3 by Brian Aker
Renamed TABLE_SHARE to TableShare
3291
  TableShare share;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3292
  const char *save_proc_info;
3293
  int write_err;
3294
960.2.25 by Monty Taylor
First step of hton rename.
3295
  if (table->s->db_type() != heap_engine ||
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3296
      error != HA_ERR_RECORD_FILE_FULL)
3297
  {
3298
    table->file->print_error(error,MYF(0));
1046.1.6 by Brian Aker
Formatting/style cleanup.
3299
    return true;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3300
  }
873.2.11 by Monty Taylor
call ha_release_temporary_latches
3301
3302
  // Release latches since this can take a long time
3303
  ha_release_temporary_latches(session);
3304
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3305
  new_table= *table;
3306
  share= *table->s;
3307
  new_table.s= &share;
971.1.21 by Monty Taylor
Store StorageEngine in system variables, rather than storage engine plugin.
3308
  new_table.s->storage_engine= myisam_engine;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3309
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
3310
                                        new_table.s->db_type())))
1046.1.6 by Brian Aker
Formatting/style cleanup.
3311
    return true;				// End of memory
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3312
520.1.22 by Brian Aker
Second pass of thd cleanup
3313
  save_proc_info=session->get_proc_info();
3314
  session->set_proc_info("converting HEAP to MyISAM");
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3315
3316
  if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3317
					recinfo, session->lex->select_lex.options |
520.1.22 by Brian Aker
Second pass of thd cleanup
3318
					session->options))
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3319
    goto err2;
3320
  if (new_table.open_tmp_table())
3321
    goto err1;
3322
  if (table->file->indexes_are_disabled())
3323
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
3324
  table->file->ha_index_or_rnd_end();
3325
  table->file->ha_rnd_init(1);
3326
  if (table->no_rows)
3327
  {
3328
    new_table.file->extra(HA_EXTRA_NO_ROWS);
3329
    new_table.no_rows=1;
3330
  }
3331
3332
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
3333
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
3334
3335
  /*
3336
    copy all old rows from heap table to MyISAM table
3337
    This is the only code that uses record[1] to read/write but this
3338
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
3339
  */
3340
  while (!table->file->rnd_next(new_table.record[1]))
3341
  {
3342
    write_err= new_table.file->ha_write_row(new_table.record[1]);
3343
    if (write_err)
3344
      goto err;
3345
  }
3346
  /* copy row that filled HEAP table */
3347
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
3348
  {
3349
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
3350
	!ignore_last_dupp_key_error)
3351
      goto err;
3352
  }
3353
3354
  /* remove heap table and change to use myisam table */
3355
  (void) table->file->ha_rnd_end();
3356
  (void) table->file->close();                  // This deletes the table !
3357
  delete table->file;
1046.1.6 by Brian Aker
Formatting/style cleanup.
3358
  table->file= NULL;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3359
  new_table.s= table->s;                       // Keep old share
3360
  *table= new_table;
3361
  *table->s= share;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
3362
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3363
  table->file->change_table_ptr(table, table->s);
3364
  table->use_all_columns();
3365
  if (save_proc_info)
3366
  {
3367
    const char *new_proc_info=
3368
      (!strcmp(save_proc_info,"Copying to tmp table") ?
3369
      "Copying to tmp table on disk" : save_proc_info);
520.1.22 by Brian Aker
Second pass of thd cleanup
3370
    session->set_proc_info(new_proc_info);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3371
  }
1046.1.6 by Brian Aker
Formatting/style cleanup.
3372
  return false;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3373
3374
 err:
3375
  table->file->print_error(write_err, MYF(0));
3376
  (void) table->file->ha_rnd_end();
3377
  (void) new_table.file->close();
3378
 err1:
1039.3.12 by Stewart Smith
remove handler::ha_delete_table and have StorageEngine::deleteTable instead
3379
  new_table.s->db_type()->deleteTable(session, new_table.s->table_name.str);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3380
 err2:
3381
  delete new_table.file;
520.1.22 by Brian Aker
Second pass of thd cleanup
3382
  session->set_proc_info(save_proc_info);
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3383
  table->mem_root= new_table.mem_root;
1046.1.6 by Brian Aker
Formatting/style cleanup.
3384
  return true;
327.1.2 by Brian Aker
Commiting next pass of Table class cleanup.
3385
}
3386
1005.2.3 by Monty Taylor
Further reversion of P.
3387
my_bitmap_map *Table::use_all_columns(MY_BITMAP *bitmap)
354 by Brian Aker
Refactor of Table methods.
3388
{
1005.2.3 by Monty Taylor
Further reversion of P.
3389
  my_bitmap_map *old= bitmap->bitmap;
3390
  bitmap->bitmap= s->all_set.bitmap;
354 by Brian Aker
Refactor of Table methods.
3391
  return old;
3392
}
3393
1005.2.3 by Monty Taylor
Further reversion of P.
3394
void Table::restore_column_map(my_bitmap_map *old)
354 by Brian Aker
Refactor of Table methods.
3395
{
1005.2.3 by Monty Taylor
Further reversion of P.
3396
  read_set->bitmap= old;
354 by Brian Aker
Refactor of Table methods.
3397
}
3398
482 by Brian Aker
Remove uint.
3399
uint32_t Table::find_shortest_key(const key_map *usable_keys)
355 by Brian Aker
More Table cleanup
3400
{
365.2.6 by Monty Taylor
Undid some stupid int->int16_t conversions.
3401
  uint32_t min_length= UINT32_MAX;
3402
  uint32_t best= MAX_KEY;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3403
  if (usable_keys->any())
355 by Brian Aker
More Table cleanup
3404
  {
1046.1.6 by Brian Aker
Formatting/style cleanup.
3405
    for (uint32_t nr= 0; nr < s->keys ; nr++)
355 by Brian Aker
More Table cleanup
3406
    {
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3407
      if (usable_keys->test(nr))
355 by Brian Aker
More Table cleanup
3408
      {
3409
        if (key_info[nr].key_length < min_length)
3410
        {
3411
          min_length= key_info[nr].key_length;
3412
          best=nr;
3413
        }
3414
      }
3415
    }
3416
  }
3417
  return best;
3418
}
3419
3420
/*****************************************************************************
3421
  Remove duplicates from tmp table
3422
  This should be recoded to add a unique index to the table and remove
3423
  duplicates
3424
  Table is a locked single thread table
3425
  fields is the number of fields to check (from the end)
3426
*****************************************************************************/
3427
3428
bool Table::compare_record(Field **ptr)
3429
{
3430
  for (; *ptr ; ptr++)
3431
  {
3432
    if ((*ptr)->cmp_offset(s->rec_buff_length))
3433
      return true;
3434
  }
3435
  return false;
3436
}
3437
3438
/* Return false if row hasn't changed */
3439
3440
bool Table::compare_record()
3441
{
3442
  if (s->blob_fields + s->varchar_fields == 0)
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
3443
    return memcmp(this->record[0], this->record[1], (size_t) s->reclength);
355 by Brian Aker
More Table cleanup
3444
  /* Compare null bits */
3445
  if (memcmp(null_flags,
3446
	     null_flags + s->rec_buff_length,
3447
	     s->null_bytes))
3448
    return true;				// Diff in NULL value
3449
  /* Compare updated fields */
3450
  for (Field **ptr= field ; *ptr ; ptr++)
3451
  {
1005.2.12 by Monty Taylor
Moved some things to the API.
3452
    if (isWriteSet((*ptr)->field_index) &&
355 by Brian Aker
More Table cleanup
3453
	(*ptr)->cmp_binary_offset(s->rec_buff_length))
3454
      return true;
3455
  }
3456
  return false;
3457
}
3458
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
3459
/*
3460
 * Store a record from previous record into next
3461
 *
3462
 */
3463
void Table::storeRecord()
3464
{
997.5.2 by chris
Remove comments, do/while, spaces per Monty review
3465
  memcpy(record[1], record[0], (size_t) s->reclength);
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
3466
}
3467
3468
/*
3469
 * Store a record as an insert
3470
 *
3471
 */
3472
void Table::storeRecordAsInsert()
3473
{
997.5.2 by chris
Remove comments, do/while, spaces per Monty review
3474
  memcpy(insert_values, record[0], (size_t) s->reclength);
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
3475
}
3476
3477
/*
3478
 * Store a record with default values
3479
 *
3480
 */
3481
void Table::storeRecordAsDefault()
3482
{
997.5.2 by chris
Remove comments, do/while, spaces per Monty review
3483
  memcpy(s->default_values, record[0], (size_t) s->reclength);
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
3484
}
3485
3486
/*
3487
 * Restore a record from previous record into next
3488
 *
3489
 */
3490
void Table::restoreRecord()
3491
{
997.5.2 by chris
Remove comments, do/while, spaces per Monty review
3492
  memcpy(record[0], record[1], (size_t) s->reclength);
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
3493
}
3494
3495
/*
3496
 * Restore a record with default values
3497
 *
3498
 */
3499
void Table::restoreRecordAsDefault()
3500
{
997.5.2 by chris
Remove comments, do/while, spaces per Monty review
3501
  memcpy(record[0], s->default_values, (size_t) s->reclength);
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
3502
}
3503
3504
/*
3505
 * Empty a record
3506
 *
3507
 */
3508
void Table::emptyRecord()
3509
{
997.5.2 by chris
Remove comments, do/while, spaces per Monty review
3510
  restoreRecordAsDefault();
3511
  memset(null_flags, 255, s->null_bytes);
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
3512
}
354 by Brian Aker
Refactor of Table methods.
3513
3514
/*****************************************************************************
3515
  The different ways to read a record
3516
  Returns -1 if row was not found, 0 if row was found and 1 on errors
3517
*****************************************************************************/
3518
3519
/** Help function when we get some an error from the table handler. */
3520
3521
int Table::report_error(int error)
3522
{
3523
  if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND)
3524
  {
3525
    status= STATUS_GARBAGE;
3526
    return -1;					// key not found; ok
3527
  }
3528
  /*
3529
    Locking reads can legally return also these errors, do not
3530
    print them to the .err log
3531
  */
3532
  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
3533
    errmsg_printf(ERRMSG_LVL_ERROR, _("Got error %d when reading table '%s'"),
354 by Brian Aker
Refactor of Table methods.
3534
		    error, s->path.str);
3535
  file->print_error(error,MYF(0));
3536
3537
  return 1;
3538
}
3539
1 by brian
clean slate
3540
934.1.1 by Brian Aker
Moved two functions in classes.
3541
void Table::setup_table_map(TableList *table_list, uint32_t table_number)
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.
3542
{
934.1.1 by Brian Aker
Moved two functions in classes.
3543
  used_fields= 0;
3544
  const_table= 0;
3545
  null_row= 0;
3546
  status= STATUS_NO_RECORD;
3547
  maybe_null= table_list->outer_join;
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.
3548
  TableList *embedding= table_list->embedding;
934.1.1 by Brian Aker
Moved two functions in classes.
3549
  while (!maybe_null && embedding)
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.
3550
  {
934.1.1 by Brian Aker
Moved two functions in classes.
3551
    maybe_null= embedding->outer_join;
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.
3552
    embedding= embedding->embedding;
3553
  }
934.1.1 by Brian Aker
Moved two functions in classes.
3554
  tablenr= table_number;
3555
  map= (table_map) 1 << table_number;
3556
  force_index= table_list->force_index;
3557
  covering_keys= s->keys_for_keyread;
1005.2.6 by Monty Taylor
Re-added bitset<> as a replacement for Bitmap<>
3558
  merge_keys.reset();
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.
3559
}
3560
1054.1.7 by Brian Aker
Refactor TableList methods.
3561
Field *Table::find_field_in_table_sef(const char *name)
3562
{
3563
  Field **field_ptr;
3564
  if (s->name_hash.records)
3565
  {
3566
    field_ptr= (Field**)hash_search(&s->name_hash,(unsigned char*) name,
3567
                                    strlen(name));
3568
    if (field_ptr)
3569
    {
3570
      /*
3571
        field_ptr points to field in TableShare. Convert it to the matching
3572
        field in table
3573
      */
3574
      field_ptr= (field + (field_ptr - s->field));
3575
    }
3576
  }
3577
  else
3578
  {
3579
    if (!(field_ptr= field))
3580
      return (Field *)0;
3581
    for (; *field_ptr; ++field_ptr)
3582
      if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
3583
        break;
3584
  }
3585
  if (field_ptr)
3586
    return *field_ptr;
3587
  else
3588
    return (Field *)0;
3589
}
3590
1 by brian
clean slate
3591
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
3592
template class List<String>;
3593
template class List_iterator<String>;
3594
#endif