~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/heap/ha_heap.cc

  • Committer: Zimin
  • Date: 2010-06-30 06:36:56 UTC
  • mto: (1643.1.5 build)
  • mto: This revision was merged to the branch mainline in revision 1644.
  • Revision ID: ziminq@gmail.com-20100630063656-5oa531u1mfyn6ybl
move the comment of 'create' in TableList as well

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
#include "heap_priv.h"
17
17
#include <drizzled/error.h>
21
21
#include <drizzled/field/varstring.h>
22
22
#include "drizzled/plugin/daemon.h"
23
23
 
24
 
#include <boost/thread/mutex.hpp>
25
 
 
26
24
#include "heap.h"
27
25
#include "ha_heap.h"
28
26
 
34
32
 
35
33
static const string engine_name("MEMORY");
36
34
 
37
 
boost::mutex THR_LOCK_heap;
 
35
pthread_mutex_t THR_LOCK_heap= PTHREAD_MUTEX_INITIALIZER;
38
36
 
39
37
static const char *ha_heap_exts[] = {
40
38
  NULL
53
51
                          HTON_SKIP_STORE_LOCK |
54
52
                          HTON_TEMPORARY_ONLY)
55
53
  {
 
54
    pthread_mutex_init(&THR_LOCK_heap, MY_MUTEX_INIT_FAST);
56
55
  }
57
56
 
58
57
  virtual ~HeapEngine()
59
58
  {
60
59
    hp_panic(HA_PANIC_CLOSE);
 
60
 
 
61
    pthread_mutex_destroy(&THR_LOCK_heap);
61
62
  }
62
63
 
63
 
  virtual Cursor *create(Table &table)
 
64
  virtual Cursor *create(TableShare &table,
 
65
                          memory::Root *mem_root)
64
66
  {
65
 
    return new ha_heap(*this, table);
 
67
    return new (mem_root) ha_heap(*this, table);
66
68
  }
67
69
 
68
70
  const char **bas_ext() const {
93
95
                           const TableIdentifier &identifier,
94
96
                           message::Table &table_message);
95
97
 
 
98
  /* Temp only engine, so do not return values. */
 
99
  void doGetTableNames(CachedDirectory &, SchemaIdentifier& , set<string>&) { };
 
100
 
96
101
  uint32_t max_supported_keys()          const { return MAX_KEY; }
97
102
  uint32_t max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
98
103
 
99
 
  uint32_t index_flags(enum  ha_key_alg ) const
 
104
  uint32_t index_flags(enum  ha_key_alg algorithm) const
100
105
  {
101
 
    return ( HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
 
106
    return ((algorithm == HA_KEY_ALG_BTREE) ?
 
107
            HA_READ_NEXT |
 
108
            HA_READ_PREV |
 
109
            HA_READ_ORDER |
 
110
            HA_READ_RANGE :
 
111
            HA_ONLY_WHOLE_INDEX |
 
112
            HA_KEY_SCAN_NOT_ROR);
102
113
  }
103
114
 
104
115
  bool doDoesTableExist(Session& session, const TableIdentifier &identifier);
105
116
  void doGetTableIdentifiers(CachedDirectory &directory,
106
 
                             const SchemaIdentifier &schema_identifier,
107
 
                             TableIdentifier::vector &set_of_identifiers);
 
117
                             SchemaIdentifier &schema_identifier,
 
118
                             TableIdentifiers &set_of_identifiers);
108
119
};
109
120
 
110
121
void HeapEngine::doGetTableIdentifiers(CachedDirectory&,
111
 
                                       const SchemaIdentifier&,
112
 
                                       TableIdentifier::vector&)
 
122
                                       SchemaIdentifier&,
 
123
                                       TableIdentifiers&)
113
124
{
114
125
}
115
126
 
116
127
bool HeapEngine::doDoesTableExist(Session& session, const TableIdentifier &identifier)
117
128
{
118
 
  return session.getMessageCache().doesTableMessageExist(identifier);
 
129
  return session.doesTableMessageExist(identifier);
119
130
}
120
131
 
121
132
int HeapEngine::doGetTableDefinition(Session &session,
122
133
                                     const TableIdentifier &identifier,
123
134
                                     message::Table &table_proto)
