~drizzle-trunk/drizzle/development

1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
4
 *  Copyright (C) 2010 Brian Aker
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
5
 *  Copyright (C) 2009 Sun Microsystems
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
 */
21
22
/*
23
  This class is shared between different table objects. There is one
24
  instance of table share per one table in the database.
25
*/
26
27
/* Basic functions needed by many modules */
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
28
#include "config.h"
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
29
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
30
#include <pthread.h>
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
31
#include <float.h>
32
33
#include <sys/types.h>
34
#include <sys/stat.h>
35
#include <fcntl.h>
36
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
37
38
#include <cassert>
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
39
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
40
#include "drizzled/error.h"
41
#include "drizzled/gettext.h"
42
#include "drizzled/sql_base.h"
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
43
#include "drizzled/pthread_globals.h"
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
44
#include "drizzled/internal/my_pthread.h"
1502.5.7 by Barry.Leslie at PrimeBase
Renamed the 'Event' plugin to 'EventObserver' plugin along with some internal class renames to make things clearer.
45
#include "drizzled/plugin/event_observer.h"
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
46
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
47
#include "drizzled/session.h"
48
49
#include "drizzled/charset.h"
50
#include "drizzled/internal/m_string.h"
51
#include "drizzled/internal/my_sys.h"
52
53
#include "drizzled/item/string.h"
54
#include "drizzled/item/int.h"
55
#include "drizzled/item/decimal.h"
56
#include "drizzled/item/float.h"
57
#include "drizzled/item/null.h"
58
#include "drizzled/temporal.h"
59
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
60
#include "drizzled/field.h"
61
#include "drizzled/field/str.h"
62
#include "drizzled/field/num.h"
63
#include "drizzled/field/blob.h"
64
#include "drizzled/field/enum.h"
65
#include "drizzled/field/null.h"
66
#include "drizzled/field/date.h"
67
#include "drizzled/field/decimal.h"
68
#include "drizzled/field/real.h"
69
#include "drizzled/field/double.h"
70
#include "drizzled/field/long.h"
71
#include "drizzled/field/int64_t.h"
72
#include "drizzled/field/num.h"
73
#include "drizzled/field/timestamp.h"
74
#include "drizzled/field/datetime.h"
75
#include "drizzled/field/varstring.h"
76
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
77
using namespace std;
78
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
79
namespace drizzled
80
{
81
1241.9.33 by Monty Taylor
Moved most of the global vars to set_var where they belong.
82
extern size_t table_def_size;
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
83
static TableDefinitionCache table_def_cache;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
84
static pthread_mutex_t LOCK_table_share;
85
bool table_def_inited= false;
86
87
/*****************************************************************************
88
  Functions to handle table definition cach (TableShare)
89
 *****************************************************************************/
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
90
91
92
void TableShare::cacheStart(void)
93
{
94
  pthread_mutex_init(&LOCK_table_share, MY_MUTEX_INIT_FAST);
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
95
  table_def_inited= true;
1223.3.2 by Monty Taylor
Added init-time rehash to the table_def_cache.
96
  /* 
97
   * This is going to overalloc a bit - as rehash sets the number of
98
   * buckets, not the number of elements. BUT, it'll allow us to not need
1429.3.1 by Monty Taylor
Use unordered_map from the upcoming c++0x standard instead of a homemade
99
   * to rehash later on as the unordered_map grows.
1530.1.3 by Brian Aker
Style cleanup for table_share
100
 */
1223.3.2 by Monty Taylor
Added init-time rehash to the table_def_cache.
101
  table_def_cache.rehash(table_def_size);
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
102
}
103
104
105
void TableShare::cacheStop(void)
106
{
107
  if (table_def_inited)
108
  {
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
109
    table_def_inited= false;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
110
    pthread_mutex_destroy(&LOCK_table_share);
111
  }
112
}
113
114
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
115
/**
116
 * @TODO: This should return size_t
117
 */
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
118
uint32_t cached_table_definitions(void)
119
{
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
120
  return static_cast<uint32_t>(table_def_cache.size());
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
121
}
122
123
124
/*
125
  Mark that we are not using table share anymore.
126
127
  SYNOPSIS
128
  release()
129
  share		Table share
130
131
  IMPLEMENTATION
132
  If ref_count goes to zero and (we have done a refresh or if we have
133
  already too many open table shares) then delete the definition.
134
*/
135
136
void TableShare::release(TableShare *share)
137
{
138
  bool to_be_deleted= false;
139
  safe_mutex_assert_owner(&LOCK_open);
140
141
  pthread_mutex_lock(&share->mutex);
142
  if (!--share->ref_count)
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
143
  {
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
144
    to_be_deleted= true;
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
145
  }
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
146
147
  if (to_be_deleted)
148
  {
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
149
    TableIdentifier identifier(share->getSchemaName(), share->getTableName());
1502.5.8 by Barry.Leslie at PrimeBase
- Changed names to match the drizzle naming convention.
150
    plugin::EventObserver::deregisterTableEvents(*share);
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
151
   
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
152
    TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
153
    if (iter != table_def_cache.end())
154
    {
155
      table_def_cache.erase(iter);
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
156
      delete share;
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
157
    }
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
158
    return;
159
  }
160
  pthread_mutex_unlock(&share->mutex);
161
}
162
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
163
void TableShare::release(TableIdentifier &identifier)
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
164
{
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
165
  TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
166
  if (iter != table_def_cache.end())
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
167
  {
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
168
    TableShare *share= (*iter).second;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
169
    share->version= 0;                          // Mark for delete
170
    if (share->ref_count == 0)
171
    {
172
      pthread_mutex_lock(&share->mutex);
1502.5.8 by Barry.Leslie at PrimeBase
- Changed names to match the drizzle naming convention.
173
      plugin::EventObserver::deregisterTableEvents(*share);
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
174
      table_def_cache.erase(identifier.getKey());
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
175
      delete share;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
176
    }
177
  }
178
}
179
180
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
181
static TableShare *foundTableShare(TableShare *share)
182
{
183
  /*
184
    We found an existing table definition. Return it if we didn't get
185
    an error when reading the table definition from file.
186
  */
187
188
  /* We must do a lock to ensure that the structure is initialized */
189
  (void) pthread_mutex_lock(&share->mutex);
190
  if (share->error)
191
  {
192
    /* Table definition contained an error */
193
    share->open_table_error(share->error, share->open_errno, share->errarg);
194
    (void) pthread_mutex_unlock(&share->mutex);
195
196
    return NULL;
197
  }
198
1578.2.4 by Brian Aker
More encapsulation of table Share, this time table count.
199
  share->incrementTableCount();
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
200
  (void) pthread_mutex_unlock(&share->mutex);
201
202
  return share;
203
}
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
204
205
/*
206
  Get TableShare for a table.
207
208
  get_table_share()
209
  session			Thread handle
210
  table_list		Table that should be opened
211
  key			Table cache key
212
  key_length		Length of key
213
  error			out: Error code from open_table_def()
214
215
  IMPLEMENTATION
216
  Get a table definition from the table definition cache.
217
  If it doesn't exist, create a new from the table definition file.
218
219
  NOTES
220
  We must have wrlock on LOCK_open when we come here
221
  (To be changed later)
222
223
  RETURN
224
  0  Error
225
#  Share for table
226
*/
227
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
228
TableShare *TableShare::getShareCreate(Session *session, 
229
                                       TableIdentifier &identifier,
230
                                       int *error)
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
231
{
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
232
  TableShare *share= NULL;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
233
234
  *error= 0;
235
236
  /* Read table definition from cache */
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
237
  TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
238
  if (iter != table_def_cache.end())
239
  {
240
    share= (*iter).second;
241
    return foundTableShare(share);
242
  }
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
243
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
244
  if (not (share= new TableShare(message::Table::STANDARD, identifier)))
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
245
  {
246
    return NULL;
247
  }
248
249
  /*
250
    Lock mutex to be able to read table definition from file without
251
    conflicts
252
  */
253
  (void) pthread_mutex_lock(&share->mutex);
254
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
255
  /**
256
   * @TODO: we need to eject something if we exceed table_def_size
1530.1.3 by Brian Aker
Style cleanup for table_share
257
 */
1340.1.2 by Brian Aker
Merge of table cache/def DD.
258
  pair<TableDefinitionCache::iterator, bool> ret=
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
259
    table_def_cache.insert(make_pair(identifier.getKey(), share));
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
260
  if (ret.second == false)
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
261
  {
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
262
    delete share;
263
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
264
    return NULL;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
265
  }
1530.1.3 by Brian Aker
Style cleanup for table_share
266
1502.1.24 by Brian Aker
Absorb TableShare proto to share methods.
267
  if (share->open_table_def(*session, identifier))
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
268
  {
269
    *error= share->error;
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
270
    table_def_cache.erase(identifier.getKey());
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
271
    delete share;
272
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
273
    return NULL;
274
  }
275
  share->ref_count++;				// Mark in use
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
276
  
1502.5.8 by Barry.Leslie at PrimeBase
- Changed names to match the drizzle naming convention.
277
  plugin::EventObserver::registerTableEvents(*share);
1502.5.2 by Barry.Leslie at PrimeBase
Changes made to drizzle source when building in the events plugin.
278
  
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
279
  (void) pthread_mutex_unlock(&share->mutex);
1371 by Brian Aker
Small corrections.
280
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
281
  return share;
282
}
283
284
285
/*
286
  Check if table definition exits in cache
287
288
  SYNOPSIS
289
  get_cached_table_share()
290
  db			Database name
291
  table_name		Table name
292
293
  RETURN
294
  0  Not cached
295
#  TableShare for table
296
*/
1358.1.9 by Brian Aker
Update for std::string
297
TableShare *TableShare::getShare(TableIdentifier &identifier)
298
{
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
299
  safe_mutex_assert_owner(&LOCK_open);
300
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
301
  TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
302
  if (iter != table_def_cache.end())
303
  {
304
    return (*iter).second;
305
  }
306
  else
307
  {
308
    return NULL;
309
  }
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
310
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
311
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
312
/* Get column name from column hash */
313
314
static unsigned char *get_field_name(Field **buff, size_t *length, bool)
315
{
316
  *length= (uint32_t) strlen((*buff)->field_name);
317
  return (unsigned char*) (*buff)->field_name;
318
}
319
320
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
321
{
322
  enum_field_types field_type;
323
324
  switch(proto_field_type)
325
  {
326
  case message::Table::Field::INTEGER:
327
    field_type= DRIZZLE_TYPE_LONG;
328
    break;
329
  case message::Table::Field::DOUBLE:
330
    field_type= DRIZZLE_TYPE_DOUBLE;
331
    break;
332
  case message::Table::Field::TIMESTAMP:
333
    field_type= DRIZZLE_TYPE_TIMESTAMP;
334
    break;
335
  case message::Table::Field::BIGINT:
336
    field_type= DRIZZLE_TYPE_LONGLONG;
337
    break;
338
  case message::Table::Field::DATETIME:
339
    field_type= DRIZZLE_TYPE_DATETIME;
340
    break;
341
  case message::Table::Field::DATE:
342
    field_type= DRIZZLE_TYPE_DATE;
343
    break;
344
  case message::Table::Field::VARCHAR:
345
    field_type= DRIZZLE_TYPE_VARCHAR;
346
    break;
347
  case message::Table::Field::DECIMAL:
348
    field_type= DRIZZLE_TYPE_DECIMAL;
349
    break;
350
  case message::Table::Field::ENUM:
351
    field_type= DRIZZLE_TYPE_ENUM;
352
    break;
353
  case message::Table::Field::BLOB:
354
    field_type= DRIZZLE_TYPE_BLOB;
355
    break;
356
  default:
357
    field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
358
    assert(1);
359
  }
360
361
  return field_type;
362
}
363
364
static Item *default_value_item(enum_field_types field_type,
365
                                const CHARSET_INFO *charset,
366
                                bool default_null, const string *default_value,
367
                                const string *default_bin_value)
368
{
369
  Item *default_item= NULL;
370
  int error= 0;
371
372
  if (default_null)
373
  {
374
    return new Item_null();
375
  }
376
377
  switch(field_type)
378
  {
379
  case DRIZZLE_TYPE_LONG:
380
  case DRIZZLE_TYPE_LONGLONG:
381
    default_item= new Item_int(default_value->c_str(),
382
                               (int64_t) internal::my_strtoll10(default_value->c_str(),
383
                                                                NULL,
384
                                                                &error),
385
                               default_value->length());
386
    break;
387
  case DRIZZLE_TYPE_DOUBLE:
388
    default_item= new Item_float(default_value->c_str(),
389
                                 default_value->length());
390
    break;
391
  case DRIZZLE_TYPE_NULL:
392
    assert(false);
393
  case DRIZZLE_TYPE_TIMESTAMP:
394
  case DRIZZLE_TYPE_DATETIME:
395
  case DRIZZLE_TYPE_DATE:
396
  case DRIZZLE_TYPE_ENUM:
397
    default_item= new Item_string(default_value->c_str(),
398
                                  default_value->length(),
399
                                  system_charset_info);
400
    break;
401
  case DRIZZLE_TYPE_VARCHAR:
402
  case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
403
    if (charset==&my_charset_bin)
404
    {
405
      default_item= new Item_string(default_bin_value->c_str(),
406
                                    default_bin_value->length(),
407
                                    &my_charset_bin);
408
    }
409
    else
410
    {
411
      default_item= new Item_string(default_value->c_str(),
412
                                    default_value->length(),
413
                                    system_charset_info);
414
    }
415
    break;
416
  case DRIZZLE_TYPE_DECIMAL:
417
    default_item= new Item_decimal(default_value->c_str(),
418
                                   default_value->length(),
419
                                   system_charset_info);
420
    break;
421
  }
422
423
  return default_item;
424
}
425
426
427
1308.2.2 by Jay Pipes
Fixes transaction log/replication for multi-column primary keys. Changes CREATE SCHEMA to not use statement-base RAW_SQL and instead use a derived message::Statement subclass.
428
/**
429
 * @todo
430
 *
431
 * Precache this stuff....
432
 */
433
bool TableShare::fieldInPrimaryKey(Field *in_field) const
434
{
435
  assert(table_proto != NULL);
1530.1.3 by Brian Aker
Style cleanup for table_share
436
1308.2.2 by Jay Pipes
Fixes transaction log/replication for multi-column primary keys. Changes CREATE SCHEMA to not use statement-base RAW_SQL and instead use a derived message::Statement subclass.
437
  size_t num_indexes= table_proto->indexes_size();
438
439
  for (size_t x= 0; x < num_indexes; ++x)
440
  {
441
    const message::Table::Index &index= table_proto->indexes(x);
442
    if (index.is_primary())
443
    {
444
      size_t num_parts= index.index_part_size();
445
      for (size_t y= 0; y < num_parts; ++y)
446
      {
447
        if (index.index_part(y).fieldnr() == in_field->field_index)
448
          return true;
449
      }
450
    }
451
  }
452
  return false;
453
}
454
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
455
const TableDefinitionCache &TableShare::getCache()
1340.1.2 by Brian Aker
Merge of table cache/def DD.
456
{
457
  return table_def_cache;
458
}
459
1608.2.4 by Brian Aker
Update for having share declared type.
460
TableShare::TableShare(TableIdentifier::Type type_arg) :
1608.2.2 by Brian Aker
Move constructors to .cc file.
461
  table_category(TABLE_UNKNOWN_CATEGORY),
462
  open_count(0),
463
  found_next_number_field(NULL),
464
  timestamp_field(NULL),
465
  key_info(NULL),
466
  blob_field(NULL),
467
  block_size(0),
468
  version(0),
469
  timestamp_offset(0),
470
  reclength(0),
471
  stored_rec_length(0),
472
  max_rows(0),
473
  table_proto(NULL),
474
  storage_engine(NULL),
1608.2.4 by Brian Aker
Update for having share declared type.
475
  tmp_table(type_arg),
1608.2.2 by Brian Aker
Move constructors to .cc file.
476
  ref_count(0),
477
  null_bytes(0),
478
  last_null_bit_pos(0),
479
  fields(0),
480
  rec_buff_length(0),
481
  keys(0),
482
  key_parts(0),
483
  max_key_length(0),
484
  max_unique_length(0),
485
  total_key_length(0),
486
  uniques(0),
487
  null_fields(0),
488
  blob_fields(0),
489
  timestamp_field_offset(0),
490
  varchar_fields(0),
491
  db_create_options(0),
492
  db_options_in_use(0),
493
  db_record_offset(0),
494
  rowid_field_offset(0),
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
495
  primary_key(MAX_KEY),
1608.2.2 by Brian Aker
Move constructors to .cc file.
496
  next_number_index(0),
497
  next_number_key_offset(0),
498
  next_number_keypart(0),
499
  error(0),
500
  open_errno(0),
501
  errarg(0),
502
  column_bitmap_size(0),
503
  blob_ptr_size(0),
504
  db_low_byte_first(false),
505
  name_lock(false),
506
  replace_with_name_lock(false),
507
  waiting_on_cond(false),
508
  keys_in_use(0),
509
  keys_for_keyread(0),
510
  event_observers(NULL),
511
  newed(true)
512
{
513
  memset(&name_hash, 0, sizeof(HASH));
514
515
  table_charset= 0;
516
  memset(&db, 0, sizeof(LEX_STRING));
517
  memset(&table_name, 0, sizeof(LEX_STRING));
518
  memset(&path, 0, sizeof(LEX_STRING));
519
  memset(&normalized_path, 0, sizeof(LEX_STRING));
520
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
521
  if (type_arg == message::Table::INTERNAL)
522
  {
523
    TableIdentifier::build_tmptable_filename(private_key_for_cache);
524
    init(&private_key_for_cache[0], &private_key_for_cache[0]);
525
  }
526
  else
527
  {
528
    init("", "");
529
  }
1608.2.2 by Brian Aker
Move constructors to .cc file.
530
}
531
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
532
TableShare::TableShare(TableIdentifier &identifier, const TableIdentifier::Key &key) :// Used by placeholder
1608.2.2 by Brian Aker
Move constructors to .cc file.
533
  table_category(TABLE_UNKNOWN_CATEGORY),
534
  open_count(0),
535
  found_next_number_field(NULL),
536
  timestamp_field(NULL),
537
  key_info(NULL),
538
  blob_field(NULL),
539
  block_size(0),
540
  version(0),
541
  timestamp_offset(0),
542
  reclength(0),
543
  stored_rec_length(0),
544
  max_rows(0),
545
  table_proto(NULL),
546
  storage_engine(NULL),
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
547
  tmp_table(message::Table::INTERNAL),
1608.2.2 by Brian Aker
Move constructors to .cc file.
548
  ref_count(0),
549
  null_bytes(0),
550
  last_null_bit_pos(0),
551
  fields(0),
552
  rec_buff_length(0),
553
  keys(0),
554
  key_parts(0),
555
  max_key_length(0),
556
  max_unique_length(0),
557
  total_key_length(0),
558
  uniques(0),
559
  null_fields(0),
560
  blob_fields(0),
561
  timestamp_field_offset(0),
562
  varchar_fields(0),
563
  db_create_options(0),
564
  db_options_in_use(0),
565
  db_record_offset(0),
566
  rowid_field_offset(0),
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
567
  primary_key(MAX_KEY),
1608.2.2 by Brian Aker
Move constructors to .cc file.
568
  next_number_index(0),
569
  next_number_key_offset(0),
570
  next_number_keypart(0),
571
  error(0),
572
  open_errno(0),
573
  errarg(0),
574
  column_bitmap_size(0),
575
  blob_ptr_size(0),
576
  db_low_byte_first(false),
577
  name_lock(false),
578
  replace_with_name_lock(false),
579
  waiting_on_cond(false),
580
  keys_in_use(0),
581
  keys_for_keyread(0),
582
  event_observers(NULL),
583
  newed(true)
584
{
585
  memset(&name_hash, 0, sizeof(HASH));
586
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
587
  assert(identifier.getKey() == key);
588
1608.2.2 by Brian Aker
Move constructors to .cc file.
589
  table_charset= 0;
590
  memset(&path, 0, sizeof(LEX_STRING));
591
  memset(&normalized_path, 0, sizeof(LEX_STRING));
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
592
593
  private_key_for_cache= key;
594
595
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
596
  table_category=         TABLE_CATEGORY_TEMPORARY;
597
  tmp_table=              message::Table::INTERNAL;
598
599
  db.str= &private_key_for_cache[0];
600
  db.length= strlen(&private_key_for_cache[0]);
601
602
  table_name.str= &private_key_for_cache[0] + strlen(&private_key_for_cache[0]) + 1;
603
  table_name.length= strlen(table_name.str);
604
  path.str= (char *)"";
605
  normalized_path.str= path.str;
606
  path.length= normalized_path.length= 0;
607
  assert(strcmp(identifier.getTableName().c_str(), table_name.str) == 0);
608
  assert(strcmp(identifier.getSchemaName().c_str(), db.str) == 0);
1608.2.4 by Brian Aker
Update for having share declared type.
609
}
610
611
1618.1.1 by Brian Aker
Modify TableIdentifier to be const
612
TableShare::TableShare(const TableIdentifier &identifier) : // Just used during createTable()
1608.2.4 by Brian Aker
Update for having share declared type.
613
  table_category(TABLE_UNKNOWN_CATEGORY),
614
  open_count(0),
615
  found_next_number_field(NULL),
616
  timestamp_field(NULL),
617
  key_info(NULL),
618
  blob_field(NULL),
619
  block_size(0),
620
  version(0),
621
  timestamp_offset(0),
622
  reclength(0),
623
  stored_rec_length(0),
624
  max_rows(0),
625
  table_proto(NULL),
626
  storage_engine(NULL),
627
  tmp_table(identifier.getType()),
628
  ref_count(0),
629
  null_bytes(0),
630
  last_null_bit_pos(0),
631
  fields(0),
632
  rec_buff_length(0),
633
  keys(0),
634
  key_parts(0),
635
  max_key_length(0),
636
  max_unique_length(0),
637
  total_key_length(0),
638
  uniques(0),
639
  null_fields(0),
640
  blob_fields(0),
641
  timestamp_field_offset(0),
642
  varchar_fields(0),
643
  db_create_options(0),
644
  db_options_in_use(0),
645
  db_record_offset(0),
646
  rowid_field_offset(0),
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
647
  primary_key(MAX_KEY),
1608.2.4 by Brian Aker
Update for having share declared type.
648
  next_number_index(0),
649
  next_number_key_offset(0),
650
  next_number_keypart(0),
651
  error(0),
652
  open_errno(0),
653
  errarg(0),
654
  column_bitmap_size(0),
655
  blob_ptr_size(0),
656
  db_low_byte_first(false),
657
  name_lock(false),
658
  replace_with_name_lock(false),
659
  waiting_on_cond(false),
660
  keys_in_use(0),
661
  keys_for_keyread(0),
662
  event_observers(NULL),
663
  newed(true)
664
{
665
  memset(&name_hash, 0, sizeof(HASH));
666
667
  table_charset= 0;
668
  memset(&db, 0, sizeof(LEX_STRING));
669
  memset(&table_name, 0, sizeof(LEX_STRING));
670
  memset(&path, 0, sizeof(LEX_STRING));
671
  memset(&normalized_path, 0, sizeof(LEX_STRING));
672
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
673
  private_key_for_cache= identifier.getKey();
674
  assert(identifier.getPath().size()); // Since we are doing a create table, this should be a positive value
675
  private_normalized_path.resize(identifier.getPath().size() + 1);
676
  memcpy(&private_normalized_path[0], identifier.getPath().c_str(), identifier.getPath().size());
677
1608.2.4 by Brian Aker
Update for having share declared type.
678
  {
679
    memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
680
    table_category=         TABLE_CATEGORY_TEMPORARY;
681
    tmp_table=              message::Table::INTERNAL;
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
682
    db.str= &private_key_for_cache[0];
683
    db.length= strlen(&private_key_for_cache[0]);
684
    table_name.str= db.str + 1;
685
    table_name.length= strlen(table_name.str);
686
    path.str= &private_normalized_path[0];
687
    normalized_path.str= path.str;
688
    path.length= normalized_path.length= private_normalized_path.size();
1608.2.4 by Brian Aker
Update for having share declared type.
689
  }
690
}
691
692
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
693
/*
694
  Used for shares that will go into the cache.
695
*/
1608.2.4 by Brian Aker
Update for having share declared type.
696
TableShare::TableShare(TableIdentifier::Type type_arg,
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
697
                       TableIdentifier &identifier,
1608.2.2 by Brian Aker
Move constructors to .cc file.
698
                       char *path_arg,
699
                       uint32_t path_length_arg) :
1502.1.22 by Brian Aker
Additional remove of memset on TableShare().
700
  table_category(TABLE_UNKNOWN_CATEGORY),
701
  open_count(0),
702
  found_next_number_field(NULL),
703
  timestamp_field(NULL),
704
  key_info(NULL),
705
  blob_field(NULL),
706
  block_size(0),
707
  version(0),
708
  timestamp_offset(0),
709
  reclength(0),
710
  stored_rec_length(0),
711
  max_rows(0),
712
  table_proto(NULL),
713
  storage_engine(NULL),
1608.2.4 by Brian Aker
Update for having share declared type.
714
  tmp_table(type_arg),
1502.1.22 by Brian Aker
Additional remove of memset on TableShare().
715
  ref_count(0),
716
  null_bytes(0),
717
  last_null_bit_pos(0),
718
  fields(0),
719
  rec_buff_length(0),
720
  keys(0),
721
  key_parts(0),
722
  max_key_length(0),
723
  max_unique_length(0),
724
  total_key_length(0),
725
  uniques(0),
726
  null_fields(0),
727
  blob_fields(0),
728
  timestamp_field_offset(0),
729
  varchar_fields(0),
730
  db_create_options(0),
731
  db_options_in_use(0),
732
  db_record_offset(0),
733
  rowid_field_offset(0),
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
734
  primary_key(MAX_KEY),
1502.1.22 by Brian Aker
Additional remove of memset on TableShare().
735
  next_number_index(0),
736
  next_number_key_offset(0),
737
  next_number_keypart(0),
738
  error(0),
739
  open_errno(0),
740
  errarg(0),
741
  column_bitmap_size(0),
742
  blob_ptr_size(0),
743
  db_low_byte_first(false),
744
  name_lock(false),
745
  replace_with_name_lock(false),
746
  waiting_on_cond(false),
747
  keys_in_use(0),
748
  keys_for_keyread(0),
1548.2.3 by Barry.Leslie at PrimeBase
Added drizzle event observer class to PBMS as well as a lot of mostly minor changes for drizzle compatability.
749
  event_observers(NULL),
1502.1.22 by Brian Aker
Additional remove of memset on TableShare().
750
  newed(true)
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
751
{
1502.1.22 by Brian Aker
Additional remove of memset on TableShare().
752
  memset(&name_hash, 0, sizeof(HASH));
753
754
  table_charset= 0;
755
  memset(&db, 0, sizeof(LEX_STRING));
756
  memset(&table_name, 0, sizeof(LEX_STRING));
757
  memset(&path, 0, sizeof(LEX_STRING));
758
  memset(&normalized_path, 0, sizeof(LEX_STRING));
1502.1.14 by Brian Aker
Remove memcpy() from TableShare and just have it deal with its own mem_root.
759
760
  mem_root.init_alloc_root(TABLE_ALLOC_BLOCK_SIZE);
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
761
  char *path_buff;
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
762
  std::string _path;
763
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
764
  private_key_for_cache= identifier.getKey();
765
  /*
766
    Let us use the fact that the key is "db/0/table_name/0" + optional
767
    part for temporary tables.
768
  */
769
  db.str= &private_key_for_cache[0];
770
  db.length=         strlen(db.str);
771
  table_name.str=    db.str + db.length + 1;
1502.1.15 by Brian Aker
Small opt to not need TableList
772
  table_name.length= strlen(table_name.str);
773
1502.1.12 by Brian Aker
Second pass through TableShare to new(). Partial hack in using bool for the
774
  if (path_arg)
775
  {
776
    _path.append(path_arg, path_length_arg);
777
  }
778
  else
779
  {
1601 by Brian Aker
Move functions to class methods.
780
    TableIdentifier::build_table_filename(_path, db.str, table_name.str, false);
1502.1.12 by Brian Aker
Second pass through TableShare to new(). Partial hack in using bool for the
781
  }
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
782
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
783
  if (mem_root.multi_alloc_root(0,
1532.1.5 by Brian Aker
Shift the varargs so that they are a part of memory::Root
784
                                &path_buff, _path.length() + 1,
785
                                NULL))
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
786
  {
787
    setPath(path_buff, _path.length());
788
    strcpy(path_buff, _path.c_str());
789
    setNormalizedPath(path_buff, _path.length());
790
1532.1.12 by Brian Aker
Remove one of the set key table cache methods.
791
    version= refresh_version;
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
792
793
    pthread_mutex_init(&mutex, MY_MUTEX_INIT_FAST);
794
    pthread_cond_init(&cond, NULL);
795
  }
796
  else
797
  {
798
    assert(0); // We should throw here.
799
  }
1502.1.12 by Brian Aker
Second pass through TableShare to new(). Partial hack in using bool for the
800
801
  newed= true;
1502.1.11 by Brian Aker
This fixes TableShare such that for the cache we now correctly call new()
802
}
803
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
804
void TableShare::init(const char *new_table_name,
1608.2.2 by Brian Aker
Move constructors to .cc file.
805
                      const char *new_path)
806
{
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
807
1608.2.2 by Brian Aker
Move constructors to .cc file.
808
  memory::init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
809
  table_category=         TABLE_CATEGORY_TEMPORARY;
810
  tmp_table=              message::Table::INTERNAL;
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
811
  db.str= (char *)"";
812
  db.length= 0;
1608.2.2 by Brian Aker
Move constructors to .cc file.
813
  table_name.str=         (char*) new_table_name;
814
  table_name.length=      strlen(new_table_name);
815
  path.str=               (char*) new_path;
816
  normalized_path.str=    (char*) new_path;
817
  path.length= normalized_path.length= strlen(new_path);
818
}
819
1619.1.1 by Brian Aker
Update for TableShare usage of key (remove a case where we had to build it).
820
TableShare::~TableShare() 
821
{
822
  assert(ref_count == 0);
823
824
  /*
825
    If someone is waiting for this to be deleted, inform it about this.
826
    Don't do a delete until we know that no one is refering to this anymore.
827
  */
828
  if (tmp_table == message::Table::STANDARD)
829
  {
830
    /* share->mutex is locked in release_table_share() */
831
    while (waiting_on_cond)
832
    {
833
      pthread_cond_broadcast(&cond);
834
      pthread_cond_wait(&cond, &mutex);
835
    }
836
    /* No thread refers to this anymore */
837
    pthread_mutex_unlock(&mutex);
838
    pthread_mutex_destroy(&mutex);
839
    pthread_cond_destroy(&cond);
840
  }
841
  hash_free(&name_hash);
842
843
  storage_engine= NULL;
844
845
  delete table_proto;
846
  table_proto= NULL;
847
848
  mem_root.free_root(MYF(0));                 // Free's share
849
}
850
1618 by Brian Aker
This is a rollup set of patches for modifications to TableIdentifier to have
851
void TableShare::setIdentifier(TableIdentifier &identifier_arg)
852
{
853
  private_key_for_cache.clear();
854
  private_key_for_cache= identifier_arg.getKey();
855
856
  /*
857
    Let us use the fact that the key is "db/0/table_name/0" + optional
858
    part for temporary tables.
859
  */
860
  db.str= &private_key_for_cache[0];
861
  db.length=         strlen(db.str);
862
  table_name.str=    db.str + db.length + 1;
863
  table_name.length= strlen(table_name.str);
864
865
  table_proto->set_name(identifier_arg.getTableName());
866
  table_proto->set_schema(identifier_arg.getSchemaName());
867
}
868
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
869
int TableShare::inner_parse_table_proto(Session& session, message::Table &table)
870
{
871
  int local_error= 0;
872
873
  if (! table.IsInitialized())
874
  {
875
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
876
    return ER_CORRUPT_TABLE_DEFINITION;
877
  }
878
1574.1.2 by Brian Aker
Remove =this reference.
879
  setTableProto(new(nothrow) message::Table(table));
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
880
1574.1.2 by Brian Aker
Remove =this reference.
881
  storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
882
  assert(storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
883
884
  message::Table::TableOptions table_options;
885
886
  if (table.has_options())
887
    table_options= table.options();
888
889
  uint32_t local_db_create_options= 0;
890
891
  if (table_options.pack_record())
892
    local_db_create_options|= HA_OPTION_PACK_RECORD;
893
894
  /* local_db_create_options was stored as 2 bytes in FRM
1530.1.3 by Brian Aker
Style cleanup for table_share
895
    Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
896
  */
1574.1.2 by Brian Aker
Remove =this reference.
897
  db_create_options= (local_db_create_options & 0x0000FFFF);
898
  db_options_in_use= db_create_options;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
899
1574.1.2 by Brian Aker
Remove =this reference.
900
  block_size= table_options.has_block_size() ?
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
901
    table_options.block_size() : 0;
902
1638.1.5 by Stewart Smith
explicit collation in table proto (from review)
903
  table_charset= get_charset(table_options.collation_id());
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
904
1574.1.2 by Brian Aker
Remove =this reference.
905
  if (!table_charset)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
906
  {
1638.1.2 by Stewart Smith
fix error message for parsing invalid table collation to fit other forms of corruption by returning to the user session an appropriate error message.
907
    char errmsg[100];
908
    snprintf(errmsg, sizeof(errmsg),
909
             _("Table %s has invalid/unknown collation: %d,%s"),
910
             getPath(),
911
             table_options.collation_id(),
912
             table_options.collation().c_str());
913
    errmsg[99]='\0';
914
915
    my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), errmsg);
1638.1.1 by Stewart Smith
have table wide default collation/collation_id in table proto as well as move to only storing it when it's not the default (utf8_general_ci). This means that the replication stream now doesn't produce COLLATE= in the transformation of create table back to SQL.
916
    return ER_CORRUPT_TABLE_DEFINITION;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
917
  }
918
1574.1.2 by Brian Aker
Remove =this reference.
919
  db_record_offset= 1;
920
921
  blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
922
923
  keys= table.indexes_size();
924
925
  key_parts= 0;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
926
  for (int indx= 0; indx < table.indexes_size(); indx++)
1574.1.2 by Brian Aker
Remove =this reference.
927
    key_parts+= table.indexes(indx).index_part_size();
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
928
1574.1.2 by Brian Aker
Remove =this reference.
929
  key_info= (KeyInfo*) alloc_root( table.indexes_size() * sizeof(KeyInfo) +key_parts*sizeof(KeyPartInfo));
1534 by Brian Aker
Remove of KeyPartInfo
930
931
  KeyPartInfo *key_part;
932
933
  key_part= reinterpret_cast<KeyPartInfo*>
1574.1.2 by Brian Aker
Remove =this reference.
934
    (key_info+table.indexes_size());
935
936
937
  ulong *rec_per_key= (ulong*) alloc_root(sizeof(ulong*)*key_parts);
938
939
  KeyInfo* keyinfo= key_info;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
940
  for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
941
  {
942
    message::Table::Index indx= table.indexes(keynr);
943
944
    keyinfo->table= 0;
945
    keyinfo->flags= 0;
946
947
    if (indx.is_unique())
948
      keyinfo->flags|= HA_NOSAME;
949
950
    if (indx.has_options())
951
    {
1537 by Brian Aker
Remove dead options/rename Option and remove the update that we no longer
952
      message::Table::Index::Options indx_options= indx.options();
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
953
      if (indx_options.pack_key())
954
        keyinfo->flags|= HA_PACK_KEY;
955
956
      if (indx_options.var_length_key())
957
        keyinfo->flags|= HA_VAR_LENGTH_PART;
958
959
      if (indx_options.null_part_key())
960
        keyinfo->flags|= HA_NULL_PART_KEY;
961
962
      if (indx_options.binary_pack_key())
963
        keyinfo->flags|= HA_BINARY_PACK_KEY;
964
965
      if (indx_options.has_partial_segments())
966
        keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
967
968
      if (indx_options.auto_generated_key())
969
        keyinfo->flags|= HA_GENERATED_KEY;
970
971
      if (indx_options.has_key_block_size())
972
      {
973
        keyinfo->flags|= HA_USES_BLOCK_SIZE;
974
        keyinfo->block_size= indx_options.key_block_size();
975
      }
976
      else
977
      {
978
        keyinfo->block_size= 0;
979
      }
980
    }
981
982
    switch (indx.type())
983
    {
984
    case message::Table::Index::UNKNOWN_INDEX:
985
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
986
      break;
987
    case message::Table::Index::BTREE:
988
      keyinfo->algorithm= HA_KEY_ALG_BTREE;
989
      break;
990
    case message::Table::Index::HASH:
991
      keyinfo->algorithm= HA_KEY_ALG_HASH;
992
      break;
993
994
    default:
995
      /* TODO: suitable warning ? */
996
      keyinfo->algorithm= HA_KEY_ALG_UNDEF;
997
      break;
998
    }
999
1000
    keyinfo->key_length= indx.key_length();
1001
1002
    keyinfo->key_parts= indx.index_part_size();
1003
1004
    keyinfo->key_part= key_part;
1005
    keyinfo->rec_per_key= rec_per_key;
1006
1007
    for (unsigned int partnr= 0;
1008
         partnr < keyinfo->key_parts;
1009
         partnr++, key_part++)
1010
    {
1011
      message::Table::Index::IndexPart part;
1012
      part= indx.index_part(partnr);
1013
1014
      *rec_per_key++= 0;
1015
1016
      key_part->field= NULL;
1017
      key_part->fieldnr= part.fieldnr() + 1; // start from 1.
1018
      key_part->null_bit= 0;
1019
      /* key_part->null_offset is only set if null_bit (see later) */
1020
      /* key_part->key_type= */ /* I *THINK* this may be okay.... */
1021
      /* key_part->type ???? */
1022
      key_part->key_part_flag= 0;
1023
      if (part.has_in_reverse_order())
1024
        key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
1025
1026
      key_part->length= part.compare_length();
1027
1638.8.1 by Stewart Smith
make the compare_length() of index parts of VARCHAR and BLOB (i.e. those with charsets) be a length in characters instead of bytes. This makes the logic converting a table proto back into a CREATE TABLE statement remotely sane. This does mean that if we increase the number of bytes utf8_general_ci uses, engines may have issues with their on disk formats (if they're not too smart)
1028
      int mbmaxlen= 1;
1029
1030
      if (table.field(part.fieldnr()).type() == message::Table::Field::VARCHAR
1031
          || table.field(part.fieldnr()).type() == message::Table::Field::BLOB)
1032
      {
1033
        uint32_t collation_id;
1034
1035
        if (table.field(part.fieldnr()).string_options().has_collation_id())
1036
          collation_id= table.field(part.fieldnr()).string_options().collation_id();
1037
        else
1038
          collation_id= table.options().collation_id();
1039
1040
        const CHARSET_INFO *cs= get_charset(collation_id);
1041
1042
        mbmaxlen= cs->mbmaxlen;
1043
      }
1044
      key_part->length*= mbmaxlen;
1045
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1046
      key_part->store_length= key_part->length;
1047
1048
      /* key_part->offset is set later */
1577 by Brian Aker
Next bit of pack removal (this removes it from where we store it).
1049
      key_part->key_type= 0;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1050
    }
1051
1052
    if (! indx.has_comment())
1053
    {
1054
      keyinfo->comment.length= 0;
1055
      keyinfo->comment.str= NULL;
1056
    }
1057
    else
1058
    {
1059
      keyinfo->flags|= HA_USES_COMMENT;
1060
      keyinfo->comment.length= indx.comment().length();
1574.1.2 by Brian Aker
Remove =this reference.
1061
      keyinfo->comment.str= strmake_root(indx.comment().c_str(), keyinfo->comment.length);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1062
    }
1063
1574.1.2 by Brian Aker
Remove =this reference.
1064
    keyinfo->name= strmake_root(indx.name().c_str(), indx.name().length());
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1065
1527.1.3 by Brian Aker
This is:
1066
    addKeyName(string(keyinfo->name, indx.name().length()));
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1067
  }
1068
1574.1.2 by Brian Aker
Remove =this reference.
1069
  keys_for_keyread.reset();
1070
  set_prefix(keys_in_use, keys);
1071
1072
  fields= table.field_size();
1073
1578.2.11 by Brian Aker
Use the Fields generated from share for Table.
1074
  setFields(fields + 1);
1574.1.2 by Brian Aker
Remove =this reference.
1075
  field[fields]= NULL;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1076
1077
  uint32_t local_null_fields= 0;
1574.1.2 by Brian Aker
Remove =this reference.
1078
  reclength= 0;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1079
1080
  vector<uint32_t> field_offsets;
1081
  vector<uint32_t> field_pack_length;
1082
1574.1.2 by Brian Aker
Remove =this reference.
1083
  field_offsets.resize(fields);
1084
  field_pack_length.resize(fields);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1085
1086
  uint32_t interval_count= 0;
1087
  uint32_t interval_parts= 0;
1088
1089
  uint32_t stored_columns_reclength= 0;
1090
1574.1.2 by Brian Aker
Remove =this reference.
1091
  for (unsigned int fieldnr= 0; fieldnr < fields; fieldnr++)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1092
  {
1093
    message::Table::Field pfield= table.field(fieldnr);
1094
    if (pfield.constraints().is_nullable())
1095
      local_null_fields++;
1096
1097
    enum_field_types drizzle_field_type=
1098
      proto_field_type_to_drizzle_type(pfield.type());
1099
1100
    field_offsets[fieldnr]= stored_columns_reclength;
1101
1102
    /* the below switch is very similar to
1530.1.3 by Brian Aker
Style cleanup for table_share
1103
      CreateField::create_length_to_internal_length in field.cc
1104
      (which should one day be replace by just this code)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1105
    */
1106
    switch(drizzle_field_type)
1107
    {
1108
    case DRIZZLE_TYPE_BLOB:
1109
    case DRIZZLE_TYPE_VARCHAR:
1110
      {
1111
        message::Table::Field::StringFieldOptions field_options= pfield.string_options();
1112
1113
        const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
1114
                                            field_options.collation_id() : 0);
1115
1116
        if (! cs)
1117
          cs= default_charset_info;
1118
1119
        field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
1120
                                                     field_options.length() * cs->mbmaxlen);
1121
      }
1122
      break;
1123
    case DRIZZLE_TYPE_ENUM:
1124
      {
1125
        message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
1126
1127
        field_pack_length[fieldnr]=
1128
          get_enum_pack_length(field_options.field_value_size());
1129
1130
        interval_count++;
1131
        interval_parts+= field_options.field_value_size();
1132
      }
1133
      break;
1134
    case DRIZZLE_TYPE_DECIMAL:
1135
      {
1136
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1137
1138
        field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
1139
      }
1140
      break;
1141
    default:
1142
      /* Zero is okay here as length is fixed for other types. */
1143
      field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
1144
    }
1145
1574.1.2 by Brian Aker
Remove =this reference.
1146
    reclength+= field_pack_length[fieldnr];
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1147
    stored_columns_reclength+= field_pack_length[fieldnr];
1148
  }
1149
1150
  /* data_offset added to stored_rec_length later */
1574.1.2 by Brian Aker
Remove =this reference.
1151
  stored_rec_length= stored_columns_reclength;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1152
1574.1.2 by Brian Aker
Remove =this reference.
1153
  null_fields= local_null_fields;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1154
1155
  ulong null_bits= local_null_fields;
1156
  if (! table_options.pack_record())
1157
    null_bits++;
1158
  ulong data_offset= (null_bits + 7)/8;
1159
1160
1574.1.2 by Brian Aker
Remove =this reference.
1161
  reclength+= data_offset;
1162
  stored_rec_length+= data_offset;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1163
1164
  ulong local_rec_buff_length;
1165
1574.1.2 by Brian Aker
Remove =this reference.
1166
  local_rec_buff_length= ALIGN_SIZE(reclength + 1);
1167
  rec_buff_length= local_rec_buff_length;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1168
1574.1.2 by Brian Aker
Remove =this reference.
1169
  resizeDefaultValues(local_rec_buff_length);
1170
  unsigned char* record= getDefaultValues();
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1171
  int null_count= 0;
1172
1173
  if (! table_options.pack_record())
1174
  {
1175
    null_count++; // one bit for delete mark.
1176
    *record|= 1;
1177
  }
1178
1179
1574.1.7 by Brian Aker
Remove interval allocation via memroot.
1180
  intervals.resize(interval_count);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1181
1182
  /* Now fix the TYPELIBs for the intervals (enum values)
1530.1.3 by Brian Aker
Style cleanup for table_share
1183
    and field names.
1184
  */
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1185
1186
  uint32_t interval_nr= 0;
1187
1574.1.2 by Brian Aker
Remove =this reference.
1188
  for (unsigned int fieldnr= 0; fieldnr < fields; fieldnr++)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1189
  {
1190
    message::Table::Field pfield= table.field(fieldnr);
1191
1192
    /* enum typelibs */
1193
    if (pfield.type() != message::Table::Field::ENUM)
1194
      continue;
1195
1196
    message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
1197
1579.3.14 by Stewart Smith
have a constant for the maximum number of enum elements
1198
    if (field_options.field_value_size() > Field_enum::max_supported_elements)
1579.3.11 by Stewart Smith
Fix parsing the table proto message so that an error is returned (ER_CORRUPT_TABLE_DEFINITION) if there are too many elements for an ENUM column.
1199
    {
1200
      char errmsg[100];
1201
      snprintf(errmsg, sizeof(errmsg),
1202
               _("ENUM column %s has greater than %d possible values"),
1579.3.14 by Stewart Smith
have a constant for the maximum number of enum elements
1203
               pfield.name().c_str(),
1204
               Field_enum::max_supported_elements);
1579.3.11 by Stewart Smith
Fix parsing the table proto message so that an error is returned (ER_CORRUPT_TABLE_DEFINITION) if there are too many elements for an ENUM column.
1205
      errmsg[99]='\0';
1206
1207
      my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), errmsg);
1208
      return ER_CORRUPT_TABLE_DEFINITION;
1209
    }
