~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
16
#define DRIZZLE_SERVER 1
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
17
#include <drizzled/server_includes.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
18
#include <storage/heap/ha_heap.h>
19
#include <storage/heap/heapdef.h>
549 by Monty Taylor
Took gettext.h out of header files.
20
#include <drizzled/error.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
21
#include <drizzled/table.h>
22
#include <drizzled/session.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
23
#include <drizzled/field/timestamp.h>
24
#include <drizzled/field/varstring.h>
1 by brian
clean slate
25
596 by Brian Aker
Refactor out dead mutexes
26
pthread_mutex_t THR_LOCK_heap= PTHREAD_MUTEX_INITIALIZER;
27
1 by brian
clean slate
28
static handler *heap_create_handler(handlerton *hton,
584.5.1 by Monty Taylor
Removed field includes from field.h.
29
                                    TABLE_SHARE *table,
1 by brian
clean slate
30
                                    MEM_ROOT *mem_root);
31
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
32
int heap_deinit(void *)
1 by brian
clean slate
33
{
596 by Brian Aker
Refactor out dead mutexes
34
  pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST);
35
224.2.3 by Brian Aker
Fix for memory leak in shutdown/restart of an engine (not fixed in 5.1)
36
  return hp_panic(HA_PANIC_CLOSE);
1 by brian
clean slate
37
}
38
39
40
int heap_init(void *p)
41
{
42
  handlerton *heap_hton;
43
44
  heap_hton= (handlerton *)p;
45
  heap_hton->state=      SHOW_OPTION_YES;
46
  heap_hton->create=     heap_create_handler;
47
  heap_hton->flags=      HTON_CAN_RECREATE;
48
49
  return 0;
50
}
51
52
static handler *heap_create_handler(handlerton *hton,
53
                                    TABLE_SHARE *table, 
54
                                    MEM_ROOT *mem_root)
55
{
56
  return new (mem_root) ha_heap(hton, table);
57
}
58
59
60
/*****************************************************************************
61
** HEAP tables
62
*****************************************************************************/
63
64
ha_heap::ha_heap(handlerton *hton, TABLE_SHARE *table_arg)
65
  :handler(hton, table_arg), file(0), records_changed(0), key_stat_version(0), 
66
  internal_table(0)
67
{}
68
69
70
static const char *ha_heap_exts[] = {
461 by Monty Taylor
Removed NullS. bu-bye.
71
  NULL
1 by brian
clean slate
72
};
73
74
const char **ha_heap::bas_ext() const
75
{
76
  return ha_heap_exts;
77
}
78
79
/*
80
  Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to 
81
  rec_per_key) after 1/HEAP_STATS_UPDATE_THRESHOLD fraction of table records 
82
  have been inserted/updated/deleted. delete_all_rows() and table flush cause 
83
  immediate update.
84
85
  NOTE
86
   hash index statistics must be updated when number of table records changes
87
   from 0 to non-zero value and vice versa. Otherwise records_in_range may 
88
   erroneously return 0 and 'range' may miss records.
89
*/
90
#define HEAP_STATS_UPDATE_THRESHOLD 10
91
482 by Brian Aker
Remove uint.
92
int ha_heap::open(const char *name, int mode, uint32_t test_if_locked)
1 by brian
clean slate
93
{
94
  if ((test_if_locked & HA_OPEN_INTERNAL_TABLE) || (!(file= heap_open(name, mode)) && my_errno == ENOENT))
95
  {
96
    HA_CREATE_INFO create_info;
97
    internal_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
98
    memset(&create_info, 0, sizeof(create_info));
1 by brian
clean slate
99
    file= 0;
100
    if (!create(name, table, &create_info))
101
    {
102
        file= internal_table ?
103
          heap_open_from_share(internal_share, mode) :
104
          heap_open_from_share_and_register(internal_share, mode);
105
      if (!file)
106
      {
107
         /* Couldn't open table; Remove the newly created table */
108
        pthread_mutex_lock(&THR_LOCK_heap);
109
        hp_free(internal_share);
110
        pthread_mutex_unlock(&THR_LOCK_heap);
111
      }
112
      implicit_emptied= 1;
113
    }
114
  }
115
  ref_length= sizeof(HEAP_PTR);
116
  if (file)
117
  {
118
    /* Initialize variables for the opened table */
119
    set_keys_for_scanning();
120
    /*
121
      We cannot run update_key_stats() here because we do not have a
122
      lock on the table. The 'records' count might just be changed
123
      temporarily at this moment and we might get wrong statistics (Bug
124
      #10178). Instead we request for update. This will be done in
125
      ha_heap::info(), which is always called before key statistics are
126
      used.
127
    */
128
    key_stat_version= file->s->key_stat_version-1;
129
  }
130
  return (file ? 0 : 1);
131
}
132
133
int ha_heap::close(void)
134
{
135
  return internal_table ? hp_close(file) : heap_close(file);
136
}
137
138
139
/*
140
  Create a copy of this table
141
142
  DESCRIPTION
143
    Do same as default implementation but use file->s->name instead of 
144
    table->s->path. This is needed by Windows where the clone() call sees
145
    '/'-delimited path in table->s->path, while ha_peap::open() was called 
146
    with '\'-delimited path.
147
*/
148
149
handler *ha_heap::clone(MEM_ROOT *mem_root)
150
{
151
  handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
152
  if (new_handler && !new_handler->ha_open(table, file->s->name, table->db_stat,
153
                                           HA_OPEN_IGNORE_IF_LOCKED))
154
    return new_handler;
155
  return NULL;  /* purecov: inspected */
156
}
157
158
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
159
const char *ha_heap::index_type(uint32_t inx)
160
{
161
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
162
          "BTREE" : "HASH");
