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