124
135
{
125
 
  if (session.getMessageCache().getTableMessage(identifier, table_proto))
 
136
  if (session.getTableMessage(identifier, table_proto))
126
137
    return EEXIST;
127
138
 
128
139
  return ENOENT;
133
144
*/
134
145
int HeapEngine::doDropTable(Session &session, const TableIdentifier &identifier)
135
146
{
136
 
  session.getMessageCache().removeTableMessage(identifier);
 
147
  session.removeTableMessage(identifier);
137
148
 
138
149
  int error= heap_delete_table(identifier.getPath().c_str());
139
150
 
158
169
*****************************************************************************/
159
170
 
160
171
ha_heap::ha_heap(plugin::StorageEngine &engine_arg,
161
 
                 Table &table_arg)
 
172
                 TableShare &table_arg)
162
173
  :Cursor(engine_arg, table_arg), file(0), records_changed(0), key_stat_version(0),
163
174
  internal_table(0)
164
175
{}
176
187
*/
177
188
#define MEMORY_STATS_UPDATE_THRESHOLD 10
178
189
 
179
 
int ha_heap::doOpen(const drizzled::TableIdentifier &identifier, int mode, uint32_t test_if_locked)
 
190
int ha_heap::open(const char *name, int mode, uint32_t test_if_locked)
180
191
{
181
 
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(identifier.getPath().c_str(), mode)) && errno == ENOENT))
 
192
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && errno == ENOENT))
182
193
  {
 
194
    HA_CREATE_INFO create_info;
183
195
    internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
 
196
    memset(&create_info, 0, sizeof(create_info));
184
197
    file= 0;
185
198
    HP_SHARE *internal_share= NULL;
186
199
    message::Table create_proto;
187
200
 
188
 
    if (not heap_storage_engine->heap_create_table(getTable()->in_use,
189
 
                                                   identifier.getPath().c_str(),
190
 
                                                   getTable(),
191
 
                                                   internal_table,
192
 
                                                   create_proto,
193
 
                                                   &internal_share))
 
201
    if (!heap_storage_engine->heap_create_table(table->in_use, name, table,
 
202
                                                internal_table,
 
203
                                                create_proto,
 
204
                                                &internal_share))
194
205
    {
195
206
        file= internal_table ?
196
207
          heap_open_from_share(internal_share, mode) :
198
209
      if (!file)
199
210
      {
200
211
         /* Couldn't open table; Remove the newly created table */
201
 
        THR_LOCK_heap.lock();
 
212
        pthread_mutex_lock(&THR_LOCK_heap);
202
213
        hp_free(internal_share);
203
 
        THR_LOCK_heap.unlock();
 
214
        pthread_mutex_unlock(&THR_LOCK_heap);
204
215
      }
205
216
    }
206
217
  }
217
228
      ha_heap::info(), which is always called before key statistics are
218
229
      used.
219
230
    */
220
 
    key_stat_version= file->getShare()->key_stat_version - 1;
 
231
    key_stat_version= file->s->key_stat_version - 1;
221
232
  }
222
233
  return (file ? 0 : 1);
223
234
}
238
249
    with '\'-delimited path.
239
250
*/
240
251
 
241
 
Cursor *ha_heap::clone(memory::Root *)
 