163
}
164
165
166
uint32_t ha_heap::index_flags(uint32_t inx, uint32_t, bool) const
167
{
168
  return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
169
          HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE :
170
          HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
171
}
172
173
1 by brian
clean slate
174
/*
175
  Compute which keys to use for scanning
176
177
  SYNOPSIS
178
    set_keys_for_scanning()
179
    no parameter
180
181
  DESCRIPTION
182
    Set the bitmap btree_keys, which is used when the upper layers ask
183
    which keys to use for scanning. For each btree index the
184
    corresponding bit is set.
185
186
  RETURN
187
    void
188
*/
189
190
void ha_heap::set_keys_for_scanning(void)
191
{
192
  btree_keys.clear_all();
482 by Brian Aker
Remove uint.
193
  for (uint32_t i= 0 ; i < table->s->keys ; i++)
1 by brian
clean slate
194
  {
195
    if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
196
      btree_keys.set_bit(i);
197
  }
198
}
199
200
201
void ha_heap::update_key_stats()
202
{
482 by Brian Aker
Remove uint.
203
  for (uint32_t i= 0; i < table->s->keys; i++)
1 by brian
clean slate
204
  {
205
    KEY *key=table->key_info+i;
206
    if (!key->rec_per_key)
207
      continue;
208
    if (key->algorithm != HA_KEY_ALG_BTREE)
209
    {
210
      if (key->flags & HA_NOSAME)
211
        key->rec_per_key[key->key_parts-1]= 1;
212
      else
213
      {
214
        ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
482 by Brian Aker
Remove uint.
215
        uint32_t no_records= hash_buckets ? (uint) (file->s->records/hash_buckets) : 2;
1 by brian
clean slate
216
        if (no_records < 2)
217
          no_records= 2;
218
        key->rec_per_key[key->key_parts-1]= no_records;
219
      }
220
    }
221
  }
222
  records_changed= 0;
223
  /* At the end of update_key_stats() we can proudly claim they are OK. */
224
  key_stat_version= file->s->key_stat_version;
225
}
226
227
481 by Brian Aker
Remove all of uchar.
228
int ha_heap::write_row(unsigned char * buf)
1 by brian
clean slate
229
{
230
  int res;
231
  ha_statistic_increment(&SSV::ha_write_count);
232
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
233
    table->timestamp_field->set_time();
234
  if (table->next_number_field && buf == table->record[0])
235
  {
236
    if ((res= update_auto_increment()))
237
      return res;
238
  }
239
  res= heap_write(file,buf);
584.5.1 by Monty Taylor
Removed field includes from field.h.
240
  if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
1 by brian
clean slate
241
               file->s->records))
242
  {
243
    /*
244
       We can perform this safely since only one writer at the time is
245
       allowed on the table.
246
    */
247
    file->s->key_stat_version++;
248
  }
249
  return res;