1210
1211
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1212
    const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
1213
                                             field_options.collation_id() : 0);
1214
1215
    if (! charset)
1216
      charset= default_charset_info;
1217
1574.1.7 by Brian Aker
Remove interval allocation via memroot.
1218
    TYPELIB *t= (&intervals[interval_nr]);
1574.1.2 by Brian Aker
Remove =this reference.
1219
1220
    t->type_names= (const char**)alloc_root((field_options.field_value_size() + 1) * sizeof(char*));
1221
1222
    t->type_lengths= (unsigned int*) alloc_root((field_options.field_value_size() + 1) * sizeof(unsigned int));
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1223
1224
    t->type_names[field_options.field_value_size()]= NULL;
1225
    t->type_lengths[field_options.field_value_size()]= 0;
1226
1227
    t->count= field_options.field_value_size();
1228
    t->name= NULL;
1229
1230
    for (int n= 0; n < field_options.field_value_size(); n++)
1231
    {
1574.1.2 by Brian Aker
Remove =this reference.
1232
      t->type_names[n]= strmake_root(field_options.field_value(n).c_str(), field_options.field_value(n).length());
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1233
1234
      /* 
1235
       * Go ask the charset what the length is as for "" length=1
1236
       * and there's stripping spaces or some other crack going on.
1530.1.3 by Brian Aker
Style cleanup for table_share
1237
     */
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1238
      uint32_t lengthsp;
1239
      lengthsp= charset->cset->lengthsp(charset,
1240
                                        t->type_names[n],
1241
                                        field_options.field_value(n).length());
1242
      t->type_lengths[n]= lengthsp;
1243
    }