252
Cursor *ha_heap::clone(memory::Root *mem_root)
242
253
{
243
 
  Cursor *new_handler= getTable()->getMutableShare()->db_type()->getCursor(*getTable());
244
 
  TableIdentifier identifier(getTable()->getShare()->getSchemaName(),
245
 
                             getTable()->getShare()->getTableName(),
246
 
                             getTable()->getShare()->getPath());
 
254
  Cursor *new_handler= table->getMutableShare()->db_type()->getCursor(*(table->getMutableShare()), mem_root);
 
255
  TableIdentifier identifier(table->getShare()->getSchemaName(),
 
256
                             table->getShare()->getTableName(),
 
257
                             table->getShare()->getPath());
247
258
 
248
 
  if (new_handler && !new_handler->ha_open(identifier, getTable()->db_stat,
 
259
  if (new_handler && !new_handler->ha_open(identifier, table, file->s->name, table->db_stat,
249
260
                                           HA_OPEN_IGNORE_IF_LOCKED))
250
261
    return new_handler;
251
262
  return NULL;
252
263
}
253
264
 
254
265
 
255
 
const char *ha_heap::index_type(uint32_t )
 
266
const char *ha_heap::index_type(uint32_t inx)
256
267
{
257
 
  return ("HASH");
 
268
  return ((table_share->getKeyInfo(inx).algorithm == HA_KEY_ALG_BTREE) ?
 
269
          "BTREE" : "HASH");
258
270
}
259
271
 
260
272
 
276
288
 
277
289
void ha_heap::set_keys_for_scanning(void)
278
290
{
 
291
  btree_keys.reset();
 
292
  for (uint32_t i= 0 ; i < table->getShare()->sizeKeys() ; i++)
 
293
  {
 
294
    if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
 
295
      btree_keys.set(i);
 
296
  }
279
297
}
280
298
 
281
299
 
282
300
void ha_heap::update_key_stats()
283
301
{
284
 
  for (uint32_t i= 0; i < getTable()->getShare()->sizeKeys(); i++)
 
302
  for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++)
285
303
  {
286
 
    KeyInfo *key= &getTable()->key_info[i];
287
 
 
 
304
    KeyInfo *key= &table->key_info[i];
288
305
    if (!key->rec_per_key)
289
306
      continue;
290
 
 
 
307
    if (key->algorithm != HA_KEY_ALG_BTREE)
291
308
    {
292
309
      if (key->flags & HA_NOSAME)
293
310
        key->rec_per_key[key->key_parts-1]= 1;
294
311
      else
295
312
      {
296
 
        ha_rows hash_buckets= file->getShare()->keydef[i].hash_buckets;
297
 
        uint32_t no_records= hash_buckets ? (uint) (file->getShare()->records/hash_buckets) : 2;
 
313
        ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
 
314
        uint32_t no_records= hash_buckets ? (uint) (file->s->records/hash_buckets) : 2;
298
315
        if (no_records < 2)
299
316
          no_records= 2;
300
317
        key->rec_per_key[key->key_parts-1]= no_records;
303
320
  }
304
321
  records_changed= 0;
305
322
  /* At the end of update_key_stats() we can proudly claim they are OK. */
306
 
  key_stat_version= file->getShare()->key_stat_version;
 
323
  key_stat_version= file->s->key_stat_version;
307
324
}
308
325
 
309
326
 
310
327
int ha_heap::doInsertRecord(unsigned char * buf)
311
328
{
312
329
  int res;
313
 
  if (getTable()->next_number_field && buf == getTable()->getInsertRecord())
 
330
  if (table->next_number_field && buf == table->record[0])
314
331
  {
315
332
    if ((res= update_auto_increment()))
316
333
      return res;
317
334
  }
318
335
  res= heap_write(file,buf);
319
336
  if (!res && (++records_changed*MEMORY_STATS_UPDATE_THRESHOLD >
320
 
               file->getShare()->records))
 
337
               file->s->records))
321
338
  {
322
339
    /*
323
340
       We can perform this safely since only one writer at the time is
324
341
       allowed on the table.
325
342
    */
326
 
    file->getShare()->key_stat_version++;
 
343
    file->s->key_stat_version++;
327
344
  }
328
345
  return res;
329
346
}
334
351
 
335
352
  res= heap_update(file,old_data,new_data);
336
353
  if (!res && ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD >
337
 
              file->getShare()->records)
 
354
              file->s->records)
338
355
  {
339
356
    /*
340
357
       We can perform this safely since only one writer at the time is
341
358
       allowed on the table.
342
359
    */
343
 
    file->getShare()->key_stat_version++;
 
360
    file->s->key_stat_version++;
344
361
  }
345
362
  return res;
346
363
}
350
367
  int res;
351
368
 
352
369
  res= heap_delete(file,buf);
353
 
  if (!res && getTable()->getShare()->getType() == message::Table::STANDARD &&
354
 
      ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD > file->getShare()->records)
 
370
  if (!res && table->getShare()->getType() == message::Table::STANDARD &&
 
371
      ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD > file->s->records)
355
372
  {
356
373
    /*
357
374
       We can perform this safely since only one writer at the time is
358
375
       allowed on the table.
359
376
    */
360
 
    file->getShare()->key_stat_version++;
 
377
    file->s->key_stat_version++;
361
378
  }
362
379
  return res;
363
380
}
369
386
  assert(inited==INDEX);
370
387
  ha_statistic_increment(&system_status_var::ha_read_key_count);
371
388
  int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
