~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/blitzdb/ha_blitz.cc

  • Committer: Monty Taylor
  • Date: 2010-07-09 14:06:50 UTC
  • Revision ID: mordred@inaugust.com-20100709140650-ojeih829v3wbdkyv
Added include guard for generator.h to make cpplint happy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <config.h>
21
 
 
 
20
#include "config.h"
22
21
#include "ha_blitz.h"
23
 
#include <drizzled/plugin/storage_engine.h>
24
22
 
25
23
using namespace std;
26
24
using namespace drizzled;
27
 
namespace po= boost::program_options;
28
25
 
29
26
static pthread_mutex_t blitz_utility_mutex;
30
27
 
35
32
  NULL
36
33
};
37
34
 
38
 
/* Global Variables for Startup Options */
39
 
uint64_t blitz_estimated_rows;
40
 
 
41
35
class BlitzEngine : public drizzled::plugin::StorageEngine {
42
36
private:
43
37
  TCMAP *blitz_table_cache;
57
51
    tcmapdel(blitz_table_cache);
58
52
  }
59
53
 
60
 
  virtual drizzled::Cursor *create(drizzled::Table &table) {
61
 
    return new ha_blitz(*this, table);
 
54
  virtual drizzled::Cursor *create(drizzled::TableShare &table,
 
55
                                   drizzled::memory::Root *mem_root) {
 
56
    return new (mem_root) ha_blitz(*this, table);
62
57
  }
63
58
 
64
59
  const char **bas_ext() const {
67
62
 
68
63
  int doCreateTable(drizzled::Session &session,
69
64
                    drizzled::Table &table_arg,
70
 
                    const drizzled::identifier::Table &identifier,
 
65
                    const drizzled::TableIdentifier &identifier,
71
66
                    drizzled::message::Table &table_proto);
72
67
 
73
68
  int doRenameTable(drizzled::Session &session,
74
 
                    const drizzled::identifier::Table &from_identifier,
75
 
                    const drizzled::identifier::Table &to_identifier);
 
69
                    const drizzled::TableIdentifier &from_identifier,
 
70
                    const drizzled::TableIdentifier &to_identifier);
76
71
 
77
72
  int doDropTable(drizzled::Session &session,
78
 
                  const drizzled::identifier::Table &identifier);
 
73
                  const drizzled::TableIdentifier &identifier);
79
74
 
80
75
  int doGetTableDefinition(drizzled::Session &session,
81
 
                           const drizzled::identifier::Table &identifier,
 
76
                           const drizzled::TableIdentifier &identifier,
82
77
                           drizzled::message::Table &table_proto);
83
78
 
 
79
  void doGetTableNames(drizzled::CachedDirectory &directory,
 
80
                       const drizzled::SchemaIdentifier &schema_identifier,
 
81
                       std::set<std::string>& set_of_names);
 
82
 
84
83
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
85
 
                             const drizzled::identifier::Schema &schema_identifier,
86
 
                             drizzled::identifier::Table::vector &set_of_identifiers);
 
84
                             const drizzled::SchemaIdentifier &schema_identifier,
 
85
                             drizzled::TableIdentifiers &set_of_identifiers);
87
86
 
88
87
  bool doDoesTableExist(drizzled::Session &session,
89
 
                        const drizzled::identifier::Table &identifier);
90
 
 
91
 
  bool validateCreateTableOption(const std::string &key,
92
 
                                 const std::string &state);
 
88
                        const drizzled::TableIdentifier &identifier);
93
89
 
94
90
  bool doCreateTableCache(void);
95
91
 
119
115
static char *skip_btree_key(const char *key, const size_t skip_len,
120
116
                            int *return_klen);
121
117
 
122
 
