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