372
 
  getTable()->status = error ? STATUS_NOT_FOUND : 0;
 
389
  table->status = error ? STATUS_NOT_FOUND : 0;
373
390
  return error;
374
391
}
375
392
 
380
397
  ha_statistic_increment(&system_status_var::ha_read_key_count);
381
398
  int error= heap_rkey(file, buf, active_index, key, keypart_map,
382
399
                       HA_READ_PREFIX_LAST);
383
 
  getTable()->status= error ? STATUS_NOT_FOUND : 0;
 
400
  table->status= error ? STATUS_NOT_FOUND : 0;
384
401
  return error;
385
402
}
386
403
 
390
407
{
391
408
  ha_statistic_increment(&system_status_var::ha_read_key_count);
392
409
  int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
393
 
  getTable()->status = error ? STATUS_NOT_FOUND : 0;
 
410
  table->status = error ? STATUS_NOT_FOUND : 0;
394
411
  return error;
395
412
}
396
413
 
399
416
  assert(inited==INDEX);
400
417
  ha_statistic_increment(&system_status_var::ha_read_next_count);
401
418
  int error=heap_rnext(file,buf);
402
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
419
  table->status=error ? STATUS_NOT_FOUND: 0;
403
420
  return error;
404
421
}
405
422
 
408
425
  assert(inited==INDEX);
409
426
  ha_statistic_increment(&system_status_var::ha_read_prev_count);
410
427
  int error=heap_rprev(file,buf);
411
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
428
  table->status=error ? STATUS_NOT_FOUND: 0;
412
429
  return error;
413
430
}
414
431
 
417
434
  assert(inited==INDEX);
418
435
  ha_statistic_increment(&system_status_var::ha_read_first_count);
419
436
  int error=heap_rfirst(file, buf, active_index);
420
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
437
  table->status=error ? STATUS_NOT_FOUND: 0;
421
438
  return error;
422
439
}
423
440
 
426
443
  assert(inited==INDEX);
427
444
  ha_statistic_increment(&system_status_var::ha_read_last_count);
428
445
  int error=heap_rlast(file, buf, active_index);
429
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
446
  table->status=error ? STATUS_NOT_FOUND: 0;
430
447
  return error;
431
448
}
432
449
 
439
456
{
440
457
  ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
441
458
  int error=heap_scan(file, buf);
442
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
459
  table->status=error ? STATUS_NOT_FOUND: 0;
443
460
  return error;
444
461
}
445
462
 
450
467
  ha_statistic_increment(&system_status_var::ha_read_rnd_count);
451
468
  memcpy(&heap_position, pos, sizeof(HEAP_PTR));
452
469
  error=heap_rrnd(file, buf, heap_position);
453
 
  getTable()->status=error ? STATUS_NOT_FOUND: 0;
 
470
  table->status=error ? STATUS_NOT_FOUND: 0;
454
471
  return error;
455
472
}
456
473
 
479
496
    have to update the key statistics. Hoping that a table lock is now
480
497
    in place.
481
498
  */
482
 
  if (key_stat_version != file->getShare()->key_stat_version)
 
499
  if (key_stat_version != file->s->key_stat_version)
483
500
    update_key_stats();
484
501
  return 0;
485
502
}
486
503
 
 
504
 
 
505
enum row_type ha_heap::get_row_type() const
 
506
{
 
507
  if (file->s->recordspace.is_variable_size)
 
508
    return ROW_TYPE_DYNAMIC;
 
509
 
 
510
  return ROW_TYPE_FIXED;
 
511
}
 
512
 