1244
    interval_nr++;
1245
  }
1246
1247
1248
  /* and read the fields */
1249
  interval_nr= 0;
1250
1574.1.2 by Brian Aker
Remove =this reference.
1251
  bool use_hash= fields >= MAX_FIELDS_BEFORE_HASH;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1252
1253
  if (use_hash)
1574.1.2 by Brian Aker
Remove =this reference.
1254
    use_hash= ! hash_init(&name_hash,
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1255
                          system_charset_info,
1574.1.2 by Brian Aker
Remove =this reference.
1256
                          fields,
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1257
                          0,
1258
                          0,
1259
                          (hash_get_key) get_field_name,
1260
                          0,
1261
                          0);
1262
1574.1.2 by Brian Aker
Remove =this reference.
1263
  unsigned char* null_pos= getDefaultValues();
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1264
  int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
1265
1574.1.2 by Brian Aker
Remove =this reference.
1266
  for (unsigned int fieldnr= 0; fieldnr < fields; fieldnr++)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1267
  {
1268
    message::Table::Field pfield= table.field(fieldnr);
1269
1270
    Field::utype unireg_type= Field::NONE;
1271
1272
    if (pfield.has_numeric_options() &&
1273
        pfield.numeric_options().is_autoincrement())
1274
    {
1275
      unireg_type= Field::NEXT_NUMBER;
1276
    }
1277
1278
    if (pfield.has_options() &&
1638.3.2 by Stewart Smith
use default_expression and update_expression instead of default_value and update_value in the table proto for NOW()
1279
        pfield.options().has_default_expression() &&
1638.3.3 by Stewart Smith
store CURRENT_TIMESTAMP instead of NOW() in the table proto as this is what we end up displaying in SHOW CREATE so more accurately represents what's going on. Although it could go either way (it totally does not matter), this paves the way for SHOW CREATE TABLE running through statement_transform.
1280
        pfield.options().default_expression().compare("CURRENT_TIMESTAMP") == 0)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1281
    {
1638.3.2 by Stewart Smith
use default_expression and update_expression instead of default_value and update_value in the table proto for NOW()
1282
      if (pfield.options().has_update_expression() &&
1638.3.3 by Stewart Smith
store CURRENT_TIMESTAMP instead of NOW() in the table proto as this is what we end up displaying in SHOW CREATE so more accurately represents what's going on. Although it could go either way (it totally does not matter), this paves the way for SHOW CREATE TABLE running through statement_transform.
1283
          pfield.options().update_expression().compare("CURRENT_TIMESTAMP") == 0)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1284
      {
1285
        unireg_type= Field::TIMESTAMP_DNUN_FIELD;
1286
      }
1638.3.2 by Stewart Smith
use default_expression and update_expression instead of default_value and update_value in the table proto for NOW()
1287
      else if (! pfield.options().has_update_expression())
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1288
      {
1530.1.3 by Brian Aker
Style cleanup for table_share
1289
        unireg_type= Field::TIMESTAMP_DN_FIELD;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1290
      }
1291
      else
1530.1.3 by Brian Aker
Style cleanup for table_share
1292
        assert(1); // Invalid update value.
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1293
    }
1294
    else if (pfield.has_options() &&
1638.3.2 by Stewart Smith
use default_expression and update_expression instead of default_value and update_value in the table proto for NOW()
1295
             pfield.options().has_update_expression() &&
1638.3.3 by Stewart Smith
store CURRENT_TIMESTAMP instead of NOW() in the table proto as this is what we end up displaying in SHOW CREATE so more accurately represents what's going on. Although it could go either way (it totally does not matter), this paves the way for SHOW CREATE TABLE running through statement_transform.
1296
             pfield.options().update_expression().compare("CURRENT_TIMESTAMP") == 0)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1297
    {
1298
      unireg_type= Field::TIMESTAMP_UN_FIELD;
1299
    }
1300
1301
    LEX_STRING comment;
1302
    if (!pfield.has_comment())
1303
    {
1304
      comment.str= (char*)"";
1305
      comment.length= 0;
1306
    }
1307
    else
1308
    {
1309
      size_t len= pfield.comment().length();
1310
      const char* str= pfield.comment().c_str();
1311
1574.1.2 by Brian Aker
Remove =this reference.
1312
      comment.str= strmake_root(str, len);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1313
      comment.length= len;
1314
    }
1315
1316
    enum_field_types field_type;
1317
1318
    field_type= proto_field_type_to_drizzle_type(pfield.type());
1319
1320
    const CHARSET_INFO *charset= &my_charset_bin;
1321
1322
    if (field_type == DRIZZLE_TYPE_BLOB ||
1323
        field_type == DRIZZLE_TYPE_VARCHAR)
1324
    {
1325
      message::Table::Field::StringFieldOptions field_options= pfield.string_options();
1326
1327
      charset= get_charset(field_options.has_collation_id() ?
1328
                           field_options.collation_id() : 0);
1329
1330
      if (! charset)
1530.1.3 by Brian Aker
Style cleanup for table_share
1331
        charset= default_charset_info;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1332
    }
1333
1334
    if (field_type == DRIZZLE_TYPE_ENUM)
1335
    {
1336
      message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
1337
1338
      charset= get_charset(field_options.has_collation_id()?
1530.1.3 by Brian Aker
Style cleanup for table_share
1339
                           field_options.collation_id() : 0);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1340
1341
      if (! charset)
1530.1.3 by Brian Aker
Style cleanup for table_share
1342
        charset= default_charset_info;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1343
    }
1344
1345
    uint8_t decimals= 0;
1346
    if (field_type == DRIZZLE_TYPE_DECIMAL
1347
        || field_type == DRIZZLE_TYPE_DOUBLE)
1348
    {
1349
      message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1350
1351
      if (! pfield.has_numeric_options() || ! fo.has_scale())
1352
      {
1353
        /*
1354
          We don't write the default to table proto so
1355
          if no decimals specified for DOUBLE, we use the default.
1356
        */
1357
        decimals= NOT_FIXED_DEC;
1358
      }
1359
      else
1360
      {
1361
        if (fo.scale() > DECIMAL_MAX_SCALE)
1362
        {
1363
          local_error= 4;
1364
1530.1.3 by Brian Aker
Style cleanup for table_share
1365
          return local_error;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1366
        }
1367
        decimals= static_cast<uint8_t>(fo.scale());
1368
      }
1369
    }
1370
1371
    Item *default_value= NULL;
1372
1373
    if (pfield.options().has_default_value() ||
1638.7.1 by Stewart Smith
in the table proto, having default_null set to false explicitly (instead of just having it as a default) had a different behaviour than if it was not set and defaulting to NULL. This meant that you'd get empty defaults instead of no default. This only showed up in table_function tables.
1374
        pfield.options().default_null()  ||
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1375
        pfield.options().has_default_bin_value())
1376
    {
1377
      default_value= default_value_item(field_type,
1378
                                        charset,
1379
                                        pfield.options().default_null(),
1380
                                        &pfield.options().default_value(),
1381
                                        &pfield.options().default_bin_value());
1382
    }
1383
1384
1385
    Table temp_table; /* Use this so that BLOB DEFAULT '' works */
1386
    memset(&temp_table, 0, sizeof(temp_table));
1574.1.2 by Brian Aker
Remove =this reference.
1387
    temp_table.setShare(this);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1388
    temp_table.in_use= &session;
1574 by Brian Aker
Rollup patch for hiding tableshare.
1389
    temp_table.getMutableShare()->db_low_byte_first= true; //Cursor->low_byte_first();
1390
    temp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1391
1392
    uint32_t field_length= 0; //Assignment is for compiler complaint.
1393
1394
    switch (field_type)
1395
    {
1396
    case DRIZZLE_TYPE_BLOB:
1397
    case DRIZZLE_TYPE_VARCHAR:
1530.1.3 by Brian Aker
Style cleanup for table_share
1398
      {
1399
        message::Table::Field::StringFieldOptions field_options= pfield.string_options();
1400
1401
        charset= get_charset(field_options.has_collation_id() ?
1402
                             field_options.collation_id() : 0);
1403
1404
        if (! charset)
1405
          charset= default_charset_info;
1406
1407
        field_length= field_options.length() * charset->mbmaxlen;
1408
      }
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1409
      break;
1410
    case DRIZZLE_TYPE_DOUBLE:
1530.1.3 by Brian Aker
Style cleanup for table_share
1411
      {
1412
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1413
        if (!fo.has_precision() && !fo.has_scale())
1414
        {
1415
          field_length= DBL_DIG+7;
1416
        }
1417
        else
1418
        {
1419
          field_length= fo.precision();
1420
        }
1421
        if (field_length < decimals &&
1422
            decimals != NOT_FIXED_DEC)
1423
        {
1424
          my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
1425
          local_error= 1;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1426
1530.1.3 by Brian Aker
Style cleanup for table_share
1427
          return local_error;
1428
        }
1429
        break;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1430
      }
1431
    case DRIZZLE_TYPE_DECIMAL:
1530.1.3 by Brian Aker
Style cleanup for table_share
1432
      {
1433
        message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1434
1530.1.3 by Brian Aker
Style cleanup for table_share
1435
        field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
1436
                                                     false);
1437
        break;
1438
      }
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1439
    case DRIZZLE_TYPE_TIMESTAMP:
1440
    case DRIZZLE_TYPE_DATETIME:
1441
      field_length= DateTime::MAX_STRING_LENGTH;
1442
      break;
1443
    case DRIZZLE_TYPE_DATE:
1444
      field_length= Date::MAX_STRING_LENGTH;
1445
      break;
1446
    case DRIZZLE_TYPE_ENUM:
1447
      {
1530.1.3 by Brian Aker
Style cleanup for table_share
1448
        field_length= 0;
1449
1450
        message::Table::Field::EnumerationValues fo= pfield.enumeration_values();
1451
1452
        for (int valnr= 0; valnr < fo.field_value_size(); valnr++)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1453
        {
1530.1.3 by Brian Aker
Style cleanup for table_share
1454
          if (fo.field_value(valnr).length() > field_length)
1455
          {
1456
            field_length= charset->cset->numchars(charset,
1457
                                                  fo.field_value(valnr).c_str(),
1458
                                                  fo.field_value(valnr).c_str()
1459
                                                  + fo.field_value(valnr).length())
1460
              * charset->mbmaxlen;
1461
          }
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1462
        }
1463
      }
1530.1.3 by Brian Aker
Style cleanup for table_share
1464
      break;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1465
    case DRIZZLE_TYPE_LONG:
1466
      {
1467
        uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
1530.1.3 by Brian Aker
Style cleanup for table_share
1468
        field_length= MAX_INT_WIDTH+sign_len;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1469
      }
1470
      break;
1471
    case DRIZZLE_TYPE_LONGLONG:
1472
      field_length= MAX_BIGINT_WIDTH;
1473
      break;
1474
    case DRIZZLE_TYPE_NULL:
1475
      abort(); // Programming error
1476
    }