250
}
251
481 by Brian Aker
Remove all of uchar.
252
int ha_heap::update_row(const unsigned char * old_data, unsigned char * new_data)
1 by brian
clean slate
253
{
254
  int res;
255
  ha_statistic_increment(&SSV::ha_update_count);
256
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
257
    table->timestamp_field->set_time();
258
  res= heap_update(file,old_data,new_data);
259
  if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > 
260
              file->s->records)
261
  {
262
    /*
263
       We can perform this safely since only one writer at the time is
264
       allowed on the table.
265
    */
266
    file->s->key_stat_version++;
267
  }
268
  return res;
269
}
270
481 by Brian Aker
Remove all of uchar.
271
int ha_heap::delete_row(const unsigned char * buf)
1 by brian
clean slate
272
{
273
  int res;
274
  ha_statistic_increment(&SSV::ha_delete_count);
275
  res= heap_delete(file,buf);
276
  if (!res && table->s->tmp_table == NO_TMP_TABLE && 
277
      ++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
278
  {
279
    /*
280
       We can perform this safely since only one writer at the time is
281
       allowed on the table.
282
    */
283
    file->s->key_stat_version++;
284
  }
285
  return res;
286
}
287
481 by Brian Aker
Remove all of uchar.
288
int ha_heap::index_read_map(unsigned char *buf, const unsigned char *key,
1 by brian
clean slate
289
                            key_part_map keypart_map,
290
                            enum ha_rkey_function find_flag)
291
{
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
292
  assert(inited==INDEX);
1 by brian
clean slate
293
  ha_statistic_increment(&SSV::ha_read_key_count);
294
  int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
295
  table->status = error ? STATUS_NOT_FOUND : 0;
296
  return error;
297
}
298
481 by Brian Aker
Remove all of uchar.
299
int ha_heap::index_read_last_map(unsigned char *buf, const unsigned char *key,
1 by brian
clean slate
300
                                 key_part_map keypart_map)
301
{
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
302
  assert(inited==INDEX);
1 by brian
clean slate
303
  ha_statistic_increment(&SSV::ha_read_key_count);
304
  int error= heap_rkey(file, buf, active_index, key, keypart_map,
305
		       HA_READ_PREFIX_LAST);
306
  table->status= error ? STATUS_NOT_FOUND : 0;
307
  return error;
308
}
309
482 by Brian Aker
Remove uint.
310
int ha_heap::index_read_idx_map(unsigned char *buf, uint32_t index, const unsigned char *key,
1 by brian
clean slate
311
                                key_part_map keypart_map,
312
                                enum ha_rkey_function find_flag)
313
{
314
  ha_statistic_increment(&SSV::ha_read_key_count);
315
  int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
316
  table->status = error ? STATUS_NOT_FOUND : 0;
317
  return error;
318
}
319
481 by Brian Aker
Remove all of uchar.
320
int ha_heap::index_next(unsigned char * buf)
1 by brian
clean slate
321
{
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
322
  assert(inited==INDEX);
1 by brian
clean slate
323
  ha_statistic_increment(&SSV::ha_read_next_count);
324
  int error=heap_rnext(file,buf);
325
  table->status=error ? STATUS_NOT_FOUND: 0;
326
  return error;
327
}
328
481 by Brian Aker
Remove all of uchar.
329
int ha_heap::index_prev(unsigned char * buf)
1 by brian
clean slate
330
{
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
331
  assert(inited==INDEX);
1 by brian
clean slate
332
  ha_statistic_increment(&SSV::ha_read_prev_count);
333
  int error=heap_rprev(file,buf);
334
  table->status=error ? STATUS_NOT_FOUND: 0;
335
  return error;
336
}
337
481 by Brian Aker
Remove all of uchar.
338
int ha_heap::index_first(unsigned char * buf)
1 by brian
clean slate
339
{
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
340
  assert(inited==INDEX);
1 by brian
clean slate
341
  ha_statistic_increment(&SSV::ha_read_first_count);
342
  int error=heap_rfirst(file, buf, active_index);
343
  table->status=error ? STATUS_NOT_FOUND: 0;
344
  return error;
345
}
346
481 by Brian Aker
Remove all of uchar.
347
int ha_heap::index_last(unsigned char * buf)
1 by brian
clean slate
348
{
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
349
  assert(inited==INDEX);
1 by brian
clean slate
350
  ha_statistic_increment(&SSV::ha_read_last_count);
351
  int error=heap_rlast(file, buf, active_index);
352
  table->status=error ? STATUS_NOT_FOUND: 0;
353
  return error;
354
}
355
356
int ha_heap::rnd_init(bool scan)
357
{
358
  return scan ? heap_scan_init(file) : 0;
359
}
360
481 by Brian Aker
Remove all of uchar.
361
int ha_heap::rnd_next(unsigned char *buf)
1 by brian
clean slate
362
{
363
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
364
  int error=heap_scan(file, buf);
365
  table->status=error ? STATUS_NOT_FOUND: 0;
366
  return error;
367
}
368
481 by Brian Aker
Remove all of uchar.
369
int ha_heap::rnd_pos(unsigned char * buf, unsigned char *pos)
1 by brian
clean slate
370
{
371
  int error;
372
  HEAP_PTR heap_position;
373
  ha_statistic_increment(&SSV::ha_read_rnd_count);
212.6.8 by Mats Kindahl
Removing extreneous explicit casts for the heap storage engine.
374
  memcpy(&heap_position, pos, sizeof(HEAP_PTR));
1 by brian
clean slate
375
  error=heap_rrnd(file, buf, heap_position);
376
  table->status=error ? STATUS_NOT_FOUND: 0;
377
  return error;
378
}
379
481 by Brian Aker
Remove all of uchar.
380
void ha_heap::position(const unsigned char *record __attribute__((unused)))
1 by brian
clean slate
381
{
382
  *(HEAP_PTR*) ref= heap_position(file);	// Ref is aligned
383
}
384
482 by Brian Aker
Remove uint.
385
int ha_heap::info(uint32_t flag)
1 by brian
clean slate
386
{
387
  HEAPINFO hp_info;
388
  (void) heap_info(file,&hp_info,flag);
389
390
  errkey=                     hp_info.errkey;
391
  stats.records=              hp_info.records;
392
  stats.deleted=              hp_info.deleted;
393
  stats.mean_rec_length=      hp_info.reclength;
394
  stats.data_file_length=     hp_info.data_length;
395
  stats.index_file_length=    hp_info.index_length;
396
  stats.max_data_file_length= hp_info.max_records * hp_info.reclength;
397
  stats.delete_length=        hp_info.deleted * hp_info.reclength;
398
  if (flag & HA_STATUS_AUTO)
399
    stats.auto_increment_value= hp_info.auto_increment;
400
  /*
401
    If info() is called for the first time after open(), we will still
402
    have to update the key statistics. Hoping that a table lock is now
403
    in place.
404
  */
405
  if (key_stat_version != file->s->key_stat_version)
406
    update_key_stats();
407
  return 0;
408
}
409
410
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
411
enum row_type ha_heap::get_row_type() const
412
{
413
  if (file->s->recordspace.is_variable_size)
414
    return ROW_TYPE_DYNAMIC;
415
416
  return ROW_TYPE_FIXED;
417
}
418
1 by brian
clean slate
419
int ha_heap::extra(enum ha_extra_function operation)
420
{
421
  return heap_extra(file,operation);
422
}
423
424
425
int ha_heap::reset()
426
{
427
  return heap_reset(file);
428
}
429
430
431
int ha_heap::delete_all_rows()
432
{
433
  heap_clear(file);
434
  if (table->s->tmp_table == NO_TMP_TABLE)
435
  {
436
    /*
437
       We can perform this safely since only one writer at the time is
438
       allowed on the table.
439
    */
440
    file->s->key_stat_version++;
441
  }
442
  return 0;
443
}
444
520.1.22 by Brian Aker
Second pass of thd cleanup
445
int ha_heap::external_lock(Session *session __attribute__((unused)),
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
446
                           int lock_type __attribute__((unused)))
1 by brian
clean slate
447
{
448
  return 0;					// No external locking
449
}
450
451
452
/*
453
  Disable indexes.
454
455
  SYNOPSIS
456
    disable_indexes()
457
    mode        mode of operation:
458
                HA_KEY_SWITCH_NONUNIQ      disable all non-unique keys
459
                HA_KEY_SWITCH_ALL          disable all keys
460
                HA_KEY_SWITCH_NONUNIQ_SAVE dis. non-uni. and make persistent
461
                HA_KEY_SWITCH_ALL_SAVE     dis. all keys and make persistent
462
463
  DESCRIPTION
464
    Disable indexes and clear keys to use for scanning.
465
466
  IMPLEMENTATION
467
    HA_KEY_SWITCH_NONUNIQ       is not implemented.
468
    HA_KEY_SWITCH_NONUNIQ_SAVE  is not implemented with HEAP.
469
    HA_KEY_SWITCH_ALL_SAVE      is not implemented with HEAP.
470
471
  RETURN
472
    0  ok
473
    HA_ERR_WRONG_COMMAND  mode not implemented.
474
*/
475
482 by Brian Aker
Remove uint.
476
int ha_heap::disable_indexes(uint32_t mode)
1 by brian
clean slate
477
{
478
  int error;
479
480
  if (mode == HA_KEY_SWITCH_ALL)
481
  {
482
    if (!(error= heap_disable_indexes(file)))
483
      set_keys_for_scanning();
484
  }
485
  else
486
  {
487
    /* mode not implemented */
488
    error= HA_ERR_WRONG_COMMAND;
489
  }
490
  return error;
491
}
492
493
494
/*
495
  Enable indexes.
496
497
  SYNOPSIS
498
    enable_indexes()
499
    mode        mode of operation:
500
                HA_KEY_SWITCH_NONUNIQ      enable all non-unique keys
501
                HA_KEY_SWITCH_ALL          enable all keys
502
                HA_KEY_SWITCH_NONUNIQ_SAVE en. non-uni. and make persistent
503
                HA_KEY_SWITCH_ALL_SAVE     en. all keys and make persistent
504
505
  DESCRIPTION
506
    Enable indexes and set keys to use for scanning.
507
    The indexes might have been disabled by disable_index() before.
508
    The function works only if both data and indexes are empty,
509
    since the heap storage engine cannot repair the indexes.
510
    To be sure, call handler::delete_all_rows() before.
511
512
  IMPLEMENTATION
513
    HA_KEY_SWITCH_NONUNIQ       is not implemented.
514
    HA_KEY_SWITCH_NONUNIQ_SAVE  is not implemented with HEAP.
515
    HA_KEY_SWITCH_ALL_SAVE      is not implemented with HEAP.
516
517
  RETURN
518
    0  ok
519
    HA_ERR_CRASHED  data or index is non-empty. Delete all rows and retry.
520
    HA_ERR_WRONG_COMMAND  mode not implemented.
521
*/
522
482 by Brian Aker
Remove uint.
523
int ha_heap::enable_indexes(uint32_t mode)
1 by brian
clean slate
524
{
525
  int error;
526
527
  if (mode == HA_KEY_SWITCH_ALL)
528
  {
529
    if (!(error= heap_enable_indexes(file)))
530
      set_keys_for_scanning();
531
  }
532
  else
533
  {
534
    /* mode not implemented */
535
    error= HA_ERR_WRONG_COMMAND;
536
  }
537
  return error;
538
}
539
540
541
/*
542
  Test if indexes are disabled.
543
544
  SYNOPSIS
545
    indexes_are_disabled()
546
    no parameters
547
548
  RETURN
549
    0  indexes are not disabled
550
    1  all indexes are disabled
551
   [2  non-unique indexes are disabled - NOT YET IMPLEMENTED]
552
*/
553
554
int ha_heap::indexes_are_disabled(void)
555
{
556
  return heap_indexes_are_disabled(file);
557
}
558
520.1.22 by Brian Aker
Second pass of thd cleanup
559
THR_LOCK_DATA **ha_heap::store_lock(Session *session __attribute__((unused)),
77.1.7 by Monty Taylor
Heap builds clean.
560
                                    THR_LOCK_DATA **to,
561
                                    enum thr_lock_type lock_type)
1 by brian
clean slate
562
{
563
  if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
564
    file->lock.type=lock_type;
565
  *to++= &file->lock;
566
  return to;
567
}
568
569
/*
570
  We have to ignore ENOENT entries as the HEAP table is created on open and
571
  not when doing a CREATE on the table.
572
*/
573
574
int ha_heap::delete_table(const char *name)
575
{
590.1.7 by Stewart Smith
remove mysql_frm_type
576
  return heap_delete_table(name);
1 by brian
clean slate
577
}
578
579
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
580
void ha_heap::drop_table(const char *name __attribute__((unused)))
1 by brian
clean slate
581
{
582
  file->s->delete_on_close= 1;
583
  close();
584
}
585
586
587
int ha_heap::rename_table(const char * from, const char * to)
588
{
589
  return heap_rename(from,to);
590
}
591
592
482 by Brian Aker
Remove uint.
593
ha_rows ha_heap::records_in_range(uint32_t inx, key_range *min_key,
1 by brian
clean slate
594
                                  key_range *max_key)
595
{
596
  KEY *key=table->key_info+inx;
597
  if (key->algorithm == HA_KEY_ALG_BTREE)
598
    return hp_rb_records_in_range(file, inx, min_key, max_key);
599
600
  if (!min_key || !max_key ||
601
      min_key->length != max_key->length ||
602
      min_key->length != key->key_length ||
603
      min_key->flag != HA_READ_KEY_EXACT ||
604
      max_key->flag != HA_READ_AFTER_KEY)
605
    return HA_POS_ERROR;			// Can only use exact keys
606
607
  if (stats.records <= 1)
608
    return stats.records;
609
610
  /* Assert that info() did run. We need current statistics here. */
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
611
  assert(key_stat_version == file->s->key_stat_version);
1 by brian
clean slate
612
  return key->rec_per_key[key->key_parts-1];
613
}
614
615
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
616
int ha_heap::create(const char *name, Table *table_arg,
1 by brian
clean slate
617
		    HA_CREATE_INFO *create_info)
618
{
482 by Brian Aker
Remove uint.
619
  uint32_t key, parts, mem_per_row_keys= 0, keys= table_arg->s->keys;
620
  uint32_t auto_key= 0, auto_key_type= 0;
621
  uint32_t max_key_fieldnr = 0, key_part_size = 0, next_field_pos = 0;
622
  uint32_t column_idx, column_count= table_arg->s->fields;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
623
  HP_COLUMNDEF *columndef;
1 by brian
clean slate
624
  HP_KEYDEF *keydef;
625
  HA_KEYSEG *seg;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
626
  char buff[FN_REFLEN];
1 by brian
clean slate
627
  int error;
628
  TABLE_SHARE *share= table_arg->s;
629
  bool found_real_auto_increment= 0;
630
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
631
  if (!(columndef= (HP_COLUMNDEF*) my_malloc(column_count * sizeof(HP_COLUMNDEF), MYF(MY_WME))))
632
    return my_errno;
633
634
  for (column_idx= 0; column_idx < column_count; column_idx++)
635
  {
636
    Field* field= *(table_arg->field + column_idx);
637
    HP_COLUMNDEF* column= columndef + column_idx;
638
    column->type= (uint16_t)field->type();
639
    column->length= field->pack_length();
640
    column->offset= field->offset(field->table->record[0]);
641
642
    if (field->null_bit)
643
    {
644
      column->null_bit= field->null_bit;
481 by Brian Aker
Remove all of uchar.
645
      column->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
646
    }
647
    else
648
    {
649
      column->null_bit= 0;
650
      column->null_pos= 0;
651
    }
652
653
    if (field->type() == DRIZZLE_TYPE_VARCHAR)
654
    {
655
      column->length_bytes= (uint8_t)(((Field_varstring*)field)->length_bytes);
656
    }
657
    else
658
    {
659
      column->length_bytes= 0;
660
    }
661
  }
662
1 by brian
clean slate
663
  for (key= parts= 0; key < keys; key++)
664
    parts+= table_arg->key_info[key].key_parts;
665
666
  if (!(keydef= (HP_KEYDEF*) my_malloc(keys * sizeof(HP_KEYDEF) +
667
				       parts * sizeof(HA_KEYSEG),
668
				       MYF(MY_WME))))
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
669
  {
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
670
    free((void *) columndef);
1 by brian
clean slate
671
    return my_errno;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
672
  }
673
451 by Monty Taylor
Removed my_reinterpret_cast. It's not GNU specific.
674
  seg= reinterpret_cast<HA_KEYSEG*> (keydef + keys);
1 by brian
clean slate
675
  for (key= 0; key < keys; key++)
676
  {
677
    KEY *pos= table_arg->key_info+key;
678
    KEY_PART_INFO *key_part=     pos->key_part;
679
    KEY_PART_INFO *key_part_end= key_part + pos->key_parts;
680
681
    keydef[key].keysegs=   (uint) pos->key_parts;
682
    keydef[key].flag=      (pos->flags & (HA_NOSAME | HA_NULL_ARE_EQUAL));
683
    keydef[key].seg=       seg;
684
685
    switch (pos->algorithm) {
686
    case HA_KEY_ALG_UNDEF:
687
    case HA_KEY_ALG_HASH:
688
      keydef[key].algorithm= HA_KEY_ALG_HASH;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
689
      mem_per_row_keys+= sizeof(char*) * 2; // = sizeof(HASH_INFO)
1 by brian
clean slate
690
      break;
691
    case HA_KEY_ALG_BTREE:
692
      keydef[key].algorithm= HA_KEY_ALG_BTREE;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
693
      mem_per_row_keys+=sizeof(TREE_ELEMENT)+pos->key_length+sizeof(char*);
1 by brian
clean slate
694
      break;
695
    default:
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
696
      assert(0); // cannot happen
1 by brian
clean slate
697
    }
698
699
    for (; key_part != key_part_end; key_part++, seg++)
700
    {
701
      Field *field= key_part->field;
702
703
      if (pos->algorithm == HA_KEY_ALG_BTREE)
704
	seg->type= field->key_type();
705
      else
706
      {
707
        if ((seg->type = field->key_type()) != (int) HA_KEYTYPE_TEXT &&
708
            seg->type != HA_KEYTYPE_VARTEXT1 &&
709
            seg->type != HA_KEYTYPE_VARTEXT2 &&
710
            seg->type != HA_KEYTYPE_VARBINARY1 &&
711
            seg->type != HA_KEYTYPE_VARBINARY2)
712
          seg->type= HA_KEYTYPE_BINARY;
713
      }
714
      seg->start=   (uint) key_part->offset;
715
      seg->length=  (uint) key_part->length;
716
      seg->flag=    key_part->key_part_flag;
717
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
718
      next_field_pos= seg->start + seg->length;
719
      if (field->type() == DRIZZLE_TYPE_VARCHAR)
720
      {
721
        next_field_pos+= (uint8_t)(((Field_varstring*)field)->length_bytes);
722
      }
723
724
      if (next_field_pos > key_part_size) {
725
        key_part_size= next_field_pos;
726
      }
727
1 by brian
clean slate
728
      if (field->flags & (ENUM_FLAG | SET_FLAG))
729
        seg->charset= &my_charset_bin;
730
      else
731
        seg->charset= field->charset();
732
      if (field->null_ptr)
733
      {
734
	seg->null_bit= field->null_bit;
481 by Brian Aker
Remove all of uchar.
735
	seg->null_pos= (uint) (field->null_ptr - (unsigned char*) table_arg->record[0]);
1 by brian
clean slate
736
      }
737
      else
738
      {
739
	seg->null_bit= 0;
740
	seg->null_pos= 0;
741
      }
742
      if (field->flags & AUTO_INCREMENT_FLAG &&
743
          table_arg->found_next_number_field &&
744
          key == share->next_number_index)
745
      {
746
        /*
747
          Store key number and type for found auto_increment key
748
          We have to store type as seg->type can differ from it
749
        */
750
        auto_key= key+ 1;
751
	auto_key_type= field->key_type();
752
      }
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
753
      if ((uint)field->field_index + 1 > max_key_fieldnr)
754
      {
755
        /* Do not use seg->fieldnr as it's not reliable in case of temp tables */
756
        max_key_fieldnr= field->field_index + 1;
757
      }
1 by brian
clean slate
758
    }
759
  }
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
760
  
761
  if (key_part_size < share->null_bytes + ((share->last_null_bit_pos+7) >> 3))
762
  {
763
    /* Make sure to include null fields regardless of the presense of keys */
764
    key_part_size = share->null_bytes + ((share->last_null_bit_pos+7) >> 3);
765
  }
766
767
  
768
  
1 by brian
clean slate
769
  if (table_arg->found_next_number_field)
770
  {
771
    keydef[share->next_number_index].flag|= HA_AUTO_KEY;
772
    found_real_auto_increment= share->next_number_key_offset == 0;
773
  }
774
  HP_CREATE_INFO hp_create_info;
775
  hp_create_info.auto_key= auto_key;
776
  hp_create_info.auto_key_type= auto_key_type;
777
  hp_create_info.auto_increment= (create_info->auto_increment_value ?
778
				  create_info->auto_increment_value - 1 : 0);
520.1.22 by Brian Aker
Second pass of thd cleanup
779
  hp_create_info.max_table_size=current_session->variables.max_heap_table_size;
1 by brian
clean slate
780
  hp_create_info.with_auto_increment= found_real_auto_increment;
781
  hp_create_info.internal_table= internal_table;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
782
  hp_create_info.max_chunk_size= share->block_size;
783
  hp_create_info.is_dynamic= (share->row_type == ROW_TYPE_DYNAMIC);
784
  error= heap_create(fn_format(buff,name,"","",
785
                               MY_REPLACE_EXT|MY_UNPACK_FILENAME),
786
                   keys, keydef,
787
         column_count, columndef,
788
         max_key_fieldnr, key_part_size,
789
         share->reclength, mem_per_row_keys,
291 by Brian Aker
Head ulong conversion.
790
         (uint32_t) share->max_rows, (uint32_t) share->min_rows,
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
791
         &hp_create_info, &internal_share);
792
  
481 by Brian Aker
Remove all of uchar.
793
  free((unsigned char*) keydef);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
794
  free((void *) columndef);
51.3.1 by Jay Pipes
Removed all DBUG symbols from heap storage engine
795
  assert(file == 0);
1 by brian
clean slate
796
  return (error);
797
}
798
799
800
void ha_heap::update_create_info(HA_CREATE_INFO *create_info)
801
{
802
  table->file->info(HA_STATUS_AUTO);
803
  if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
804
    create_info->auto_increment_value= stats.auto_increment_value;
244.1.1 by Harrison Fisk
Port Ebay/Google memory storage engine variable width columns.
805
  if (!(create_info->used_fields & HA_CREATE_USED_BLOCK_SIZE))
806
  {
807
    if (file->s->recordspace.is_variable_size)
808
      create_info->block_size= file->s->recordspace.chunk_length;
809
    else
810
      create_info->block_size= 0;
811
  }
1 by brian
clean slate
812
}
813
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
814
void ha_heap::get_auto_increment(uint64_t offset __attribute__((unused)),
815
                                 uint64_t increment __attribute__((unused)),
816
                                 uint64_t nb_desired_values __attribute__((unused)),
1 by brian
clean slate
817
                                 uint64_t *first_value,
818
                                 uint64_t *nb_reserved_values)
819
{
820
  ha_heap::info(HA_STATUS_AUTO);
821
  *first_value= stats.auto_increment_value;
822
  /* such table has only table-level locking so reserves up to +inf */
163 by Brian Aker
Merge Monty's code.
823
  *nb_reserved_values= UINT64_MAX;
1 by brian
clean slate
824
}
825
826
827
bool ha_heap::check_if_incompatible_data(HA_CREATE_INFO *info,
482 by Brian Aker
Remove uint.
828
					 uint32_t table_changes)
1 by brian
clean slate
829
{
830
  /* Check that auto_increment value was not changed */
831
  if ((info->used_fields & HA_CREATE_USED_AUTO &&
832
       info->auto_increment_value != 0) ||
833
      table_changes == IS_EQUAL_NO ||
834
      table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
835
    return COMPATIBLE_DATA_NO;
836
  return COMPATIBLE_DATA_YES;
837
}
838
839
mysql_declare_plugin(heap)
840
{
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
841
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
1 by brian
clean slate
842
  "MEMORY",
177.4.3 by mark
ripped out more plugin ABI and API version checking, and plugin versions are now strings
843
  "1.0",
1 by brian
clean slate
844
  "MySQL AB",
845
  "Hash based, stored in memory, useful for temporary tables",
846
  PLUGIN_LICENSE_GPL,
847
  heap_init,
224.2.3 by Brian Aker
Fix for memory leak in shutdown/restart of an engine (not fixed in 5.1)
848
  heap_deinit,
1 by brian
clean slate
849
  NULL,                       /* status variables                */
850
  NULL,                       /* system variables                */
851
  NULL                        /* config options                  */
852
}
853
mysql_declare_plugin_end;