~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/heap/ha_heap.cc

  • Committer: Brian Aker
  • Date: 2010-08-18 16:12:58 UTC
  • mto: This revision was merged to the branch mainline in revision 1720.
  • Revision ID: brian@tangent.org-20100818161258-1vm71da888dfvwsx
Remove the code surrounding stack trace.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#include <drizzled/error.h>
18
18
#include <drizzled/table.h>
19
19
#include <drizzled/session.h>
20
 
#include <drizzled/current_session.h>
21
20
#include <drizzled/field/timestamp.h>
22
21
#include <drizzled/field/varstring.h>
23
22
#include "drizzled/plugin/daemon.h"
24
23
 
 
24
#include <boost/thread/mutex.hpp>
 
25
 
25
26
#include "heap.h"
26
27
#include "ha_heap.h"
27
28
 
33
34
 
34
35
static const string engine_name("MEMORY");
35
36
 
36
 
pthread_mutex_t THR_LOCK_heap= PTHREAD_MUTEX_INITIALIZER;
 
37
boost::mutex THR_LOCK_heap;
37
38
 
38
39
static const char *ha_heap_exts[] = {
39
40
  NULL
52
53
                          HTON_SKIP_STORE_LOCK |
53
54
                          HTON_TEMPORARY_ONLY)
54
55
  {
55
 
    pthread_mutex_init(&THR_LOCK_heap, MY_MUTEX_INIT_FAST);
56
56
  }
57
57
 
58
58
  virtual ~HeapEngine()
59
59
  {
60
60
    hp_panic(HA_PANIC_CLOSE);
61
 
 
62
 
    pthread_mutex_destroy(&THR_LOCK_heap);
63
61
  }
64
62
 
65
 
  virtual Cursor *create(TableShare &table,
66
 
                          memory::Root *mem_root)
 
63
  virtual Cursor *create(TableShare &table)
67
64
  {
68
 
    return new (mem_root) ha_heap(*this, table);
 
65
    return new ha_heap(*this, table);
69
66
  }
70
67
 
71
68
  const char **bas_ext() const {
74
71
 
75
72
  int doCreateTable(Session &session,
76
73
                    Table &table_arg,
77
 
                    drizzled::TableIdentifier &identifier,
 
74
                    const TableIdentifier &identifier,
78
75
                    message::Table &create_proto);
79
76
 
80
77
  /* For whatever reason, internal tables can be created by Cursor::open()
88
85
                        message::Table &create_proto,
89
86
                        HP_SHARE **internal_share);
90
87
 
91
 
  int doRenameTable(Session&, TableIdentifier &from, TableIdentifier &to);
 
88
  int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
92
89
 
93
 
  int doDropTable(Session&, TableIdentifier &identifier);
 
90
  int doDropTable(Session&, const TableIdentifier &identifier);
94
91
 
95
92
  int doGetTableDefinition(Session& session,
96
 
                           TableIdentifier &identifier,
 
93
                           const TableIdentifier &identifier,
97
94
                           message::Table &table_message);
98
95
 
99
96
  /* Temp only engine, so do not return values. */
100
 
  void doGetTableNames(CachedDirectory &, SchemaIdentifier& , set<string>&) { };
 
97
  void doGetTableNames(CachedDirectory &, const SchemaIdentifier& , set<string>&) { };
101
98
 
102
99
  uint32_t max_supported_keys()          const { return MAX_KEY; }
103
100
  uint32_t max_supported_key_part_length() const { return MAX_KEY_LENGTH; }
113
110
            HA_KEY_SCAN_NOT_ROR);
114
111
  }
115
112
 
116
 
  bool doDoesTableExist(Session& session, TableIdentifier &identifier);
117
 
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
118
 
                             drizzled::SchemaIdentifier &schema_identifier,
119
 
                             drizzled::TableIdentifiers &set_of_identifiers);
 
113
  bool doDoesTableExist(Session& session, const TableIdentifier &identifier);
 
114
  void doGetTableIdentifiers(CachedDirectory &directory,
 
115
                             const SchemaIdentifier &schema_identifier,
 
116
                             TableIdentifiers &set_of_identifiers);