1477
1574.1.2 by Brian Aker
Remove =this reference.
1478
    Field* f= make_field(record + field_offsets[fieldnr] + data_offset,
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1479
                                field_length,
1480
                                pfield.constraints().is_nullable(),
1481
                                null_pos,
1482
                                null_bit_pos,
1483
                                decimals,
1484
                                field_type,
1485
                                charset,
1486
                                (Field::utype) MTYP_TYPENR(unireg_type),
1487
                                ((field_type == DRIZZLE_TYPE_ENUM) ?
1574.1.7 by Brian Aker
Remove interval allocation via memroot.
1488
                                 &intervals[interval_nr++]
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1489
                                 : (TYPELIB*) 0),
1532 by Brian Aker
just remove entirely the need for fieldnames.
1490
                                getTableProto()->field(fieldnr).name().c_str());
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1491
1574.1.2 by Brian Aker
Remove =this reference.
1492
    field[fieldnr]= f;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1493
1494
    f->init(&temp_table); /* blob default values need table obj */
1495
1496
    if (! (f->flags & NOT_NULL_FLAG))
1497
    {
1498
      *f->null_ptr|= f->null_bit;
1499
      if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
1500
        null_pos++;
1501
      null_count++;
1502
    }
1503
1504
    if (default_value)
1505
    {
1506
      enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
1637.1.2 by Brian Aker
Put in call for to make sure enum is always accurate.
1507
      session.count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1508
      int res= default_value->save_in_field(f, 1);
1509
      session.count_cuted_fields= old_count_cuted_fields;
1510
      if (res != 0 && res != 3) /* @TODO Huh? */
1511
      {
1512
        my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
1513
        local_error= 1;
1514
1530.1.3 by Brian Aker
Style cleanup for table_share
1515
        return local_error;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1516
      }
1517
    }