static bool str_is_numeric(const std::string &str);
123
 
 
124
118
int BlitzEngine::doCreateTable(drizzled::Session &,
125
119
                               drizzled::Table &table,
126
 
                               const drizzled::identifier::Table &identifier,
 
120
                               const drizzled::TableIdentifier &identifier,
127
121
                               drizzled::message::Table &proto) {
128
122
  BlitzData dict;
129
123
  BlitzTree btree;
131
125
 
132
126
  /* Temporary fix for blocking composite keys. We need to add this
133
127
     check because version 1 doesn't handle composite indexes. */
134
 
  for (uint32_t i = 0; i < table.getShare()->keys; i++) {
 
128
  for (uint32_t i = 0; i < table.s->keys; i++) {
135
129
    if (table.key_info[i].key_parts > 1)
136
130
      return HA_ERR_UNSUPPORTED;
137
131
  }
145
139
    return ecode;
146
140
 
147
141
  /* Create b+tree index(es) for this table. */
148
 
  for (uint32_t i = 0; i < table.getShare()->keys; i++) {
 
142
  for (uint32_t i = 0; i < table.s->keys; i++) {
149
143
    if ((ecode = btree.create(identifier.getPath().c_str(), i)) != 0)
150
144
      return ecode;
151
145
  }
164
158
}
165
159
 
166
160
int BlitzEngine::doRenameTable(drizzled::Session &,
167
 
                               const drizzled::identifier::Table &from,
168
 
                               const drizzled::identifier::Table &to) {
 
161
                               const drizzled::TableIdentifier &from,
 
162
                               const drizzled::TableIdentifier &to) {
169
163
  int rv = 0;
170
164
 
171
165
  BlitzData blitz_table;
172
166
  uint32_t nkeys;
173
167
 
174
 
  BlitzData dict;
175
 
  int ecode;
176
 
  /* Write the table definition to system table. */
177
 
  if ((ecode = dict.open_system_table(from.getPath(), HDBOWRITER)) != 0)
178
 
    return ecode;
179
 
 
180
 
  drizzled::message::Table proto;
181
 
  char *proto_string;
182
 
  int proto_string_len;
183
 
 
184
 
  proto_string = dict.get_system_entry(BLITZ_TABLE_PROTO_KEY.c_str(),
185
 
                                       BLITZ_TABLE_PROTO_KEY.length(),
186
 
                                       &proto_string_len);
187
 
 
188
 
  if (proto_string == NULL) {
189
 
    return ENOMEM;
190
 
  }
191
 
 
192
 
  if (!proto.ParseFromArray(proto_string, proto_string_len)) {
193
 
    free(proto_string);
194
 
    return HA_ERR_CRASHED_ON_USAGE;
195
 
  }
196
 
 
197
 
  free(proto_string);
198
 
 
199
 
  proto.set_name(to.getTableName());
200
 
  proto.set_schema(to.getSchemaName());
201
 
  proto.set_catalog(to.getCatalogName());
202
 
 
203
 
  if (!dict.write_table_definition(proto)) {
204
 
    dict.close_system_table();
205
 
    return HA_ERR_CRASHED_ON_USAGE;
206
 
  }
207
 
 
208
 
  dict.close_system_table();
209
 
 
210
168
  /* Find out the number of indexes in this table. This information
211
169
     is required because BlitzDB creates a file for each indexes.*/
212
170
  if (blitz_table.open_data_table(from.getPath().c_str(), HDBOREADER) != 0)
243
201
}
244
202
 
245
203
int BlitzEngine::doDropTable(drizzled::Session &,
246
 
                             const drizzled::identifier::Table &identifier) {
 
204
                             const drizzled::TableIdentifier &identifier) {
247
205
  BlitzData dict;
248
206
  BlitzTree btree;
249
207
  char buf[FN_REFLEN];
284
242
}
285
243
 
286
244
int BlitzEngine::doGetTableDefinition(drizzled::Session &,
287
 
                                      const drizzled::identifier::Table &identifier,
 
245
                                      const drizzled::TableIdentifier &identifier,
288
246
                                      drizzled::message::Table &proto) {
289
247
  struct stat stat_info;
290
248
  std::string path(identifier.getPath());
325
283
  return EEXIST;
326
284
}
327
285
 
 
286
void BlitzEngine::doGetTableNames(drizzled::CachedDirectory &directory,
 
287
                                  const drizzled::SchemaIdentifier &,
 
288
                                  std::set<string> &set_of_names) {
 
289
  drizzled::CachedDirectory::Entries entries = directory.getEntries();
 
290
 
 
291
  for (drizzled::CachedDirectory::Entries::iterator entry_iter = entries.begin();
 
292
       entry_iter != entries.end(); ++entry_iter) {
 
293
 
 
294
    drizzled::CachedDirectory::Entry *entry = *entry_iter;
 
295
    std::string *filename = &entry->filename;
 
296
 
 
297
    assert(filename->size());
 
298
 
 
299
    const char *ext = strchr(filename->c_str(), '.');
 
300
 
 
301
    if (ext != NULL) {
 
302
      char uname[NAME_LEN + 1];
 
303
      uint32_t file_name_len;
 
304
 
 
305
      file_name_len = TableIdentifier::filename_to_tablename(filename->c_str(),
 
306
                                                             uname,
 
307
                                                             sizeof(uname));
 
308
 
 
309
      uname[file_name_len - sizeof(BLITZ_DATA_EXT) + 1]= '\0';
 
310
      set_of_names.insert(uname);
 
311
    }
 
312
  }
 
313
}
 
314
 
328
315
void BlitzEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
329
 
                                        const drizzled::identifier::Schema &schema_id,
330
 
                                        drizzled::identifier::Table::vector &ids) {
 
316
                                        const drizzled::SchemaIdentifier &schema_id,
 
317
                                        drizzled::TableIdentifiers &ids) {
331
318
  drizzled::CachedDirectory::Entries entries = directory.getEntries();
332
319
 
333
320
  for (drizzled::CachedDirectory::Entries::iterator entry_iter = entries.begin();
346
333
      char uname[NAME_LEN + 1];
347
334
      uint32_t file_name_len;
348
335
 
349
 
      file_name_len = identifier::Table::filename_to_tablename(filename->c_str(),
 
336
      file_name_len = TableIdentifier::filename_to_tablename(filename->c_str(),
350
337
                                                             uname,
351
338
                                                             sizeof(uname));
352
339
 
353
340
      uname[file_name_len - sizeof(BLITZ_DATA_EXT) + 1]= '\0';
354
 
      ids.push_back(identifier::Table(schema_id, uname));
 
341
      ids.push_back(TableIdentifier(schema_id, uname));
355
342
    }
356
343
  }
357
344
}
358
345
 
359
346
bool BlitzEngine::doDoesTableExist(drizzled::Session &,
360
 
                                   const drizzled::identifier::Table &identifier) {
 
347
                                   const drizzled::TableIdentifier &identifier) {
361
348
  std::string proto_path(identifier.getPath());
362
349
  proto_path.append(BLITZ_DATA_EXT);
363
350
 
364
351
  return (access(proto_path.c_str(), F_OK)) ? false : true;
365
352
}
366
353
 
367
 
bool BlitzEngine::validateCreateTableOption(const std::string &key,
368
 
                                            const std::string &state) {
369
 
  if (key == "ESTIMATED_ROWS" || key == "estimated_rows") {
370
 
    if (str_is_numeric(state))
371
 
      return true;
372
 
  }
373
 
  return false;
374
 
}
375
 
 
376
354
bool BlitzEngine::doCreateTableCache(void) {
377
355
  return ((blitz_table_cache = tcmapnew()) == NULL) ? false : true;
378
356
}
404
382
}
405
383
 