487
513
int ha_heap::extra(enum ha_extra_function operation)
488
514
{
489
515
  return heap_extra(file,operation);
499
525
int ha_heap::delete_all_rows()
500
526
{
501
527
  heap_clear(file);
502
 
  if (getTable()->getShare()->getType() == message::Table::STANDARD)
 
528
  if (table->getShare()->getType() == message::Table::STANDARD)
503
529
  {
504
530
    /*
505
531
       We can perform this safely since only one writer at the time is
506
532
       allowed on the table.
507
533
    */
508
 
    file->getShare()->key_stat_version++;
 
534
    file->s->key_stat_version++;
509
535
  }
510
536
  return 0;
511
537
}
619
645
 
620
646
void ha_heap::drop_table(const char *)
621
647
{
622
 
  file->getShare()->delete_on_close= 1;
 
648
  file->s->delete_on_close= 1;
623
649
  close();
624
650
}
625
651
 
626
652
 
627
653
int HeapEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
628
654
{
629
 
  session.getMessageCache().renameTableMessage(from, to);
 
655
  session.renameTableMessage(from, to);
630
656
  return heap_rename(from.getPath().c_str(), to.getPath().c_str());
631
657
}
632
658
 
634
660
ha_rows ha_heap::records_in_range(uint32_t inx, key_range *min_key,
635
661
                                  key_range *max_key)
636
662
{
637
 
  KeyInfo *key= &getTable()->key_info[inx];
 
663
  KeyInfo *key= &table->key_info[inx];
 
664
  if (key->algorithm == HA_KEY_ALG_BTREE)
 
665
    return hp_rb_records_in_range(file, inx, min_key, max_key);
638
666
 
639
667
  if (!min_key || !max_key ||
640
668
      min_key->length != max_key->length ||
647
675
    return stats.records;
648
676
 
649
677
  /* Assert that info() did run. We need current statistics here. */
650
 
  assert(key_stat_version == file->getShare()->key_stat_version);
 
678
  assert(key_stat_version == file->s->key_stat_version);
651
679
  return key->rec_per_key[key->key_parts-1];
652
680
}
653
681
 
667
695
 
668
696
  if (error == 0)
669
697
  {
670
 
    session.getMessageCache().storeTableMessage(identifier, create_proto);
 
698
    session.storeTableMessage(identifier, create_proto);
671
699
  }
672
700
 
673
701
  return error;
680
708
                                  message::Table &create_proto,
681
709
                                  HP_SHARE **internal_share)
682
710
{
683
 
  uint32_t key, parts, mem_per_row_keys= 0;
684
 
  uint32_t keys= table_arg->getShare()->sizeKeys();
 
711
  uint32_t key, parts, mem_per_row_keys= 0, keys= table_arg->getShare()->sizeKeys();
685
712
  uint32_t auto_key= 0, auto_key_type= 0;
686
713
  uint32_t max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
687
 
  uint32_t column_count= table_arg->getShare()->sizeFields();
688
 
  std::vector<HP_KEYDEF> keydef;
 
714
  uint32_t column_idx, column_count= table_arg->getShare()->sizeFields();
 
715
  HP_COLUMNDEF *columndef;
 
716
  HP_KEYDEF *keydef;
 
717
  HA_KEYSEG *seg;
 
718
  char buff[FN_REFLEN];
689
719
  int error;
690
720
  bool found_real_auto_increment= 0;
691
721
 
699
729
  if (num_rows > UINT32_MAX)
700
730
    return -1;
701
731
 
 
732
  if (!(columndef= (HP_COLUMNDEF*) malloc(column_count * sizeof(HP_COLUMNDEF))))
 
733
    return errno;
 
734
 
 
735
  for (column_idx= 0; column_idx < column_count; column_idx++)
 
736
  {
 
737
    Field* field= *(table_arg->getFields() + column_idx);
 
738
    HP_COLUMNDEF* column= columndef + column_idx;
 
739
    column->type= (uint16_t)field->type();
 
740
    column->length= field->pack_length();
 
741
    column->offset= field->offset(field->table->record[0]);
 
742
 
 
743
    if (field->null_bit)
 
744
    {
 
745
      column->null_bit= field->null_bit;
 
746
      column->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
 
747
    }
 
748
    else
 
749
    {
 
750
      column->null_bit= 0;
 
751
      column->null_pos= 0;
 
752
    }
 
753
 
 
754
    if (field->type() == DRIZZLE_TYPE_VARCHAR)
 
755
    {
 
756
      column->length_bytes= (uint8_t)(((Field_varstring*)field)->length_bytes);
 
757
    }
 
758
    else
 
759
    {
 
760
      column->length_bytes= 0;
 
761
    }
 
762
  }
 
763
 
702
764
  for (key= parts= 0; key < keys; key++)
703
765
    parts+= table_arg->key_info[key].key_parts;
704
766
 
705
 
  keydef.resize(keys);
706
 
  std::vector<HA_KEYSEG> seg_buffer;
707
 
  seg_buffer.resize(parts);
708
 
  HA_KEYSEG *seg= &seg_buffer[0];
 
767
  if (!(keydef= (HP_KEYDEF*) malloc(keys * sizeof(HP_KEYDEF) +
 
768
                                    parts * sizeof(HA_KEYSEG))))
 
769
  {
 
770
    free((void *) columndef);
 
771
    return errno;
 
772
  }
709
773
 
 
774
  seg= reinterpret_cast<HA_KEYSEG*> (keydef + keys);
710
775
  for (key= 0; key < keys; key++)
711
776
  {
712
777
    KeyInfo *pos= &table_arg->key_info[key];
717
782
    keydef[key].flag=      (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
718
783
    keydef[key].seg=       seg;
719
784
 
720
 
    mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
 
785
    switch (pos->algorithm) {
 
786
    case HA_KEY_ALG_UNDEF:
 
787
    case HA_KEY_ALG_HASH:
 
788
      keydef[key].algorithm= HA_KEY_ALG_HASH;
 
789
      mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
 
790
      break;
 
791
    case HA_KEY_ALG_BTREE:
 
792
      keydef[key].algorithm= HA_KEY_ALG_BTREE;
 
793
      mem_per_row_keys+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
 
794
      break;
 
795
    default:
 
796
      assert(0); // cannot happen
 
797
    }
721
798
 
722
799
    for (; key_part != key_part_end; key_part++, seg++)
723
800
    {
724
801
      Field *field= key_part->field;
725
802
 
 
803
      if (pos->algorithm == HA_KEY_ALG_BTREE)
 
804
        seg->type= field->key_type();
 
805
      else
726
806
      {
727
807
        if ((seg->type = field->key_type()) != (int) HA_KEYTYPE_TEXT &&
728
808
            seg->type != HA_KEYTYPE_VARTEXT1 &&
738
818
      next_field_pos= seg->start + seg->length;
739
819
      if (field->type() == DRIZZLE_TYPE_VARCHAR)
740
820
      {
741
 
        next_field_pos+= (uint8_t)(((Field_varstring*)field)->pack_length_no_ptr());
 
821
        next_field_pos+= (uint8_t)(((Field_varstring*)field)->length_bytes);
742
822
      }
743
823
 
744
824
      if (next_field_pos > key_part_size) {
752
832
      if (field->null_ptr)
753
833
      {
754
834
        seg->null_bit= field->null_bit;
755
 
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->getInsertRecord());
 
835
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
756
836
      }
757
837
      else
758
838
      {
770
850
        auto_key= key+ 1;
771
851
        auto_key_type= field->key_type();
772
852
      }
773
 
      if ((uint)field->position() + 1 > max_key_fieldnr)
 
853
      if ((uint)field->field_index + 1 > max_key_fieldnr)
774
854
      {
775
855
        /* Do not use seg->fieldnr as it's not reliable in case of temp tables */
776
 
        max_key_fieldnr= field->position() + 1;
 
856
        max_key_fieldnr= field->field_index + 1;
777
857
      }
778
858
    }
779
859
  }
800
880
  hp_create_info.with_auto_increment= found_real_auto_increment;
801
881
  hp_create_info.internal_table= internal_table;
802
882
  hp_create_info.max_chunk_size= table_arg->getShare()->block_size;
803
 
 
804
 
  error= heap_create(table_name,
805
 
                     keys, &keydef[0],
806
 
                     column_count,
807
 
                     key_part_size,
808
 
                     table_arg->getShare()->getRecordLength(), mem_per_row_keys,
809
 
                     static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
810
 
                     0, // Factor out MIN
811
 
                     &hp_create_info, internal_share);
 
883
  hp_create_info.is_dynamic= (table_arg->getShare()->row_type == ROW_TYPE_DYNAMIC);
 
884
 
 
885
  error= heap_create(internal::fn_format(buff,table_name,"","",
 
886
                              MY_REPLACE_EXT|MY_UNPACK_FILENAME),
 
887
                    keys, keydef,
 
888
                    column_count, columndef,
 
889
                    max_key_fieldnr, key_part_size,
 
890
                    table_arg->getShare()->getRecordLength(), mem_per_row_keys,
 
891
                    static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
 
892
                    0, // Factor out MIN
 
893
                    &hp_create_info, internal_share);
 
894
 
 
895
  free((unsigned char*) keydef);
 
896
  free((void *) columndef);
812
897
 
813
898
  return (error);
814
899
}