1518
    else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
1519
             (f->flags & NOT_NULL_FLAG))
1520
    {
1521
      f->set_notnull();
1522
      f->store((int64_t) 1, true);
1523
    }
1524
    else
1525
    {
1526
      f->reset();
1527
    }
1528
1529
    /* hack to undo f->init() */
1660.1.3 by Brian Aker
Encapsulate Table in field
1530
    f->setTable(NULL);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1531
    f->orig_table= NULL;
1532
1533
    f->field_index= fieldnr;
1534
    f->comment= comment;
1535
    if (! default_value &&
1536
        ! (f->unireg_check==Field::NEXT_NUMBER) &&
1537
        (f->flags & NOT_NULL_FLAG) &&
1538
        (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
1539
    {
1540
      f->flags|= NO_DEFAULT_VALUE_FLAG;
1541
    }
1542
1543
    if (f->unireg_check == Field::NEXT_NUMBER)
1574.1.2 by Brian Aker
Remove =this reference.
1544
      found_next_number_field= &(field[fieldnr]);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1545
1574.1.2 by Brian Aker
Remove =this reference.
1546
    if (timestamp_field == f)
1547
      timestamp_field_offset= fieldnr;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1548
1549
    if (use_hash) /* supposedly this never fails... but comments lie */
1574.1.2 by Brian Aker
Remove =this reference.
1550
      (void) my_hash_insert(&name_hash,
1551
                            (unsigned char*)&(field[fieldnr]));
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1552
1553
  }
1554
1574.1.2 by Brian Aker
Remove =this reference.
1555
  keyinfo= key_info;
1556
  for (unsigned int keynr= 0; keynr < keys; keynr++, keyinfo++)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1557
  {
1558
    key_part= keyinfo->key_part;
1559
1560
    for (unsigned int partnr= 0;
1561
         partnr < keyinfo->key_parts;
1562
         partnr++, key_part++)
1563
    {
1564
      /* 
1565
       * Fix up key_part->offset by adding data_offset.
1566
       * We really should compute offset as well.
1567
       * But at least this way we are a little better.
1530.1.3 by Brian Aker
Style cleanup for table_share
1568
     */
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1569
      key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1570
    }
1571
  }
1572
1573
  /*
1574
    We need to set the unused bits to 1. If the number of bits is a multiple
1575
    of 8 there are no unused bits.
1576
  */
1577
1578
  if (null_count & 7)
1579
    *(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1580
1574.1.2 by Brian Aker
Remove =this reference.
1581
  null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1582
1574.1.2 by Brian Aker
Remove =this reference.
1583
  last_null_bit_pos= null_bit_pos;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1584
1585
  /* Fix key stuff */
1574.1.2 by Brian Aker
Remove =this reference.
1586
  if (key_parts)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1587
  {
1527.1.4 by Brian Aker
Second pass to remove keynames typelib.
1588
    uint32_t local_primary_key= 0;
1589
    doesKeyNameExist("PRIMARY", local_primary_key);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1590
1574.1.2 by Brian Aker
Remove =this reference.
1591
    keyinfo= key_info;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1592
    key_part= keyinfo->key_part;
1593
1574.1.2 by Brian Aker
Remove =this reference.
1594
    for (uint32_t key= 0; key < keys; key++,keyinfo++)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1595
    {
1596
      uint32_t usable_parts= 0;
1597
1598
      if (local_primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1599
      {
1530.1.3 by Brian Aker
Style cleanup for table_share
1600
        /*
1601
          If the UNIQUE key doesn't have NULL columns and is not a part key
1602
          declare this as a primary key.
1603
        */
1604
        local_primary_key=key;
1605
        for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1606
        {
1607
          uint32_t fieldnr= key_part[i].fieldnr;
1608
          if (! fieldnr ||
1574.1.2 by Brian Aker
Remove =this reference.
1609
              field[fieldnr-1]->null_ptr ||
1610
              field[fieldnr-1]->key_length() != key_part[i].length)
1530.1.3 by Brian Aker
Style cleanup for table_share
1611
          {
1612
            local_primary_key= MAX_KEY; // Can't be used
1613
            break;
1614
          }
1615
        }
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1616
      }
1617
1618
      for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1619
      {
1530.1.3 by Brian Aker
Style cleanup for table_share
1620
        Field *local_field;
1621
        if (! key_part->fieldnr)
1622
        {
1623
          return ENOMEM;
1624
        }
1574.1.2 by Brian Aker
Remove =this reference.
1625
        local_field= key_part->field= field[key_part->fieldnr-1];
1530.1.3 by Brian Aker
Style cleanup for table_share
1626
        key_part->type= local_field->key_type();
1627
        if (local_field->null_ptr)
1628
        {
1574.1.2 by Brian Aker
Remove =this reference.
1629
          key_part->null_offset=(uint32_t) ((unsigned char*) local_field->null_ptr - getDefaultValues());
1530.1.3 by Brian Aker
Style cleanup for table_share
1630
          key_part->null_bit= local_field->null_bit;
1631
          key_part->store_length+=HA_KEY_NULL_LENGTH;
1632
          keyinfo->flags|=HA_NULL_PART_KEY;
1633
          keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
1634
          keyinfo->key_length+= HA_KEY_NULL_LENGTH;
1635
        }
1636
        if (local_field->type() == DRIZZLE_TYPE_BLOB ||
1637
            local_field->real_type() == DRIZZLE_TYPE_VARCHAR)
1638
        {
1639
          if (local_field->type() == DRIZZLE_TYPE_BLOB)
1640
            key_part->key_part_flag|= HA_BLOB_PART;
1641
          else
1642
            key_part->key_part_flag|= HA_VAR_LENGTH_PART;
1643
          keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
1644
          key_part->store_length+=HA_KEY_BLOB_LENGTH;
1645
          keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
1646
        }
1647
        if (i == 0 && key != local_primary_key)
1648
          local_field->flags |= (((keyinfo->flags & HA_NOSAME) &&
1649
                                  (keyinfo->key_parts == 1)) ?
1650
                                 UNIQUE_KEY_FLAG : MULTIPLE_KEY_FLAG);
1651
        if (i == 0)
1652
          local_field->key_start.set(key);
1653
        if (local_field->key_length() == key_part->length &&
1654
            !(local_field->flags & BLOB_FLAG))
1655
        {
1574.1.2 by Brian Aker
Remove =this reference.
1656
          enum ha_key_alg algo= key_info[key].algorithm;
1657
          if (db_type()->index_flags(algo) & HA_KEYREAD_ONLY)
1530.1.3 by Brian Aker
Style cleanup for table_share
1658
          {
1574.1.2 by Brian Aker
Remove =this reference.
1659
            keys_for_keyread.set(key);
1530.1.3 by Brian Aker
Style cleanup for table_share
1660
            local_field->part_of_key.set(key);
1661
            local_field->part_of_key_not_clustered.set(key);
1662
          }
1574.1.2 by Brian Aker
Remove =this reference.
1663
          if (db_type()->index_flags(algo) & HA_READ_ORDER)
1530.1.3 by Brian Aker
Style cleanup for table_share
1664
            local_field->part_of_sortkey.set(key);
1665
        }
1666
        if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
1667
            usable_parts == i)
1668
          usable_parts++;			// For FILESORT
1669
        local_field->flags|= PART_KEY_FLAG;
1670
        if (key == local_primary_key)
1671
        {
1672
          local_field->flags|= PRI_KEY_FLAG;
1673
          /*
1674
            If this field is part of the primary key and all keys contains
1675
            the primary key, then we can use any key to find this column
1676
          */
1574.1.2 by Brian Aker
Remove =this reference.
1677
          if (storage_engine->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX))
1530.1.3 by Brian Aker
Style cleanup for table_share
1678
          {
1574.1.2 by Brian Aker
Remove =this reference.
1679
            local_field->part_of_key= keys_in_use;
1530.1.3 by Brian Aker
Style cleanup for table_share
1680
            if (local_field->part_of_sortkey.test(key))
1574.1.2 by Brian Aker
Remove =this reference.
1681
              local_field->part_of_sortkey= keys_in_use;
1530.1.3 by Brian Aker
Style cleanup for table_share
1682
          }
1683
        }
1684
        if (local_field->key_length() != key_part->length)
1685
        {
1686
          key_part->key_part_flag|= HA_PART_KEY_SEG;
1687
        }
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1688
      }
1689
      keyinfo->usable_key_parts= usable_parts; // Filesort
1690
1574.1.2 by Brian Aker
Remove =this reference.
1691
      set_if_bigger(max_key_length,keyinfo->key_length+
1530.1.3 by Brian Aker
Style cleanup for table_share
1692
                    keyinfo->key_parts);
1574.1.2 by Brian Aker
Remove =this reference.
1693
      total_key_length+= keyinfo->key_length;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1694
1695
      if (keyinfo->flags & HA_NOSAME)
1696
      {
1574.1.2 by Brian Aker
Remove =this reference.
1697
        set_if_bigger(max_unique_length,keyinfo->key_length);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1698
      }
1699
    }
1700
    if (local_primary_key < MAX_KEY &&
1574.1.2 by Brian Aker
Remove =this reference.
1701
        (keys_in_use.test(local_primary_key)))
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1702
    {
1574.1.2 by Brian Aker
Remove =this reference.
1703
      primary_key= local_primary_key;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1704
      /*
1705
        If we are using an integer as the primary key then allow the user to
1706
        refer to it as '_rowid'
1707
      */
1574.1.2 by Brian Aker
Remove =this reference.
1708
      if (key_info[local_primary_key].key_parts == 1)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1709
      {
1574.1.2 by Brian Aker
Remove =this reference.
1710
        Field *local_field= key_info[local_primary_key].key_part[0].field;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1711
        if (local_field && local_field->result_type() == INT_RESULT)
1712
        {
1713
          /* note that fieldnr here (and rowid_field_offset) starts from 1 */
1574.1.2 by Brian Aker
Remove =this reference.
1714
          rowid_field_offset= (key_info[local_primary_key].key_part[0].
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1715
                                      fieldnr);
1716
        }
1717
      }
1718
    }
1719
  }
1720
1574.1.2 by Brian Aker
Remove =this reference.
1721
  if (found_next_number_field)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1722
  {
1574.1.2 by Brian Aker
Remove =this reference.
1723
    Field *reg_field= *found_next_number_field;
1724
    if ((int) (next_number_index= (uint32_t)
1725
               find_ref_key(key_info, keys,
1726
                            getDefaultValues(), reg_field,
1727
                            &next_number_key_offset,
1728
                            &next_number_keypart)) < 0)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1729
    {
1730
      /* Wrong field definition */
1731
      local_error= 4;
1732
1733
      return local_error;
1734
    }
1735
    else
1736
    {
1737
      reg_field->flags |= AUTO_INCREMENT_FLAG;
1738
    }
1739
  }
1740
1574.1.2 by Brian Aker
Remove =this reference.
1741
  if (blob_fields)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1742
  {
1743
    uint32_t k, *save;
1744
1745
    /* Store offsets to blob fields to find them fast */
1574.1.8 by Brian Aker
Blob now allocated via vector
1746
    blob_field.resize(blob_fields);
1747
    save= &blob_field[0];
1578.2.13 by Brian Aker
Use iterator for Field in share creation.
1748
    k= 0;
1578.2.14 by Brian Aker
Additional pass through to remove raw field access.
1749
    for (Fields::iterator iter= field.begin(); iter != field.end()-1; iter++, k++)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1750
    {
1578.2.13 by Brian Aker
Use iterator for Field in share creation.
1751
      if ((*iter)->flags & BLOB_FLAG)
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1752
        (*save++)= k;
1753
    }
1754
  }
1755
1574.1.2 by Brian Aker
Remove =this reference.
1756
  db_low_byte_first= true; // @todo Question this.
1757
  column_bitmap_size= bitmap_buffer_size(fields);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1758
1574.1.5 by Brian Aker
Additional removal of mybitmap to being more C++
1759
  all_bitmap.resize(column_bitmap_size);
1760
  all_set.init(&all_bitmap[0], fields);
1761
  all_set.setAll();
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1762
1763
  return local_error;
1764
}
1765
1766
int TableShare::parse_table_proto(Session& session, message::Table &table)
1767
{
1768
  int local_error= inner_parse_table_proto(session, table);
1769
1770
  if (not local_error)
1771
    return 0;
1772
1773
  error= local_error;
1774
  open_errno= errno;
1775
  errarg= 0;
1776
  hash_free(&name_hash);
1777
  open_table_error(local_error, open_errno, 0);
1778
1779
  return local_error;
1780
}
1781
1782
1783
/*
1784
  Read table definition from a binary / text based .frm cursor
1785
1786
  SYNOPSIS
1787
  open_table_def()
1788
  session		Thread Cursor
1789
  share		Fill this with table definition
1790
1791
  NOTES
1530.1.3 by Brian Aker
Style cleanup for table_share
1792
  This function is called when the table definition is not cached in
1793
  table_def_cache
1794
  The data is returned in 'share', which is alloced by
1795
  alloc_table_share().. The code assumes that share is initialized.
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1796
1797
  RETURN VALUES
1530.1.3 by Brian Aker
Style cleanup for table_share
1798
  0	ok
1799
  1	Error (see open_table_error)
1800
  2    Error (see open_table_error)
1801
  3    Wrong data in .frm cursor
1802
  4    Error (see open_table_error)
1803
  5    Error (see open_table_error: charset unavailable)
1804
  6    Unknown .frm version
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1805
*/
1806
1807
int TableShare::open_table_def(Session& session, TableIdentifier &identifier)
1808
{
1809
  int local_error;
1810
  bool error_given;
1811
1812
  local_error= 1;
1813
  error_given= 0;
1814
1815
  message::Table table;
1816
1817
  local_error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1818
1819
  if (local_error != EEXIST)
1820
  {
1821
    if (local_error > 0)
1822
    {
1823
      errno= local_error;
1824
      local_error= 1;
1825
    }
1826
    else
1827
    {
1828
      if (not table.IsInitialized())
1829
      {
1530.1.3 by Brian Aker
Style cleanup for table_share
1830
        local_error= 4;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1831
      }
1832
    }
1833
    goto err_not_open;
1834
  }
1835
1836
  local_error= parse_table_proto(session, table);
1837
1838
  setTableCategory(TABLE_CATEGORY_USER);
1839
1840
err_not_open:
1841
  if (local_error && !error_given)
1842
  {
1843
    error= local_error;
1844
    open_table_error(error, (open_errno= errno), 0);
1845
  }
1846
1847
  return(error);
1848
}
1849
1850
1851
/*
1852
  Open a table based on a TableShare
1853
1854
  SYNOPSIS
1530.1.3 by Brian Aker
Style cleanup for table_share
1855
  open_table_from_share()
1856
  session			Thread Cursor
1857
  share		Table definition
1858
  alias       	Alias for table
1859
  db_stat		open flags (for example HA_OPEN_KEYFILE|
1860
  HA_OPEN_RNDFILE..) can be 0 (example in
1861
  ha_example_table)
1862
  ha_open_flags	HA_OPEN_ABORT_IF_LOCKED etc..
1863
  outparam       	result table
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1864
1865
  RETURN VALUES
1530.1.3 by Brian Aker
Style cleanup for table_share
1866
  0	ok
1867
  1	Error (see open_table_error)
1868
  2    Error (see open_table_error)
1869
  3    Wrong data in .frm cursor
1870
  4    Error (see open_table_error)
1871
  5    Error (see open_table_error: charset unavailable)
1872
  7    Table definition has changed in engine
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1873
*/
1874
1626.3.2 by Brian Aker
Cleanup table_share to pass in identifier.
1875
int TableShare::open_table_from_share(Session *session,
1876
                                      const TableIdentifier &identifier,
1877
                                      const char *alias,
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1878
                                      uint32_t db_stat, uint32_t ha_open_flags,
1879
                                      Table &outparam)