406
384
ha_blitz::ha_blitz(drizzled::plugin::StorageEngine &engine_arg,
407
 
                   Table &table_arg) : Cursor(engine_arg, table_arg),
 
385
                   TableShare &table_arg) : Cursor(engine_arg, table_arg),
408
386
                                            btree_cursor(NULL),
409
387
                                            table_scan(false),
410
388
                                            table_based(false),
460
438
     will use to uniquely identify a row. The actual allocation is
461
439
     done by the kernel so all we do here is specify the size of it.*/
462
440
  if (share->primary_key_exists) {
463
 
    ref_length = getTable()->key_info[getTable()->getShare()->getPrimaryKey()].key_length;
 
441
    ref_length = table->key_info[table->s->getPrimaryKey()].key_length;
464
442
  } else {
465
443
    ref_length = sizeof(held_key_len) + sizeof(uint64_t);
466
444
  }
499
477
 
500
478
int ha_blitz::doStartTableScan(bool scan) {
501
479
  /* Obtain the query type for this scan */
502
 
  sql_command_type = getTable()->getSession()->getSqlCommand();
 
480
  sql_command_type = session_sql_command(table->getSession());
503
481
  table_scan = scan;
504
482
  table_based = true;
505
483
 
506
484
  /* Obtain the most suitable lock for the given statement type. */
507
 
  blitz_optimal_lock();
 
485
  critical_section_enter();
508
486
 
509
487
  /* Get the first record from TCHDB. Let the scanner take
510
488
     care of checking return value errors. */
527
505
  held_key = NULL;
528
506
 
529
507
  if (current_key == NULL) {
530
 
    getTable()->status = STATUS_NOT_FOUND;
 
508
    table->status = STATUS_NOT_FOUND;
531
509
    return HA_ERR_END_OF_FILE;
532
510
  }
533
511
 
558
536
  /* It is now memory-leak-safe to point current_key to next_key. */
559
537
  current_key = next_key;
560
538
  current_key_len = next_key_len;
561
 
  getTable()->status = 0;
 
539
  table->status = 0;
562
540
  return 0;
563
541
}
564
542
 