120
117
};
121
118
 
122
 
void HeapEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
123
 
                                       drizzled::SchemaIdentifier&,
124
 
                                       drizzled::TableIdentifiers&)
 
119
void HeapEngine::doGetTableIdentifiers(CachedDirectory&,
 
120
                                       const SchemaIdentifier&,
 
121
                                       TableIdentifiers&)
125
122
{
126
123
}
127
124
 
128
 
bool HeapEngine::doDoesTableExist(Session& session, TableIdentifier &identifier)
 
125
bool HeapEngine::doDoesTableExist(Session& session, const TableIdentifier &identifier)
129
126
{
130
127
  return session.doesTableMessageExist(identifier);
131
128
}
132
129
 
133
130
int HeapEngine::doGetTableDefinition(Session &session,
134
 
                                     TableIdentifier &identifier,
 
131
                                     const TableIdentifier &identifier,
135
132
                                     message::Table &table_proto)
136
133
{
137
134
  if (session.getTableMessage(identifier, table_proto))
143
140
  We have to ignore ENOENT entries as the MEMORY table is created on open and
144
141
  not when doing a CREATE on the table.
145
142
*/
146
 
int HeapEngine::doDropTable(Session &session, TableIdentifier &identifier)
 
143
int HeapEngine::doDropTable(Session &session, const TableIdentifier &identifier)
147
144
{
148
145
  session.removeTableMessage(identifier);
149
146
 
157
154
 
158
155
static HeapEngine *heap_storage_engine= NULL;
159
156
 
160
 
static int heap_init(plugin::Context &context)
 
157
static int heap_init(module::Context &context)
161
158
{
162
159
  heap_storage_engine= new HeapEngine(engine_name);
163
160
  context.add(heap_storage_engine);
192
189
{
193
190
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && errno == ENOENT))
194
191
  {
195
 
    HA_CREATE_INFO create_info;
196
192
    internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
197
 
    memset(&create_info, 0, sizeof(create_info));
198
193
    file= 0;
199
194
    HP_SHARE *internal_share= NULL;
200
195
    message::Table create_proto;
201
196
 
202
 
    if (!heap_storage_engine->heap_create_table(ha_session(), name, table,
 
197
    if (!heap_storage_engine->heap_create_table(table->in_use, name, table,
203
198
                                                internal_table,
204
199
                                                create_proto,
205
200
                                                &internal_share))
210
205
      if (!file)
211
206
      {
212
207
         /* Couldn't open table; Remove the newly created table */
213
 
        pthread_mutex_lock(&THR_LOCK_heap);
 
208
        THR_LOCK_heap.lock();
214
209
        hp_free(internal_share);
215
 
        pthread_mutex_unlock(&THR_LOCK_heap);
 
210
        THR_LOCK_heap.unlock();
216
211
      }
217
 
      implicit_emptied= 1;
218
212
    }
219
213
  }
220
214
  ref_length= sizeof(HEAP_PTR);
230
224
      ha_heap::info(), which is always called before key statistics are
231
225
      used.
232
226
    */
233
 
    key_stat_version= file->s->key_stat_version-1;
 
227
    key_stat_version= file->getShare()->key_stat_version - 1;
234
228
  }
235
229
  return (file ? 0 : 1);
236
230
}
246
240
 
247
241
  DESCRIPTION
248
242
    Do same as default implementation but use file->s->name instead of
249
 
    table->s->path. This is needed by Windows where the clone() call sees
250
 
    '/'-delimited path in table->s->path, while ha_peap::open() was called
 
243
    table->getShare()->path. This is needed by Windows where the clone() call sees
 
244
    '/'-delimited path in table->getShare()->path, while ha_peap::open() was called
251
245
    with '\'-delimited path.
252
246
*/
253
247
 
254
 
Cursor *ha_heap::clone(memory::Root *mem_root)
 
248
Cursor *ha_heap::clone(memory::Root *)
255
249
{
256
 
  Cursor *new_handler= table->s->db_type()->getCursor(*table->s, mem_root);
 
250
  Cursor *new_handler= table->getMutableShare()->db_type()->getCursor(*(table->getMutableShare()));
 
251
  TableIdentifier identifier(table->getShare()->getSchemaName(),
 
252
                             table->getShare()->getTableName(),
 
253
                             table->getShare()->getPath());
257
254
 
258
 
  if (new_handler && !new_handler->ha_open(table, file->s->name, table->db_stat,
 
255
  if (new_handler && !new_handler->ha_open(identifier, table, file->getShare()->name.c_str(), table->db_stat,
259
256
                                           HA_OPEN_IGNORE_IF_LOCKED))
260
257
    return new_handler;
261
258
  return NULL;
264
261
 
265
262
const char *ha_heap::index_type(uint32_t inx)
266
263
{
267
 
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
 
264
  return ((table_share->getKeyInfo(inx).algorithm == HA_KEY_ALG_BTREE) ?
268
265
          "BTREE" : "HASH");
269
266
}
270
267
 
288
285
void ha_heap::set_keys_for_scanning(void)
289
286
{
290
287
  btree_keys.reset();
291
 
  for (uint32_t i= 0 ; i < table->s->keys ; i++)
 
288
  for (uint32_t i= 0 ; i < table->getShare()->sizeKeys() ; i++)
292
289
  {
293
290
    if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
294
291
      btree_keys.set(i);
298
295
 
299
296
void ha_heap::update_key_stats()
300
297
{
301
 
  for (uint32_t i= 0; i < table->s->keys; i++)
 
298
  for (uint32_t i= 0; i < table->getShare()->sizeKeys(); i++)
302
299
  {
303
 
    KEY *key=table->key_info+i;
 
300
    KeyInfo *key= &table->key_info[i];
304
301
    if (!key->rec_per_key)
305
302
      continue;
306
303
    if (key->algorithm != HA_KEY_ALG_BTREE)
309
306
        key->rec_per_key[key->key_parts-1]= 1;
310
307
      else
311
308
      {
312
 
        ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
313
 
        uint32_t no_records= hash_buckets ? (uint) (file->s->records/hash_buckets) : 2;
 
309
        ha_rows hash_buckets= file->getShare()->keydef[i].hash_buckets;
 
310
        uint32_t no_records= hash_buckets ? (uint) (file->getShare()->records/hash_buckets) : 2;
314
311
        if (no_records < 2)
315
312
          no_records= 2;
316
313
        key->rec_per_key[key->key_parts-1]= no_records;
319
316
  }
320
317
  records_changed= 0;
321
318
  /* At the end of update_key_stats() we can proudly claim they are OK. */
322
 
  key_stat_version= file->s->key_stat_version;
 
319
  key_stat_version= file->getShare()->key_stat_version;
323
320
}
324
321
 
325
322
 
326
 
int ha_heap::write_row(unsigned char * buf)
 
323
int ha_heap::doInsertRecord(unsigned char * buf)
327
324
{
328
325
  int res;
329
 
  ha_statistic_increment(&system_status_var::ha_write_count);
330
 
  if (table->next_number_field && buf == table->record[0])
 
326
  if (table->next_number_field && buf == table->getInsertRecord())
331
327
  {
332
328
    if ((res= update_auto_increment()))
333
329
      return res;
334
330
  }
335
331
  res= heap_write(file,buf);
336
332
  if (!res && (++records_changed*MEMORY_STATS_UPDATE_THRESHOLD >
337
 
               file->s->records))
 
333
               file->getShare()->records))
338
334
  {
339
335
    /*
340
336
       We can perform this safely since only one writer at the time is
341
337
       allowed on the table.
342
338
    */
343
 
    file->s->key_stat_version++;
 
339
    file->getShare()->key_stat_version++;
344
340
  }
345
341
  return res;
346
342
}
347
343
 
348
 
int ha_heap::update_row(const unsigned char * old_data, unsigned char * new_data)
 
344
int ha_heap::doUpdateRecord(const unsigned char * old_data, unsigned char * new_data)
349
345
{
350
346
  int res;
351
 
  ha_statistic_increment(&system_status_var::ha_update_count);
352
 
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
353
 
    table->timestamp_field->set_time();
 
347
 
354
348
  res= heap_update(file,old_data,new_data);
355
349
  if (!res && ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD >
356
 
              file->s->records)
 
350
              file->getShare()->records)
357
351
  {
358
352
    /*
359
353
       We can perform this safely since only one writer at the time is
360
354
       allowed on the table.
361
355
    */
362
 
    file->s->key_stat_version++;
 
356
    file->getShare()->key_stat_version++;
363
357
  }
364
358
  return res;
365
359
}
366
360
 
367
 
int ha_heap::delete_row(const unsigned char * buf)
 
361
int ha_heap::doDeleteRecord(const unsigned char * buf)
368
362
{
369
363
  int res;
370
 
  ha_statistic_increment(&system_status_var::ha_delete_count);
 
364
 
371
365
  res= heap_delete(file,buf);
372
 
  if (!res && table->s->tmp_table == message::Table::STANDARD &&
373
 
      ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD > file->s->records)
 
366
  if (!res && table->getShare()->getType() == message::Table::STANDARD &&
 
367
      ++records_changed*MEMORY_STATS_UPDATE_THRESHOLD > file->getShare()->records)
374
368
  {
375
369
    /*
376
370
       We can perform this safely since only one writer at the time is
377
371
       allowed on the table.
378
372
    */
379
 
    file->s->key_stat_version++;
 
373
    file->getShare()->key_stat_version++;
380
374
  }
381
375
  return res;
382
376
}
449
443
  return error;
450
444
}
451
445
 
452
 
int ha_heap::rnd_init(bool scan)
 
446
int ha_heap::doStartTableScan(bool scan)
453
447
{
454
448
  return scan ? heap_scan_init(file) : 0;
455
449
}
498
492
    have to update the key statistics. Hoping that a table lock is now
499
493
    in place.
500
494
  */
501
 
  if (key_stat_version != file->s->key_stat_version)
 
495
  if (key_stat_version != file->getShare()->key_stat_version)
502
496
    update_key_stats();
503
497
  return 0;
504
498
}
505
499
 
506
 
 
507
 
enum row_type ha_heap::get_row_type() const
508
 
{
509
 
  if (file->s->recordspace.is_variable_size)
510
 
    return ROW_TYPE_DYNAMIC;
511
 
 
512
 
  return ROW_TYPE_FIXED;
513
 
}
514
 
 
515
500
int ha_heap::extra(enum ha_extra_function operation)
516
501
{
517
502
  return heap_extra(file,operation);
527
512
int ha_heap::delete_all_rows()
528
513
{
529
514
  heap_clear(file);
530
 
  if (table->s->tmp_table == message::Table::STANDARD)
 
515
  if (table->getShare()->getType() == message::Table::STANDARD)
531
516
  {
532
517
    /*
533
518
       We can perform this safely since only one writer at the time is
534
519
       allowed on the table.
535
520
    */
536
 
    file->s->key_stat_version++;
 
521
    file->getShare()->key_stat_version++;
537
522
  }
538
523
  return 0;
539
524
}
647
632
 
648
633
void ha_heap::drop_table(const char *)
649
634
{
650
 
  file->s->delete_on_close= 1;
 
635
  file->getShare()->delete_on_close= 1;
651
636
  close();
652
637
}
653
638
 
654
639
 
655
 
int HeapEngine::doRenameTable(Session &session, TableIdentifier &from, TableIdentifier &to)
 
640
int HeapEngine::doRenameTable(Session &session, const TableIdentifier &from, const TableIdentifier &to)
656
641
{
657
642
  session.renameTableMessage(from, to);
658
643
  return heap_rename(from.getPath().c_str(), to.getPath().c_str());
662
647
ha_rows ha_heap::records_in_range(uint32_t inx, key_range *min_key,
663
648
                                  key_range *max_key)
664
649
{
665
 
  KEY *key=table->key_info+inx;
 
650
  KeyInfo *key= &table->key_info[inx];
666
651
  if (key->algorithm == HA_KEY_ALG_BTREE)
667
652
    return hp_rb_records_in_range(file, inx, min_key, max_key);
668
653
 
677
662
    return stats.records;
678
663
 
679
664
  /* Assert that info() did run. We need current statistics here. */
680
 
  assert(key_stat_version == file->s->key_stat_version);
 
665
  assert(key_stat_version == file->getShare()->key_stat_version);
681
666
  return key->rec_per_key[key->key_parts-1];
682
667
}
683
668
 
684
669
int HeapEngine::doCreateTable(Session &session,
685
670
                              Table &table_arg,
686
 
                              drizzled::TableIdentifier &identifier,
 
671
                              const TableIdentifier &identifier,
687
672
                              message::Table& create_proto)
688
673
{
689
674
  int error;
710
695
                                  message::Table &create_proto,
711
696
                                  HP_SHARE **internal_share)
712
697
{
713
 
  uint32_t key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
 
698
  uint32_t key, parts, mem_per_row_keys= 0;
 
699
  uint32_t keys= table_arg->getShare()->sizeKeys();
714
700
  uint32_t auto_key= 0, auto_key_type= 0;
715
701
  uint32_t max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
716
 
  uint32_t column_idx, column_count= table_arg->s->fields;
717
 
  HP_COLUMNDEF *columndef;
718
 
  HP_KEYDEF *keydef;
719
 
  HA_KEYSEG *seg;
 
702
  uint32_t column_count= table_arg->getShare()->sizeFields();
 
703
  std::vector<HP_COLUMNDEF> columndef;
 
704
  std::vector<HP_KEYDEF> keydef;
720
705
  char buff[FN_REFLEN];
721
706
  int error;
722
 
  TableShare *share= table_arg->s;
723
707
  bool found_real_auto_increment= 0;
724
708
 
725
709
  /* 
728
712
   * can return a number more than that, we trap it here instead of casting
729
713
   * to a truncated integer.
730
714
   */
731
 
  uint64_t num_rows= share->getMaxRows();
 
715
  uint64_t num_rows= table_arg->getShare()->getMaxRows();
732
716
  if (num_rows > UINT32_MAX)
733
717
    return -1;
734
718
 
735
 
  if (!(columndef= (HP_COLUMNDEF*) malloc(column_count * sizeof(HP_COLUMNDEF))))
736
 
    return errno;
 
719
  columndef.resize(column_count);
737
720
 
738
 
  for (column_idx= 0; column_idx < column_count; column_idx++)
 
721
  for (uint32_t column_idx= 0; column_idx < column_count; column_idx++)
739
722
  {
740
 
    Field* field= *(table_arg->field + column_idx);
741
 
    HP_COLUMNDEF* column= columndef + column_idx;
 
723
    Field* field= *(table_arg->getFields() + column_idx);
 
724
    HP_COLUMNDEF* column= &columndef[column_idx];
742
725
    column->type= (uint16_t)field->type();
743
726
    column->length= field->pack_length();
744
 
    column->offset= field->offset(field->table->record[0]);
 
727
    column->offset= field->offset(field->getTable()->getInsertRecord());
745
728
 
746
729
    if (field->null_bit)
747
730
    {
748
731
      column->null_bit= field->null_bit;
749
 
      column->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
 
732
      column->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->getInsertRecord());
750
733
    }
751
734
    else
752
735
    {
767
750
  for (key= parts= 0; key < keys; key++)
768
751
    parts+= table_arg->key_info[key].key_parts;
769
752
 
770
 
  if (!(keydef= (HP_KEYDEF*) malloc(keys * sizeof(HP_KEYDEF) +
771
 
                                    parts * sizeof(HA_KEYSEG))))
772
 
  {
773
 
    free((void *) columndef);
774
 
    return errno;
775
 
  }
 
753
  keydef.resize(keys);
 
754
  std::vector<HA_KEYSEG> seg_buffer;
 
755
  seg_buffer.resize(parts);
 
756
  HA_KEYSEG *seg= &seg_buffer[0];
776
757
 
777
 
  seg= reinterpret_cast<HA_KEYSEG*> (keydef + keys);
778
758
  for (key= 0; key < keys; key++)
779
759
  {
780
 
    KEY *pos= table_arg->key_info+key;
781
 
    KEY_PART_INFO *key_part=     pos->key_part;
782
 
    KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
 
760
    KeyInfo *pos= &table_arg->key_info[key];
 
761
    KeyPartInfo *key_part=     pos->key_part;
 
762
    KeyPartInfo *key_part_end= key_part + pos->key_parts;
783
763
 
784
764
    keydef[key].keysegs=   (uint) pos->key_parts;
785
765
    keydef[key].flag=      (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
804
784
      Field *field= key_part->field;
805
785
 
806
786
      if (pos->algorithm == HA_KEY_ALG_BTREE)
 
787
      {
807
788
        seg->type= field->key_type();
 
789
      }
808
790
      else
809
791
      {
810
792
        if ((seg->type = field->key_type()) != (int) HA_KEYTYPE_TEXT &&
835
817
      if (field->null_ptr)
836
818
      {
837
819
        seg->null_bit= field->null_bit;
838
 
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
 
820
        seg->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->getInsertRecord());
839
821
      }
840
822
      else
841
823
      {
844
826
      }
845
827
      if (field->flags & AUTO_INCREMENT_FLAG &&
846
828
          table_arg->found_next_number_field &&
847
 
          key == share->next_number_index)
 
829
          key == table_arg->getShare()->next_number_index)
848
830
      {
849
831
        /*
850
832
          Store key number and type for found auto_increment key
861
843
    }
862
844
  }
863
845
 
864
 
  if (key_part_size < share->null_bytes + ((share->last_null_bit_pos+7) >> 3))
 
846
  if (key_part_size < table_arg->getShare()->null_bytes + ((table_arg->getShare()->last_null_bit_pos+7) >> 3))
865
847
  {
866
848
    /* Make sure to include null fields regardless of the presense of keys */
867
 
    key_part_size = share->null_bytes + ((share->last_null_bit_pos+7) >> 3);
 
849
    key_part_size = table_arg->getShare()->null_bytes + ((table_arg->getShare()->last_null_bit_pos+7) >> 3);
868
850
  }
869
851
 
870
852
 
871
853
 
872
854
  if (table_arg->found_next_number_field)
873
855
  {
874
 
    keydef[share->next_number_index].flag|= HA_AUTO_KEY;
875
 
    found_real_auto_increment= share->next_number_key_offset == 0;
 
856
    keydef[table_arg->getShare()->next_number_index].flag|= HA_AUTO_KEY;
 
857
    found_real_auto_increment= table_arg->getShare()->next_number_key_offset == 0;
876
858
  }
877
859
  HP_CREATE_INFO hp_create_info;
878
860
  hp_create_info.auto_key= auto_key;
882
864
  hp_create_info.max_table_size=session->variables.max_heap_table_size;
883
865
  hp_create_info.with_auto_increment= found_real_auto_increment;
884
866
  hp_create_info.internal_table= internal_table;
885
 
  hp_create_info.max_chunk_size= share->block_size;
886
 
  hp_create_info.is_dynamic= (share->row_type == ROW_TYPE_DYNAMIC);
 
867
  hp_create_info.max_chunk_size= table_arg->getShare()->block_size;
 
868
  hp_create_info.is_dynamic= false;
887
869
 
888
870
  error= heap_create(internal::fn_format(buff,table_name,"","",
889
871
                              MY_REPLACE_EXT|MY_UNPACK_FILENAME),
890
 
                    keys, keydef,
891
 
                    column_count, columndef,
 
872
                    keys, &keydef[0],
 
873
                    column_count, &columndef[0],
892
874
                    max_key_fieldnr, key_part_size,
893
 
                    share->reclength, mem_per_row_keys,
 
875
                    table_arg->getShare()->getRecordLength(), mem_per_row_keys,
894
876
                    static_cast<uint32_t>(num_rows), /* We check for overflow above, so cast is fine here. */
895
877
                    0, // Factor out MIN
896
878
                    &hp_create_info, internal_share);
897
879
 
898
 
  free((unsigned char*) keydef);
899
 
  free((void *) columndef);
900
 
 
901
880
  return (error);
902
881
}
903
882