1880
{
1881
  int local_error;
1882
  uint32_t records, bitmap_size;
1883
  bool error_reported= false;
1884
  unsigned char *record, *bitmaps;
1885
  Field **field_ptr;
1886
1887
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1888
  assert(session->lex->is_lex_started);
1889
1890
  local_error= 1;
1891
  outparam.resetTable(session, this, db_stat);
1892
1893
1894
  if (not (outparam.alias= strdup(alias)))
1895
    goto err;
1896
1897
  /* Allocate Cursor */
1532.1.8 by Brian Aker
Yet more movement/encapsulation of mem_root in table.
1898
  if (not (outparam.cursor= db_type()->getCursor(*this, outparam.getMemRoot())))
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1899
    goto err;
1900
1901
  local_error= 4;
1902
  records= 0;
1903
  if ((db_stat & HA_OPEN_KEYFILE))
1904
    records=1;
1905
1906
  records++;
1907
1532.1.8 by Brian Aker
Yet more movement/encapsulation of mem_root in table.
1908
  if (!(record= (unsigned char*) outparam.alloc_root(rec_buff_length * records)))
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1909
    goto err;
1910
1911
  if (records == 0)
1912
  {
1913
    /* We are probably in hard repair, and the buffers should not be used */
1574 by Brian Aker
Rollup patch for hiding tableshare.
1914
    outparam.record[0]= outparam.record[1]= getDefaultValues();
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1915
  }
1916
  else
1917
  {
1918
    outparam.record[0]= record;
1919
    if (records > 1)
1920
      outparam.record[1]= record+ rec_buff_length;
1921
    else
1922
      outparam.record[1]= outparam.record[0];   // Safety
1923
  }
1924
1925
#ifdef HAVE_purify
1926
  /*
1927
    We need this because when we read var-length rows, we are not updating
1928
    bytes after end of varchar
1929
  */
1930
  if (records > 1)
1931
  {
1574 by Brian Aker
Rollup patch for hiding tableshare.
1932
    memcpy(outparam.record[0], getDefaultValues(), rec_buff_length);
1933
    memcpy(outparam.record[1], getDefaultValues(), null_bytes);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1934
    if (records > 2)
1574 by Brian Aker
Rollup patch for hiding tableshare.
1935
      memcpy(outparam.record[1], getDefaultValues(), rec_buff_length);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1936
  }
1937
#endif
1938
  if (records > 1)
1939
  {
1574 by Brian Aker
Rollup patch for hiding tableshare.
1940
    memcpy(outparam.record[1], getDefaultValues(), null_bytes);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1941
  }
1942
1532.1.8 by Brian Aker
Yet more movement/encapsulation of mem_root in table.
1943
  if (!(field_ptr = (Field **) outparam.alloc_root( (uint32_t) ((fields+1)* sizeof(Field*)))))
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1944
  {
1945
    goto err;
1946
  }
1947
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
1948
  outparam.setFields(field_ptr);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1949
1950
  record= (unsigned char*) outparam.record[0]-1;	/* Fieldstart = 1 */
1951
1952
  outparam.null_flags= (unsigned char*) record+1;
1953
1954
  /* Setup copy of fields from share, but use the right alias and record */
1955
  for (uint32_t i= 0 ; i < fields; i++, field_ptr++)
1956
  {
1532.1.8 by Brian Aker
Yet more movement/encapsulation of mem_root in table.
1957
    if (!((*field_ptr)= field[i]->clone(outparam.getMemRoot(), &outparam)))
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1958
      goto err;
1959
  }
1960
  (*field_ptr)= 0;                              // End marker
1961
1962
  if (found_next_number_field)
1963
    outparam.found_next_number_field=
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
1964
      outparam.getField(positionFields(found_next_number_field));
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1965
  if (timestamp_field)
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
1966
    outparam.timestamp_field= (Field_timestamp*) outparam.getField(timestamp_field_offset);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1967
1968
1969
  /* Fix key->name and key_part->field */
1970
  if (key_parts)
1971
  {
1535 by Brian Aker
Rename of KEY to KeyInfo
1972
    KeyInfo	*local_key_info, *key_info_end;
1534 by Brian Aker
Remove of KeyPartInfo
1973
    KeyPartInfo *key_part;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1974
    uint32_t n_length;
1535 by Brian Aker
Rename of KEY to KeyInfo
1975
    n_length= keys*sizeof(KeyInfo) + key_parts*sizeof(KeyPartInfo);
1532.1.8 by Brian Aker
Yet more movement/encapsulation of mem_root in table.
1976
    if (!(local_key_info= (KeyInfo*) outparam.alloc_root(n_length)))
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1977
      goto err;
1978
    outparam.key_info= local_key_info;
1534 by Brian Aker
Remove of KeyPartInfo
1979
    key_part= (reinterpret_cast<KeyPartInfo*> (local_key_info+keys));
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1980
1981
    memcpy(local_key_info, key_info, sizeof(*local_key_info)*keys);
1982
    memcpy(key_part, key_info[0].key_part, (sizeof(*key_part) *
1530.1.3 by Brian Aker
Style cleanup for table_share
1983
                                            key_parts));
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1984
1985
    for (key_info_end= local_key_info + keys ;
1986
         local_key_info < key_info_end ;
1987
         local_key_info++)
1988
    {
1534 by Brian Aker
Remove of KeyPartInfo
1989
      KeyPartInfo *key_part_end;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1990
1991
      local_key_info->table= &outparam;
1992
      local_key_info->key_part= key_part;
1993
1994
      for (key_part_end= key_part+ local_key_info->key_parts ;
1995
           key_part < key_part_end ;
1996
           key_part++)
1997
      {
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
1998
        Field *local_field= key_part->field= outparam.getField(key_part->fieldnr-1);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
1999
2000
        if (local_field->key_length() != key_part->length &&
2001
            !(local_field->flags & BLOB_FLAG))
2002
        {
2003
          /*
2004
            We are using only a prefix of the column as a key:
2005
            Create a new field for the key part that matches the index
2006
          */
1532.1.8 by Brian Aker
Yet more movement/encapsulation of mem_root in table.
2007
          local_field= key_part->field= local_field->new_field(outparam.getMemRoot(), &outparam, 0);
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2008
          local_field->field_length= key_part->length;
2009
        }
2010
      }
2011
    }
2012
  }
2013
2014
  /* Allocate bitmaps */
2015
2016
  bitmap_size= column_bitmap_size;
1532.1.8 by Brian Aker
Yet more movement/encapsulation of mem_root in table.
2017
  if (!(bitmaps= (unsigned char*) outparam.alloc_root(bitmap_size*3)))
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2018
  {
2019
    goto err;
2020
  }
2021
  outparam.def_read_set.init((my_bitmap_map*) bitmaps, fields);
2022
  outparam.def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), fields);