576
554
  table_based = false;
577
555
 
578
556
  if (thread_locked)
579
 
    blitz_optimal_unlock();
 
557
    critical_section_exit();
580
558
 
581
559
  return 0;
582
560
}
624
602
 
625
603
int ha_blitz::doStartIndexScan(uint32_t key_num, bool) {
626
604
  active_index = key_num;
627
 
  sql_command_type = getTable()->getSession()->getSqlCommand();
 
605
  sql_command_type = session_sql_command(table->getSession());
628
606
 
629
607
  /* This is unlikely to happen but just for assurance, re-obtain
630
608
     the lock if this thread already has a certain lock. This makes
631
609
     sure that this thread will get the most appropriate lock for
632
610
     the current statement. */
633
611
  if (thread_locked)
634
 
    blitz_optimal_unlock();
 
612
    critical_section_exit();
635
613
 
636
 
  blitz_optimal_lock();
 
614
  critical_section_enter();
637
615
  return 0;
638
616
}
639
617
 
669
647
  bt_key = btree_cursor[active_index].next_key(&bt_klen);
670
648
 
671
649
  if (bt_key == NULL) {
672
 
    getTable()->status = STATUS_NOT_FOUND;
 
650
    table->status = STATUS_NOT_FOUND;
673
651
    return HA_ERR_END_OF_FILE;
674
652
  }
675
653
 
678
656
 
679
657
  if ((row = share->dict.get_row(dict_key, dict_klen, &rlen)) == NULL) {
680
658
    free(bt_key);
681
 
    getTable()->status = STATUS_NOT_FOUND;
 
659
    table->status = STATUS_NOT_FOUND;
682
660
    return HA_ERR_KEY_NOT_FOUND;
683
661
  }
684
662
 
805
783
  btree_cursor[active_index].moved = false;
806
784
 
807
785
  if (thread_locked)
808
 
    blitz_optimal_unlock();
 
786
    critical_section_exit();
809
787
 
810
788
  return 0;
811
789
}
833
811
  ha_statistic_increment(&system_status_var::ha_write_count);
834
812
 
835
813
  /* Prepare Auto Increment field if one exists. */
