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