22
22
/*****************************************************************************
24
Copyright (C) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
25
Copyright (C) 2008, 2009 Google Inc.
24
Copyright (c) 2000, 2009, MySQL AB & Innobase Oy. All Rights Reserved.
25
Copyright (c) 2008, 2009 Google Inc.
27
27
Portions of this file contain modifications contributed and copyrighted by
28
28
Google, Inc. Those modifications are gratefully acknowledged and are described
45
45
*****************************************************************************/
46
46
/***********************************************************************
48
Copyright (C) 1995, 2009, Innobase Oy. All Rights Reserved.
49
Copyright (C) 2009, Percona Inc.
48
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
49
Copyright (c) 2009, Percona Inc.
51
51
Portions of this file contain modifications contributed and copyrighted
52
52
by Percona Inc.. Those modifications are
116
117
using namespace google;
117
118
using namespace drizzled;
119
int read_row_from_haildb(Session *session, unsigned char* buf, ib_crsr_t cursor, ib_tpl_t tuple, Table* table, bool has_hidden_primary_key, uint64_t *hidden_pkey, drizzled::memory::Root **blobroot= NULL);
120
int read_row_from_haildb(unsigned char* buf, ib_crsr_t cursor, ib_tpl_t tuple, Table* table, bool has_hidden_primary_key, uint64_t *hidden_pkey, drizzled::memory::Root **blobroot= NULL);
120
121
static void fill_ib_search_tpl_from_drizzle_key(ib_tpl_t search_tuple,
121
122
const drizzled::KeyInfo *key_info,
122
123
const unsigned char *key_ptr,
166
167
int doCreateTable(Session&,
167
168
Table& table_arg,
168
const drizzled::identifier::Table &identifier,
169
const drizzled::TableIdentifier &identifier,
169
170
drizzled::message::Table& proto);
171
int doDropTable(Session&, const identifier::Table &identifier);
172
int doDropTable(Session&, const TableIdentifier &identifier);
173
174
int doRenameTable(drizzled::Session&,
174
const drizzled::identifier::Table&,
175
const drizzled::identifier::Table&);
175
const drizzled::TableIdentifier&,
176
const drizzled::TableIdentifier&);
177
178
int doGetTableDefinition(Session& session,
178
const identifier::Table &identifier,
179
const TableIdentifier &identifier,
179
180
drizzled::message::Table &table_proto);
181
bool doDoesTableExist(Session&, const identifier::Table &identifier);
182
bool doDoesTableExist(Session&, const TableIdentifier &identifier);
184
void getTableNamesInSchemaFromHailDB(const drizzled::identifier::Schema &schema,
185
void getTableNamesInSchemaFromHailDB(const drizzled::SchemaIdentifier &schema,
185
186
drizzled::plugin::TableNameList *set_of_names,
186
drizzled::identifier::Table::vector *identifiers);
187
drizzled::TableIdentifier::vector *identifiers);
189
190
void doGetTableIdentifiers(drizzled::CachedDirectory &,
190
const drizzled::identifier::Schema &schema,
191
drizzled::identifier::Table::vector &identifiers);
191
const drizzled::SchemaIdentifier &schema,
192
drizzled::TableIdentifier::vector &identifiers);
193
194
/* The following defines can be increased if necessary */
194
195
uint32_t max_supported_keys() const { return 1000; }
431
429
ib_trx_t *transaction= get_trx(session);
431
if (all || !session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
435
if (ib_trx_state(*transaction) == IB_TRX_NOT_STARTED)
436
err= ib_trx_release(*transaction);
438
err= ib_trx_rollback(*transaction);
433
err= ib_trx_rollback(*transaction);
440
435
if (err != DB_SUCCESS)
441
return ib_err_t_to_drizzle_error(session, err);
436
return ib_err_t_to_drizzle_error(err);
443
438
*transaction= NULL;
447
if (ib_trx_state(*transaction) == IB_TRX_NOT_STARTED)
450
442
err= ib_savepoint_rollback(*transaction, statement_savepoint_name.c_str(),
451
443
statement_savepoint_name.length());
452
444
if (err != DB_SUCCESS)
453
return ib_err_t_to_drizzle_error(session, err);
445
return ib_err_t_to_drizzle_error(err);
829
820
int HailDBCursor::open(const char *name, int, uint32_t)
831
822
const char* haildb_table_name= table_path_to_haildb_name(name);
832
ib_err_t err= ib_table_get_id(haildb_table_name, &table_id);
823
ib_err_t err= ib_cursor_open_table(haildb_table_name, NULL, &cursor);
833
824
bool has_hidden_primary_key= false;
836
827
if (err != DB_SUCCESS)
837
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
839
err= ib_cursor_open_table_using_id(table_id, NULL, &cursor);
840
cursor_is_sec_index= false;
842
if (err != DB_SUCCESS)
843
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
828
return ib_err_t_to_drizzle_error(err);
845
830
err= ib_index_get_id(haildb_table_name, "HIDDEN_PRIMARY", &idx_id);
1515
1500
assert(rollback_err == DB_SUCCESS);
1516
1501
rollback_err= ib_trx_rollback(haildb_schema_transaction);
1517
1502
assert(rollback_err == DB_SUCCESS);
1518
return ib_err_t_to_drizzle_error(&session, err);
1503
return ib_err_t_to_drizzle_error(err);
1521
1506
void HailDBEngine::getTableNamesInSchemaFromHailDB(
1522
const drizzled::identifier::Schema &schema,
1507
const drizzled::SchemaIdentifier &schema,
1523
1508
drizzled::plugin::TableNameList *set_of_names,
1524
drizzled::identifier::Table::vector *identifiers)
1509
drizzled::TableIdentifier::vector *identifiers)
1526
1511
ib_trx_t transaction;
1527
1512
ib_crsr_t cursor;
1793
1778
return("BTREE");
1796
static ib_err_t write_row_to_haildb_tuple(const unsigned char* buf,
1797
Field **fields, ib_tpl_t tuple)
1781
static ib_err_t write_row_to_haildb_tuple(Field **fields, ib_tpl_t tuple)
1800
1784
ib_err_t err= DB_ERROR;
1801
ptrdiff_t row_offset= buf - (*fields)->getTable()->getInsertRecord();
1803
1786
for (Field **field= fields; *field; field++, colnr++)
1805
(**field).move_field_offset(row_offset);
1807
1788
if (! (**field).isWriteSet() && (**field).is_null())
1809
(**field).move_field_offset(-row_offset);
1813
1791
if ((**field).is_null())
1815
1793
err= ib_col_set_value(tuple, colnr, NULL, IB_SQL_NULL);
1816
1794
assert(err == DB_SUCCESS);
1817
(**field).move_field_offset(-row_offset);
1903
1878
tuple= ib_clust_read_tuple_create(cursor);
1905
if (cursor_is_sec_index)
1907
err= ib_cursor_close(cursor);
1908
assert(err == DB_SUCCESS);
1910
err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
1912
if (err != DB_SUCCESS)
1913
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
1915
cursor_is_sec_index= false;
1919
ib_cursor_attach_trx(cursor, transaction);
1880
ib_cursor_attach_trx(cursor, transaction);
1922
1882
err= ib_cursor_first(cursor);
1923
1883
if (current_session->lex->sql_command == SQLCOM_CREATE_TABLE
1979
write_row_to_haildb_tuple(record, getTable()->getFields(), tuple);
1939
write_row_to_haildb_tuple(getTable()->getFields(), tuple);
1981
1941
if (share->has_hidden_primary_key)
1983
err= ib_tuple_write_u64(tuple, getTable()->getShare()->sizeFields(),
1984
share->hidden_pkey_auto_increment_value.fetch_and_increment());
1943
err= ib_tuple_write_u64(tuple, getTable()->getShare()->fields, share->hidden_pkey_auto_increment_value.fetch_and_increment());
1987
1946
err= ib_cursor_insert_row(cursor, tuple);
2019
1978
ret= HA_ERR_FOUND_DUPP_KEY;
2021
1980
else if (err != DB_SUCCESS)
2022
ret= ib_err_t_to_drizzle_error(getTable()->getSession(), err);
1981
ret= ib_err_t_to_drizzle_error(err);
2024
1983
tuple= ib_tuple_clear(tuple);
2025
1984
ib_tuple_delete(tuple);
2027
1985
err= ib_cursor_reset(cursor);
2032
int HailDBCursor::doUpdateRecord(const unsigned char *old_data,
2033
unsigned char *new_data)
1990
int HailDBCursor::doUpdateRecord(const unsigned char *,
2035
1993
ib_tpl_t update_tuple;
2037
bool created_tuple= false;
2039
1996
update_tuple= ib_clust_read_tuple_create(cursor);
2043
ib_trx_t transaction= *get_trx(getTable()->in_use);
2045
if (cursor_is_sec_index)
2047
err= ib_cursor_close(cursor);
2048
assert(err == DB_SUCCESS);
2050
err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
2052
if (err != DB_SUCCESS)
2053
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2054
cursor_is_sec_index= false;
2058
ib_cursor_attach_trx(cursor, transaction);
2061
store_key_value_from_haildb(getTable()->key_info + getTable()->getShare()->getPrimaryKey(),
2062
ref, ref_length, old_data);
2064
ib_tpl_t search_tuple= ib_clust_search_tuple_create(cursor);
2066
fill_ib_search_tpl_from_drizzle_key(search_tuple,
2067
getTable()->key_info + 0,
2070
err= ib_cursor_set_lock_mode(cursor, IB_LOCK_X);
2071
assert(err == DB_SUCCESS);
2074
err= ib_cursor_moveto(cursor, search_tuple, IB_CUR_GE, &res);
2075
assert(err == DB_SUCCESS);
2077
tuple= ib_clust_read_tuple_create(cursor);
2079
err= ib_cursor_read_row(cursor, tuple);
2080
assert(err == DB_SUCCESS);// FIXME
2082
created_tuple= true;
2085
1998
err= ib_tuple_copy(update_tuple, tuple);
2086
1999
assert(err == DB_SUCCESS);
2088
write_row_to_haildb_tuple(new_data, getTable()->getFields(), update_tuple);
2001
write_row_to_haildb_tuple(getTable()->getFields(), update_tuple);
2090
2003
err= ib_cursor_update_row(cursor, tuple, update_tuple);
2092
2005
ib_tuple_delete(update_tuple);
2096
ib_err_t ib_err= ib_cursor_reset(cursor); //fixme check error
2097
assert(ib_err == DB_SUCCESS);
2098
tuple= ib_tuple_clear(tuple);
2099
ib_tuple_delete(tuple);
2103
2007
advance_cursor= true;
2105
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2009
if (err == DB_SUCCESS)
2011
else if (err == DB_DUPLICATE_KEY)
2012
return HA_ERR_FOUND_DUPP_KEY;
2108
2017
int HailDBCursor::doDeleteRecord(const unsigned char *)
2112
assert(ib_cursor_is_positioned(cursor) == IB_TRUE);
2113
2021
err= ib_cursor_delete_row(cursor);
2022
if (err != DB_SUCCESS)
2115
2025
advance_cursor= true;
2117
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2120
2029
int HailDBCursor::delete_all_rows(void)
2122
2031
/* I *think* ib_truncate is non-transactional....
2123
2032
so only support TRUNCATE and not DELETE FROM t;
2124
(this is what ha_innodb does)
2033
(this is what ha_haildb does)
2126
if (getTable()->in_use->getSqlCommand() != SQLCOM_TRUNCATE)
2035
if (session_sql_command(getTable()->in_use) != SQLCOM_TRUNCATE)
2127
2036
return HA_ERR_WRONG_COMMAND;
2132
2041
ib_trx_t transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
2134
if (cursor_is_sec_index)
2136
err= ib_cursor_close(cursor);
2137
assert(err == DB_SUCCESS);
2139
err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
2141
if (err != DB_SUCCESS)
2142
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2143
cursor_is_sec_index= false;
2147
ib_cursor_attach_trx(cursor, transaction);
2043
ib_cursor_attach_trx(cursor, transaction);
2150
2045
err= ib_schema_lock_exclusive(transaction);
2151
2046
if (err != DB_SUCCESS)
2198
2093
assert(transaction != NULL);
2200
if (cursor_is_sec_index)
2202
err= ib_cursor_close(cursor);
2203
assert(err == DB_SUCCESS);
2205
err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
2206
cursor_is_sec_index= false;
2210
ib_cursor_attach_trx(cursor, transaction);
2213
if (err != DB_SUCCESS)
2214
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2095
ib_cursor_attach_trx(cursor, transaction);
2216
2097
err= ib_cursor_set_lock_mode(cursor, ib_lock_mode);
2217
2098
assert(err == DB_SUCCESS); // FIXME
2221
2102
err= ib_cursor_first(cursor);
2222
2103
if (err != DB_SUCCESS && err != DB_END_OF_INDEX)
2224
int reset_err= ib_cursor_reset(cursor);
2225
assert(reset_err == DB_SUCCESS);
2226
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2105
previous_error= ib_err_t_to_drizzle_error(err);
2106
err= ib_cursor_reset(cursor);
2107
return previous_error;
2229
2110
advance_cursor= false;
2234
int read_row_from_haildb(Session *session, unsigned char* buf, ib_crsr_t cursor, ib_tpl_t tuple, Table* table, bool has_hidden_primary_key, uint64_t *hidden_pkey, drizzled::memory::Root **blobroot)
2116
int read_row_from_haildb(unsigned char* buf, ib_crsr_t cursor, ib_tpl_t tuple, Table* table, bool has_hidden_primary_key, uint64_t *hidden_pkey, drizzled::memory::Root **blobroot)
2237
2119
ptrdiff_t row_offset= buf - table->getInsertRecord();
2239
2121
err= ib_cursor_read_row(cursor, tuple);
2241
if (err == DB_RECORD_NOT_FOUND)
2123
if (err != DB_SUCCESS) // FIXME
2242
2124
return HA_ERR_END_OF_FILE;
2243
if (err != DB_SUCCESS)
2244
return ib_err_t_to_drizzle_error(session, err);
2204
return previous_error;
2326
2206
if (advance_cursor)
2328
2207
err= ib_cursor_next(cursor);
2329
if (err != DB_SUCCESS)
2330
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2333
2209
tuple= ib_tuple_clear(tuple);
2334
ret= read_row_from_haildb(getTable()->getSession(), buf, cursor, tuple,
2210
ret= read_row_from_haildb(buf, cursor, tuple, getTable(),
2336
2211
share->has_hidden_primary_key,
2337
2212
&hidden_autoinc_pkey_position);
2511
2382
if (flag & HA_STATUS_AUTO)
2512
2383
stats.auto_increment_value= 1;
2514
if (flag & HA_STATUS_ERRKEY) {
2515
const char *err_table_name;
2516
const char *err_index_name;
2518
ib_trx_t transaction= *get_trx(getTable()->in_use);
2520
err= ib_get_duplicate_key(transaction, &err_table_name, &err_index_name);
2524
for (unsigned int i = 0; i < getTable()->getShare()->keys; i++)
2526
if (strcmp(err_index_name, getTable()->key_info[i].name) == 0)
2535
if (flag & HA_STATUS_CONST)
2537
for (unsigned int i = 0; i < getTable()->getShare()->sizeKeys(); i++)
2539
const char* index_name= getTable()->key_info[i].name;
2542
ha_rows rec_per_key;
2544
err= ib_get_index_stat_n_diff_key_vals(cursor, index_name,
2547
if (err != DB_SUCCESS)
2548
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2550
for (unsigned int j=0; j < getTable()->key_info[i].key_parts; j++)
2552
if (n_diff[j+1] == 0)
2553
rec_per_key= stats.records;
2555
rec_per_key= stats.records / n_diff[j+1];
2557
/* We import this heuristic from ha_innodb, which says
2558
that MySQL favours table scans too much over index searches,
2559
so we pretend our index selectivity is 2 times better. */
2561
rec_per_key= rec_per_key / 2;
2563
if (rec_per_key == 0)
2566
getTable()->key_info[i].rec_per_key[j]=
2567
rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
2568
(ulong) rec_per_key;
2578
2387
int HailDBCursor::doStartIndexScan(uint32_t keynr, bool)
2581
2389
ib_trx_t transaction= *get_trx(getTable()->in_use);
2583
2391
active_index= keynr;
2393
ib_cursor_attach_trx(cursor, transaction);
2585
2395
if (active_index == 0 && ! share->has_hidden_primary_key)
2587
if (cursor_is_sec_index)
2589
err= ib_cursor_close(cursor);
2590
assert(err == DB_SUCCESS);
2592
err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
2594
if (err != DB_SUCCESS)
2595
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2600
ib_cursor_attach_trx(cursor, transaction);
2603
cursor_is_sec_index= false;
2604
2397
tuple= ib_clust_read_tuple_create(cursor);
2608
2402
ib_id_t index_id;
2609
2403
err= ib_index_get_id(table_path_to_haildb_name(getShare()->getPath()),
2610
2404
getShare()->getKeyInfo(keynr).name,
2612
2406
if (err != DB_SUCCESS)
2613
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2615
2409
err= ib_cursor_close(cursor);
2616
2410
assert(err == DB_SUCCESS);
2618
2411
err= ib_cursor_open_index_using_id(index_id, transaction, &cursor);
2620
2413
if (err != DB_SUCCESS)
2621
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2623
cursor_is_sec_index= true;
2625
2416
tuple= ib_clust_read_tuple_create(cursor);
2626
2417
ib_cursor_set_cluster_access(cursor);
2629
err= ib_cursor_set_lock_mode(cursor, ib_lock_mode);
2420
ib_err_t err= ib_cursor_set_lock_mode(cursor, ib_lock_mode);
2630
2421
assert(err == DB_SUCCESS);
2632
2423
advance_cursor= false;
2772
2563
if (err != DB_SUCCESS)
2774
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2565
return ib_err_t_to_drizzle_error(err);
2777
2568
tuple= ib_tuple_clear(tuple);
2778
ret= read_row_from_haildb(getTable()->getSession(), buf, cursor, tuple,
2569
ret= read_row_from_haildb(buf, cursor, tuple, getTable(),
2780
2570
share->has_hidden_primary_key,
2781
2571
&hidden_autoinc_pkey_position,
2782
2572
(allocate_blobs)? &blobroot : NULL);
2903
2683
if (err == DB_END_OF_INDEX)
2904
2684
return HA_ERR_END_OF_FILE;
2906
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2910
2690
tuple= ib_tuple_clear(tuple);
2911
ret= read_row_from_haildb(getTable()->getSession(), buf, cursor, tuple,
2691
ret= read_row_from_haildb(buf, cursor, tuple, getTable(),
2913
2692
share->has_hidden_primary_key,
2914
2693
&hidden_autoinc_pkey_position);
2927
2706
err= ib_cursor_first(cursor);
2928
2707
if (err != DB_SUCCESS)
2929
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2708
return ib_err_t_to_drizzle_error(err);
2931
2710
tuple= ib_tuple_clear(tuple);
2932
ret= read_row_from_haildb(getTable()->getSession(), buf, cursor, tuple,
2711
ret= read_row_from_haildb(buf, cursor, tuple, getTable(),
2934
2712
share->has_hidden_primary_key,
2935
2713
&hidden_autoinc_pkey_position);
2948
2726
err= ib_cursor_last(cursor);
2949
2727
if (err != DB_SUCCESS)
2950
return ib_err_t_to_drizzle_error(getTable()->getSession(), err);
2728
return ib_err_t_to_drizzle_error(err);
2952
2730
tuple= ib_tuple_clear(tuple);
2953
ret= read_row_from_haildb(getTable()->getSession(), buf, cursor, tuple,
2731
ret= read_row_from_haildb(buf, cursor, tuple, getTable(),
2955
2732
share->has_hidden_primary_key,
2956
2733
&hidden_autoinc_pkey_position);
2957
2734
advance_cursor= true;