836
 
  if (getTable()->next_number_field && drizzle_row == getTable()->getInsertRecord()) {
 
814
  if (table->next_number_field && drizzle_row == table->record[0]) {
837
815
    pthread_mutex_lock(&blitz_utility_mutex);
838
816
    if ((rv = update_auto_increment()) != 0) {
839
817
      pthread_mutex_unlock(&blitz_utility_mutex);
840
818
      return rv;
841
819
    }
842
820
 
843
 
    uint64_t next_val = getTable()->next_number_field->val_int();
 
821
    uint64_t next_val = table->next_number_field->val_int();
844
822
 
845
823
    if (next_val > share->auto_increment_value) {
846
824
      share->auto_increment_value = next_val;
971
949
      /* Now write the new key. */
972
950
      prefix_len = make_index_key(key_buffer, i, new_row);
973
951
 
974
 
      if (i == getTable()->getShare()->getPrimaryKey()) {
 
952
      if (i == table->s->getPrimaryKey()) {
975
953
        key = merge_key(key_buffer, prefix_len, key_buffer, prefix_len, &klen);
976
954
        rv = share->btrees[i].write(key, klen);
977
955
      } else {
998
976
  if (table_based) {
999
977
    rv = share->dict.write_row(held_key, held_key_len, row_buf, row_len);
1000
978
  } else {
1001
 
    int klen = make_index_key(key_buffer, getTable()->getShare()->getPrimaryKey(), old_row);
 
979
    int klen = make_index_key(key_buffer, table->s->getPrimaryKey(), old_row);
1002
980
 
1003
981
    /* Delete with the old key. */
1004
982
    share->dict.delete_row(key_buffer, klen);
1005
983
 
1006
984
    /* Write with the new key. */
1007
 
    klen = make_index_key(key_buffer, getTable()->getShare()->getPrimaryKey(), new_row);
 
985
    klen = make_index_key(key_buffer, table->s->getPrimaryKey(), new_row);
1008
986
    rv = share->dict.write_row(key_buffer, klen, row_buf, row_len);
1009
987
  }
1010
988
 
1096
1074
}
1097
1075
 
1098
1076
uint32_t ha_blitz::max_row_length(void) {
1099
 
  uint32_t length = (getTable()->getRecordLength() + getTable()->sizeFields() * 2);
1100
 
  uint32_t *pos = getTable()->getBlobField();
1101
 
  uint32_t *end = pos + getTable()->sizeBlobFields();
 
1077
  uint32_t length = (table->getRecordLength() + table->sizeFields() * 2);
 
1078
  uint32_t *pos = table->getBlobField();
 
1079
  uint32_t *end = pos + table->sizeBlobFields();
1102
1080
 
1103
1081
  while (pos != end) {
1104
 
    length += 2 + ((Field_blob *)getTable()->getField(*pos))->get_length();
 
1082
    length += 2 + ((Field_blob *)table->getField(*pos))->get_length();
1105
1083
    pos++;
1106
1084
  }
1107
1085
 
1118
1096
  /* Getting here means that there is a PK in this table. Get the
1119
1097
     binary representation of the PK, pack it to BlitzDB's key buffer
1120
1098
     and return the size of it. */
1121
 
  return make_index_key(pack_to, getTable()->getShare()->getPrimaryKey(), row);
 
1099
  return make_index_key(pack_to, table->s->getPrimaryKey(), row);
1122
1100
}
1123
1101
 
1124
1102
size_t ha_blitz::make_index_key(char *pack_to, int key_num,
1125
1103
                                const unsigned char *row) {
1126
 
  KeyInfo *key = &getTable()->key_info[key_num];
 
1104
  KeyInfo *key = &table->key_info[key_num];
1127
1105
  KeyPartInfo *key_part = key->key_part;
1128
1106
  KeyPartInfo *key_part_end = key_part + key->key_parts;
1129
1107
 
1143
1121
      *pos++ = 1;
1144
1122
    }
1145
1123
 
1146
 
    /* Here we normalize VARTEXT1 to VARTEXT2 for simplicity. */
1147
 
    if (key_part->type == HA_KEYTYPE_VARTEXT1) {
1148
 
      /* Extract the length of the string from the row. */
1149
 
      uint16_t data_len = *(uint8_t *)(row + key_part->offset);
1150
 
 
1151
 
      /* Copy the length of the string. Use 2 bytes. */
1152
 
      int2store(pos, data_len);
1153
 
      pos += sizeof(data_len);
1154
 
 
1155
 
      /* Copy the string data */
1156
 
      memcpy(pos, row + key_part->offset + sizeof(uint8_t), data_len);
1157
 
      pos += data_len;
1158
 
    } else {
1159
 
      end = key_part->field->pack(pos, row + key_part->offset);
1160
 
      offset = end - pos;
1161
 
      pos += offset;
1162
 
    }
 
1124
    end = key_part->field->pack(pos, row + key_part->offset);
 
1125
    offset = end - pos;
 
1126
    pos += offset;
1163
1127
  }
1164
1128
 
1165
1129
  return ((char *)pos - pack_to);
1198
1162
}
1199
1163
 
1200
1164
size_t ha_blitz::btree_key_length(const char *key, const int key_num) {
1201
 
  KeyInfo *key_info = &getTable()->key_info[key_num];
 
1165
  KeyInfo *key_info = &table->key_info[key_num];
1202
1166
  KeyPartInfo *key_part = key_info->key_part;
1203
1167
  KeyPartInfo *key_part_end = key_part + key_info->key_parts;
1204
1168
  char *pos = (char *)key;
1207
1171
 
1208
1172
  for (; key_part != key_part_end; key_part++) {
1209
1173
    if (key_part->null_bit) {
1210
 
      pos++;
1211
1174
      rv++;
1212
1175
      if (*key == 0)
1213
1176
        continue;
1214
1177
    }
1215
1178
 
1216
 
    if (key_part->type == HA_KEYTYPE_VARTEXT1 ||
1217
 
        key_part->type == HA_KEYTYPE_VARTEXT2) {
 
1179
    if (key_part->type == HA_KEYTYPE_VARTEXT1) {
 
1180
      len = *(uint8_t *)pos;
 
1181
      rv += len + sizeof(uint8_t);
 
1182
    } else if (key_part->type == HA_KEYTYPE_VARTEXT2) {
1218
1183
      len = uint2korr(pos);
1219
1184
      rv += len + sizeof(uint16_t);
1220
1185
    } else {
1237
1202
/* Converts a native Drizzle index key to BlitzDB's format. */
1238
1203
char *ha_blitz::native_to_blitz_key(const unsigned char *native_key,
1239
1204
                                    const int key_num, int *return_key_len) {
1240
 
  KeyInfo *key = &getTable()->key_info[key_num];
 
1205
  KeyInfo *key = &table->key_info[key_num];
1241
1206
  KeyPartInfo *key_part = key->key_part;
1242
1207
  KeyPartInfo *key_part_end = key_part + key->key_parts;
1243
1208
 
1258
1223
        continue;
1259
1224
    }
1260
1225
 
1261
 
    /* Normalize a VARTEXT1 key to VARTEXT2. */
 
1226
    /* This is a temporary workaround for a bug in Drizzle's VARCHAR
 
1227
       where a 1 byte representable length varchar's actual data is
 
1228
       positioned 2 bytes ahead of the beginning of the buffer. The
 
1229
       correct behavior is to be positioned 1 byte ahead. Furthermore,
 
1230
       this is only applicable with varchar keys on READ. */
1262
1231
    if (key_part->type == HA_KEYTYPE_VARTEXT1) {
1263
 
      uint16_t str_len = *(uint16_t *)key_pos;
1264
 
 
1265
 
      /* Copy the length of the string over to key buffer. */
1266
 
      int2store(keybuf_pos, str_len);
1267
 
      keybuf_pos += sizeof(str_len);
1268
 
 
1269
 
      /* Copy the actual value over to the key buffer. */
1270
 
      memcpy(keybuf_pos, key_pos + sizeof(str_len), str_len);
1271
 
      keybuf_pos += str_len;
1272
 
 
1273
 
      /* NULL byte + Length of str (2 byte) + Actual String. */
1274
 
      offset = 1 + sizeof(str_len) + str_len;
 
1232
      /* Dereference the 1 byte length of the value. */
 
1233
      uint8_t varlen = *(uint8_t *)key_pos;
 
1234
      *keybuf_pos++ = varlen;
 
1235
 
 
1236
      /* Read the value by skipping 2 bytes. This is the workaround. */
 
1237
      memcpy(keybuf_pos, key_pos + sizeof(uint16_t), varlen);
 
1238
      offset = (sizeof(uint8_t) + varlen);
 
1239
      keybuf_pos += varlen;
1275
1240
    } else {
1276
1241
      end = key_part->field->pack(keybuf_pos, key_pos);
1277
1242
      offset = end - keybuf_pos;
1292
1257
 
1293
1258
  /* Nothing special to do if the table is fixed length */
1294
1259
  if (share->fixed_length_table) {
1295
 
    memcpy(row_buffer, row_to_pack, getTable()->getShare()->getRecordLength());
1296
 
    return (size_t)getTable()->getShare()->getRecordLength();
 
1260
    memcpy(row_buffer, row_to_pack, table->s->getRecordLength());
 
1261
    return (size_t)table->s->getRecordLength();
1297
1262
  }
1298
1263
 
1299
1264
  /* Copy NULL bits */
1300
 
  memcpy(row_buffer, row_to_pack, getTable()->getShare()->null_bytes);
1301
 
  pos = row_buffer + getTable()->getShare()->null_bytes;
 
1265
  memcpy(row_buffer, row_to_pack, table->s->null_bytes);
 
1266
  pos = row_buffer + table->s->null_bytes;
1302
1267
 
1303
1268
  /* Pack each field into the buffer */
1304
 
  for (Field **field = getTable()->getFields(); *field; field++) {
 
1269
  for (Field **field = table->getFields(); *field; field++) {
1305
1270
    if (!((*field)->is_null()))
1306
1271
      pos = (*field)->pack(pos, row_to_pack + (*field)->offset(row_to_pack));
1307
1272
  }
1322
1287
  /* Start by copying NULL bits which is the beginning block
1323
1288
     of a Drizzle row. */
1324
1289
  pos = (const unsigned char *)from;
1325
 
  memcpy(to, pos, getTable()->getShare()->null_bytes);
1326
 
  pos += getTable()->getShare()->null_bytes;
 
1290
  memcpy(to, pos, table->s->null_bytes);
 
1291
  pos += table->s->null_bytes;
1327
1292
 
1328
1293
  /* Unpack all fields in the provided row. */
1329
 
  for (Field **field = getTable()->getFields(); *field; field++) {
 
1294
  for (Field **field = table->getFields(); *field; field++) {
1330
1295
    if (!((*field)->is_null())) {
1331
 
      pos = (*field)->unpack(to + (*field)->offset(getTable()->getInsertRecord()), pos);
 
1296
      pos = (*field)->unpack(to + (*field)->offset(table->record[0]), pos);
1332
1297
    }
1333
1298
  }
1334
1299
 
1350
1315
 
1351
1316
      secondary_row_buffer_size = size;
1352
1317
      secondary_row_buffer = (unsigned char *)new_ptr;
 
1318
      buf = secondary_row_buffer;
1353
1319
    }
1354
 
    buf = secondary_row_buffer;
1355
1320
  }
1356
1321
  return buf;
1357
1322
}
1360
1325
 
1361
1326
BlitzShare *ha_blitz::get_share(const char *name) {
1362
1327
  BlitzShare *share_ptr;
1363
 
  BlitzEngine *bz_engine = (BlitzEngine *)getEngine();
 
1328
  BlitzEngine *bz_engine = (BlitzEngine *)engine;
1364
1329
  std::string table_path(name);
1365
1330
 
1366
1331
  pthread_mutex_lock(&blitz_utility_mutex);
1385
1350
  }
1386
1351
 
1387
1352
  /* Prepare Index Structure(s) */
1388
 
  KeyInfo *curr = &getTable()->getMutableShare()->getKeyInfo(0);
1389
 
  share_ptr->btrees = new BlitzTree[getTable()->getShare()->keys];
 
1353
  KeyInfo *curr = &table->s->getKeyInfo(0);
 
1354
  share_ptr->btrees = new BlitzTree[table->s->keys];
1390
1355
 
1391
 
  for (uint32_t i = 0; i < getTable()->getShare()->keys; i++, curr++) {
 
1356
  for (uint32_t i = 0; i < table->s->keys; i++, curr++) {
1392
1357
    share_ptr->btrees[i].open(table_path.c_str(), i, BDBOWRITER);
1393
1358
    share_ptr->btrees[i].parts = new BlitzKeyPart[curr->key_parts];
1394
1359
 
1395
 
    if (getTable()->key_info[i].flags & HA_NOSAME)
 
1360
    if (table->key_info[i].flags & HA_NOSAME)
1396
1361
      share_ptr->btrees[i].unique = true;
1397
1362
 
1398
1363
    share_ptr->btrees[i].length = curr->key_length;
1405
1370
      if (f->null_ptr) {
1406
1371
        share_ptr->btrees[i].parts[j].null_bitmask = f->null_bit;
1407
1372
        share_ptr->btrees[i].parts[j].null_pos
1408
 
          = (uint32_t)(f->null_ptr - (unsigned char *)getTable()->getInsertRecord());
 
1373
          = (uint32_t)(f->null_ptr - (unsigned char *)table->record[0]);
1409
1374
      }
1410
1375
 
1411
1376
      share_ptr->btrees[i].parts[j].flag = curr->key_part[j].key_part_flag;
1423
1388
  /* Set Meta Data */
1424
1389
  share_ptr->auto_increment_value = share_ptr->dict.read_meta_autoinc();
1425
1390
  share_ptr->table_name = table_path;
1426
 
  share_ptr->nkeys = getTable()->getShare()->keys;
 
1391
  share_ptr->nkeys = table->s->keys;
1427
1392
  share_ptr->use_count = 1;
1428
1393
 
1429
 
  share_ptr->fixed_length_table = !(getTable()->getShare()->db_create_options
 
1394
  share_ptr->fixed_length_table = !(table->s->db_create_options
1430
1395
                                    & HA_OPTION_PACK_RECORD);
1431
1396
 
1432
 
  if (getTable()->getShare()->getPrimaryKey() >= MAX_KEY)
 
1397
  if (table->s->getPrimaryKey() >= MAX_KEY)
1433
1398
    share_ptr->primary_key_exists = false;
1434
1399
  else
1435
1400
    share_ptr->primary_key_exists = true;
1460
1425
      share->btrees[i].close();
1461
1426
    }
1462
1427
 
1463
 
    BlitzEngine *bz_engine = (BlitzEngine *)getEngine();
 
1428
    BlitzEngine *bz_engine = (BlitzEngine *)engine;
1464
1429
    bz_engine->deleteTableShare(share->table_name);
1465
1430
 
1466
1431
    delete[] share->btrees;
1481
1446
 
1482
1447
  pthread_mutex_init(&blitz_utility_mutex, NULL);
1483
1448
  context.add(blitz_engine);
1484
 
  context.registerVariable(new sys_var_uint64_t_ptr("estimated-rows",
1485
 
                                                    &blitz_estimated_rows));
1486
1449
  return 0;
1487
1450
}
1488
1451
 
1494
1457
  return pos + skip_len + sizeof(uint16_t);
1495
1458
}
1496
1459
 
1497
 
static bool str_is_numeric(const std::string &str) {
1498
 
  for (uint32_t i = 0; i < str.length(); i++) {
1499
 
    if (!std::isdigit(str[i]))
1500
 
      return false;
1501
 
  }
1502
 
  return true;
1503
 
}
1504
 
 
1505
 
static void blitz_init_options(drizzled::module::option_context &context)
1506
 
{
1507
 
  context("estimated-rows",
1508
 
          po::value<uint64_t>(&blitz_estimated_rows)->default_value(0),
1509
 
          N_("Estimated number of rows that a BlitzDB table will store."));
1510
 
}
1511
 
 
1512
 
DRIZZLE_PLUGIN(blitz_init, NULL, blitz_init_options);
 
1460
DRIZZLE_PLUGIN(blitz_init, NULL, NULL);