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