2023
  outparam.tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), fields);
2024
  outparam.default_column_bitmaps();
2025
2026
  /* The table struct is now initialized;  Open the table */
2027
  local_error= 2;
2028
  if (db_stat)
2029
  {
1578.2.9 by Brian Aker
Simplify ha_open.
2030
    assert(!(db_stat & HA_WAIT_IF_LOCKED));
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2031
    int ha_err;
1626.3.1 by Brian Aker
Adding in TableIdentifier for ha_open; (first pass)
2032
2033
    if ((ha_err= (outparam.cursor->ha_open(identifier, &outparam, getNormalizedPath(),
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2034
                          (db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1578.2.9 by Brian Aker
Simplify ha_open.
2035
                          (db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2036
    {
2037
      switch (ha_err)
2038
      {
1530.1.3 by Brian Aker
Style cleanup for table_share
2039
      case HA_ERR_NO_SUCH_TABLE:
2040
        /*
2041
          The table did not exists in storage engine, use same error message
2042
          as if the .frm cursor didn't exist
2043
        */
2044
        local_error= 1;
2045
        errno= ENOENT;
2046
        break;
2047
      case EMFILE:
2048
        /*
2049
          Too many files opened, use same error message as if the .frm
2050
          cursor can't open
2051
        */
2052
        local_error= 1;
2053
        errno= EMFILE;
2054
        break;
2055
      default:
2056
        outparam.print_error(ha_err, MYF(0));
2057
        error_reported= true;
2058
        if (ha_err == HA_ERR_TABLE_DEF_CHANGED)
2059
          local_error= 7;
2060
        break;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2061
      }
2062
      goto err;
2063
    }
2064
  }
2065
2066
#if defined(HAVE_purify)
2067
  memset(bitmaps, 0, bitmap_size*3);
2068
#endif
2069
2070
  return 0;
2071
1530.1.3 by Brian Aker
Style cleanup for table_share
2072
err:
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2073
  if (!error_reported)
2074
    open_table_error(local_error, errno, 0);
2075
2076
  delete outparam.cursor;
2077
  outparam.cursor= 0;				// For easier error checking
2078
  outparam.db_stat= 0;
1532.1.8 by Brian Aker
Yet more movement/encapsulation of mem_root in table.
2079
  outparam.getMemRoot()->free_root(MYF(0));       // Safe to call on zeroed root
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2080
  free((char*) outparam.alias);
2081
  return (local_error);
2082
}
2083
2084
/* error message when opening a form cursor */
2085
void TableShare::open_table_error(int pass_error, int db_errno, int pass_errarg)
2086
{
2087
  int err_no;
2088
  char buff[FN_REFLEN];
2089
  myf errortype= ME_ERROR+ME_WAITTANG;
2090
2091
  switch (pass_error) {
2092
  case 7:
2093
  case 1:
2094
    if (db_errno == ENOENT)
2095
    {
2096
      my_error(ER_NO_SUCH_TABLE, MYF(0), db.str, table_name.str);
2097
    }
2098
    else
2099
    {
2100
      snprintf(buff, sizeof(buff), "%s",normalized_path.str);
2101
      my_error((db_errno == EMFILE) ? ER_CANT_OPEN_FILE : ER_FILE_NOT_FOUND,
2102
               errortype, buff, db_errno);
2103
    }
2104
    break;
2105
  case 2:
1530.1.3 by Brian Aker
Style cleanup for table_share
2106
    {
2107
      err_no= (db_errno == ENOENT) ? ER_FILE_NOT_FOUND : (db_errno == EAGAIN) ?
2108
        ER_FILE_USED : ER_CANT_OPEN_FILE;
1578.4.11 by Brian Aker
PAss through the code removing current_session
2109
      my_error(err_no, errortype, normalized_path.str, db_errno);
1530.1.3 by Brian Aker
Style cleanup for table_share
2110
      break;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2111
    }
2112
  case 5:
2113
    {
1530.1.3 by Brian Aker
Style cleanup for table_share
2114
      const char *csname= get_charset_name((uint32_t) pass_errarg);
2115
      char tmp[10];
2116
      if (!csname || csname[0] =='?')
2117
      {
2118
        snprintf(tmp, sizeof(tmp), "#%d", pass_errarg);
2119
        csname= tmp;
2120
      }
2121
      my_printf_error(ER_UNKNOWN_COLLATION,
2122
                      _("Unknown collation '%s' in table '%-.64s' definition"),
2123
                      MYF(0), csname, table_name.str);
2124
      break;
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2125
    }
2126
  case 6:
2127
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
2128
    my_printf_error(ER_NOT_FORM_FILE,
2129
                    _("Table '%-.64s' was created with a different version "
1530.1.3 by Brian Aker
Style cleanup for table_share
2130
                      "of Drizzle and cannot be read"),
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2131
                    MYF(0), buff);
2132
    break;
2133
  case 8:
2134
    break;
2135
  default:				/* Better wrong error than none */
2136
  case 4:
2137
    snprintf(buff, sizeof(buff), "%s", normalized_path.str);
2138
    my_error(ER_NOT_FORM_FILE, errortype, buff, 0);
2139
    break;
2140
  }
2141
  return;
2142
} /* open_table_error */
2143
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2144
Field *TableShare::make_field(unsigned char *ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2145
                              uint32_t field_length,
2146
                              bool is_nullable,
2147
                              unsigned char *null_pos,
2148
                              unsigned char null_bit,
2149
                              uint8_t decimals,
2150
                              enum_field_types field_type,
2151
                              const CHARSET_INFO * field_charset,
2152
                              Field::utype unireg_check,
2153
                              TYPELIB *interval,
2154
                              const char *field_name)
2155
{
2156
  if (! is_nullable)
2157
  {
2158
    null_pos=0;
2159
    null_bit=0;
2160
  }
2161
  else
2162
  {
2163
    null_bit= ((unsigned char) 1) << null_bit;
2164
  }
2165
2166
  switch (field_type) 
2167
  {
2168
  case DRIZZLE_TYPE_DATE:
2169
  case DRIZZLE_TYPE_DATETIME:
2170
  case DRIZZLE_TYPE_TIMESTAMP:
2171
    field_charset= &my_charset_bin;
2172
  default: break;
2173
  }
2174
2175
  switch (field_type)
2176
  {
2177
  case DRIZZLE_TYPE_ENUM:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2178
    return new (&mem_root) Field_enum(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2179
                                 field_length,
2180
                                 null_pos,
2181
                                 null_bit,
2182
                                 field_name,
2183
                                 get_enum_pack_length(interval->count),
2184
                                 interval,
2185
                                 field_charset);
2186
  case DRIZZLE_TYPE_VARCHAR:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2187
    return new (&mem_root) Field_varstring(ptr,field_length,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2188
                                      HA_VARCHAR_PACKLENGTH(field_length),
2189
                                      null_pos,null_bit,
2190
                                      field_name,
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2191
                                      this,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2192
                                      field_charset);
2193
  case DRIZZLE_TYPE_BLOB:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2194
    return new (&mem_root) Field_blob(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2195
                                 null_pos,
2196
                                 null_bit,
2197
                                 field_name,
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2198
                                 this,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2199
                                 calc_pack_length(DRIZZLE_TYPE_LONG, 0),
2200
                                 field_charset);
2201
  case DRIZZLE_TYPE_DECIMAL:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2202
    return new (&mem_root) Field_decimal(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2203
                                    field_length,
2204
                                    null_pos,
2205
                                    null_bit,
2206
                                    unireg_check,
2207
                                    field_name,
2208
                                    decimals,
2209
                                    false,
2210
                                    false /* is_unsigned */);
2211
  case DRIZZLE_TYPE_DOUBLE:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2212
    return new (&mem_root) Field_double(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2213
                                   field_length,
2214
                                   null_pos,
2215
                                   null_bit,
2216
                                   unireg_check,
2217
                                   field_name,
2218
                                   decimals,
2219
                                   false,
2220
                                   false /* is_unsigned */);
2221
  case DRIZZLE_TYPE_LONG:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2222
    return new (&mem_root) Field_long(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2223
                                 field_length,
2224
                                 null_pos,
2225
                                 null_bit,
2226
                                 unireg_check,
2227
                                 field_name,
2228
                                 false,
2229
                                 false /* is_unsigned */);
2230
  case DRIZZLE_TYPE_LONGLONG:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2231
    return new (&mem_root) Field_int64_t(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2232
                                    field_length,
2233
                                    null_pos,
2234
                                    null_bit,
2235
                                    unireg_check,
2236
                                    field_name,
2237
                                    false,
2238
                                    false /* is_unsigned */);
2239
  case DRIZZLE_TYPE_TIMESTAMP:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2240
    return new (&mem_root) Field_timestamp(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2241
                                      field_length,
2242
                                      null_pos,
2243
                                      null_bit,
2244
                                      unireg_check,
2245
                                      field_name,
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2246
                                      this,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2247
                                      field_charset);
2248
  case DRIZZLE_TYPE_DATE:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2249
    return new (&mem_root) Field_date(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2250
                                 null_pos,
2251
                                 null_bit,
2252
                                 field_name,
2253
                                 field_charset);
2254
  case DRIZZLE_TYPE_DATETIME:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2255
    return new (&mem_root) Field_datetime(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2256
                                     null_pos,
2257
                                     null_bit,
2258
                                     field_name,
2259
                                     field_charset);
2260
  case DRIZZLE_TYPE_NULL:
1532.1.6 by Brian Aker
Encapsulate the ownership of the table members to the table (so not in
2261
    return new (&mem_root) Field_null(ptr,
1530.1.2 by Brian Aker
Second pass through field name, this also corrects _ name usage.
2262
                                 field_length,
2263
                                 field_name,
2264
                                 field_charset);
2265
  default: // Impossible (Wrong version)
2266
    break;
2267
  }
2268
  return 0;
2269
}
2270
1527.1.2 by Brian Aker
Move all TableShare methods into .cc file.
2271
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
2272
} /* namespace drizzled */