~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to plugin/haildb/haildb_engine.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-12-21 16:39:40 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20101221163940-c1pfo1jjvx7909xq
Tags: 2010.12.06-0ubuntu1
* New upstream release.
* Added libaio-dev build depend for InnoDB.
* Removed libpcre patch - applied upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
/*****************************************************************************
23
23
 
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.
26
26
 
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
/***********************************************************************
47
47
 
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.
50
50
 
51
51
Portions of this file contain modifications contributed and copyrighted
52
52
by Percona Inc.. Those modifications are
76
76
#include <drizzled/error.h>
77
77
#include "drizzled/internal/my_pthread.h"
78
78
#include <drizzled/plugin/transactional_storage_engine.h>
 
79
#include <drizzled/plugin/error_message.h>
79
80
 
80
81
#include <fcntl.h>
 
82
#include <stdarg.h>
81
83
 
82
84
#include <string>
83
85
#include <boost/algorithm/string.hpp>
352
354
  isolation_level= tx_isolation_to_ib_trx_level((enum_tx_isolation)session_tx_isolation(session));
353
355
  *transaction= ib_trx_begin(isolation_level);
354
356
 
355
 
  return 0;
 
357
  return *transaction == NULL;
356
358
}
357
359
 
358
360
void HailDBEngine::doStartStatement(Session *session)
488
490
    nr++;
489
491
  }
490
492
  ib_tuple_delete(tuple);
 
493
  tuple= NULL;
491
494
  err= ib_cursor_reset(cursor);
492
495
  assert(err == DB_SUCCESS);
493
496
  return nr;
818
821
int HailDBCursor::open(const char *name, int, uint32_t)
819
822
{
820
823
  const char* haildb_table_name= table_path_to_haildb_name(name);
821
 
  ib_err_t err= ib_cursor_open_table(haildb_table_name, NULL, &cursor);
 
824
  ib_err_t err= ib_table_get_id(haildb_table_name, &table_id);
822
825
  bool has_hidden_primary_key= false;
823
826
  ib_id_t idx_id;
824
827
 
825
828
  if (err != DB_SUCCESS)
826
829
    return ib_err_t_to_drizzle_error(err);
827
830
 
 
831
  err= ib_cursor_open_table_using_id(table_id, NULL, &cursor);
 
832
  cursor_is_sec_index= false;
 
833
 
 
834
  if (err != DB_SUCCESS)
 
835
    return ib_err_t_to_drizzle_error(err);
 
836
 
828
837
  err= ib_index_get_id(haildb_table_name, "HIDDEN_PRIMARY", &idx_id);
829
838
 
830
839
  if (err == DB_SUCCESS)
1776
1785
  return("BTREE");
1777
1786
}
1778
1787
 
1779
 
static ib_err_t write_row_to_haildb_tuple(Field **fields, ib_tpl_t tuple)
 
1788
static ib_err_t write_row_to_haildb_tuple(const unsigned char* buf,
 
1789
                                          Field **fields, ib_tpl_t tuple)
1780
1790
{
1781
1791
  int colnr= 0;
1782
1792
  ib_err_t err= DB_ERROR;
 
1793
  ptrdiff_t row_offset= buf - (*fields)->getTable()->getInsertRecord();
1783
1794
 
1784
1795
  for (Field **field= fields; *field; field++, colnr++)
1785
1796
  {
 
1797
    (**field).move_field_offset(row_offset);
 
1798
 
1786
1799
    if (! (**field).isWriteSet() && (**field).is_null())
 
1800
    {
 
1801
      (**field).move_field_offset(-row_offset);
1787
1802
      continue;
 
1803
    }
1788
1804
 
1789
1805
    if ((**field).is_null())
1790
1806
    {
1791
1807
      err= ib_col_set_value(tuple, colnr, NULL, IB_SQL_NULL);
1792
1808
      assert(err == DB_SUCCESS);
 
1809
      (**field).move_field_offset(-row_offset);
1793
1810
      continue;
1794
1811
    }
1795
1812
 
1801
1818
      */
1802
1819
      String str;
1803
1820
      (**field).setReadSet();
1804
 
      (**field).val_str(&str);
 
1821
      (**field).val_str_internal(&str);
1805
1822
      err= ib_col_set_value(tuple, colnr, str.ptr(), str.length());
1806
1823
    }
1807
1824
    else if ((**field).type() == DRIZZLE_TYPE_ENUM)
1827
1844
    }
1828
1845
 
1829
1846
    assert (err == DB_SUCCESS);
 
1847
 
 
1848
    (**field).move_field_offset(-row_offset);
1830
1849
  }
1831
1850
 
1832
1851
  return err;
1875
1894
 
1876
1895
  tuple= ib_clust_read_tuple_create(cursor);
1877
1896
 
1878
 
  ib_cursor_attach_trx(cursor, transaction);
 
1897
  if (cursor_is_sec_index)
 
1898
  {
 
1899
    err= ib_cursor_close(cursor);
 
1900
    assert(err == DB_SUCCESS);
 
1901
 
 
1902
    err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
 
1903
 
 
1904
    if (err != DB_SUCCESS)
 
1905
      return ib_err_t_to_drizzle_error(err);
 
1906
 
 
1907
    cursor_is_sec_index= false;
 
1908
  }
 
1909
  else
 
1910
  {
 
1911
    ib_cursor_attach_trx(cursor, transaction);
 
1912
  }
1879
1913
 
1880
1914
  err= ib_cursor_first(cursor);
1881
1915
  if (current_session->lex->sql_command == SQLCOM_CREATE_TABLE
1934
1968
 
1935
1969
  }
1936
1970
 
1937
 
  write_row_to_haildb_tuple(getTable()->getFields(), tuple);
 
1971
  write_row_to_haildb_tuple(record, getTable()->getFields(), tuple);
1938
1972
 
1939
1973
  if (share->has_hidden_primary_key)
1940
1974
  {
1967
2001
      err= ib_cursor_first(cursor);
1968
2002
      assert(err == DB_SUCCESS || err == DB_END_OF_INDEX);
1969
2003
 
1970
 
      write_row_to_haildb_tuple(getTable()->getFields(), tuple);
 
2004
      write_row_to_haildb_tuple(record, getTable()->getFields(), tuple);
1971
2005
 
1972
2006
      err= ib_cursor_insert_row(cursor, tuple);
1973
2007
      assert(err==DB_SUCCESS); // probably be nice and process errors
1980
2014
 
1981
2015
  tuple= ib_tuple_clear(tuple);
1982
2016
  ib_tuple_delete(tuple);
 
2017
  tuple= NULL;
1983
2018
  err= ib_cursor_reset(cursor);
1984
2019
 
1985
2020
  return ret;
1986
2021
}
1987
2022
 
1988
 
int HailDBCursor::doUpdateRecord(const unsigned char *,
1989
 
                                         unsigned char *)
 
2023
int HailDBCursor::doUpdateRecord(const unsigned char *old_data,
 
2024
                                 unsigned char *new_data)
1990
2025
{
1991
2026
  ib_tpl_t update_tuple;
1992
2027
  ib_err_t err;
 
2028
  bool created_tuple= false;
1993
2029
 
1994
2030
  update_tuple= ib_clust_read_tuple_create(cursor);
1995
2031
 
 
2032
  if (tuple == NULL)
 
2033
  {
 
2034
    ib_trx_t transaction= *get_trx(getTable()->in_use);
 
2035
 
 
2036
    if (cursor_is_sec_index)
 
2037
    {
 
2038
      err= ib_cursor_close(cursor);
 
2039
      assert(err == DB_SUCCESS);
 
2040
 
 
2041
      err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
 
2042
 
 
2043
      if (err != DB_SUCCESS)
 
2044
        return ib_err_t_to_drizzle_error(err);
 
2045
      cursor_is_sec_index= false;
 
2046
    }
 
2047
    else
 
2048
    {
 
2049
      ib_cursor_attach_trx(cursor, transaction);
 
2050
    }
 
2051
 
 
2052
    store_key_value_from_haildb(getTable()->key_info + getTable()->getShare()->getPrimaryKey(),
 
2053
                                  ref, ref_length, old_data);
 
2054
 
 
2055
    ib_tpl_t search_tuple= ib_clust_search_tuple_create(cursor);
 
2056
 
 
2057
    fill_ib_search_tpl_from_drizzle_key(search_tuple,
 
2058
                                        getTable()->key_info + 0,
 
2059
                                        ref, ref_length);
 
2060
 
 
2061
    err= ib_cursor_set_lock_mode(cursor, IB_LOCK_X);
 
2062
    assert(err == DB_SUCCESS);
 
2063
 
 
2064
    int res;
 
2065
    err= ib_cursor_moveto(cursor, search_tuple, IB_CUR_GE, &res);
 
2066
    assert(err == DB_SUCCESS);
 
2067
 
 
2068
    tuple= ib_clust_read_tuple_create(cursor);
 
2069
 
 
2070
    err= ib_cursor_read_row(cursor, tuple);
 
2071
    assert(err == DB_SUCCESS);// FIXME
 
2072
 
 
2073
    created_tuple= true;
 
2074
  }
 
2075
 
1996
2076
  err= ib_tuple_copy(update_tuple, tuple);
1997
2077
  assert(err == DB_SUCCESS);
1998
2078
 
1999
 
  write_row_to_haildb_tuple(getTable()->getFields(), update_tuple);
 
2079
  write_row_to_haildb_tuple(new_data, getTable()->getFields(), update_tuple);
2000
2080
 
2001
2081
  err= ib_cursor_update_row(cursor, tuple, update_tuple);
2002
2082
 
2003
2083
  ib_tuple_delete(update_tuple);
2004
2084
 
 
2085
  if (created_tuple)
 
2086
  {
 
2087
    ib_err_t ib_err= ib_cursor_reset(cursor); //fixme check error
 
2088
    assert(ib_err == DB_SUCCESS);
 
2089
    tuple= ib_tuple_clear(tuple);
 
2090
    ib_tuple_delete(tuple);
 
2091
    tuple= NULL;
 
2092
  }
 
2093
 
2005
2094
  advance_cursor= true;
2006
2095
 
2007
 
  if (err == DB_SUCCESS)
2008
 
    return 0;
2009
 
  else if (err == DB_DUPLICATE_KEY)
2010
 
    return HA_ERR_FOUND_DUPP_KEY;
2011
 
  else
2012
 
    return -1;
 
2096
  return ib_err_t_to_drizzle_error(err);
2013
2097
}
2014
2098
 
2015
2099
int HailDBCursor::doDeleteRecord(const unsigned char *)
2016
2100
{
2017
2101
  ib_err_t err;
2018
2102
 
 
2103
  assert(ib_cursor_is_positioned(cursor) == IB_TRUE);
2019
2104
  err= ib_cursor_delete_row(cursor);
2020
 
  if (err != DB_SUCCESS)
2021
 
    return -1; // FIXME
2022
2105
 
2023
2106
  advance_cursor= true;
2024
 
  return 0;
 
2107
 
 
2108
  return ib_err_t_to_drizzle_error(err);
2025
2109
}
2026
2110
 
2027
2111
int HailDBCursor::delete_all_rows(void)
2028
2112
{
2029
2113
  /* I *think* ib_truncate is non-transactional....
2030
2114
     so only support TRUNCATE and not DELETE FROM t;
2031
 
     (this is what ha_haildb does)
 
2115
     (this is what ha_innodb does)
2032
2116
  */
2033
2117
  if (session_sql_command(getTable()->in_use) != SQLCOM_TRUNCATE)
2034
2118
    return HA_ERR_WRONG_COMMAND;
2038
2122
 
2039
2123
  ib_trx_t transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
2040
2124
 
2041
 
  ib_cursor_attach_trx(cursor, transaction);
 
2125
  if (cursor_is_sec_index)
 
2126
  {
 
2127
    err= ib_cursor_close(cursor);
 
2128
    assert(err == DB_SUCCESS);
 
2129
 
 
2130
    err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
 
2131
 
 
2132
    if (err != DB_SUCCESS)
 
2133
      return ib_err_t_to_drizzle_error(err);
 
2134
    cursor_is_sec_index= false;
 
2135
  }
 
2136
  else
 
2137
  {
 
2138
    ib_cursor_attach_trx(cursor, transaction);
 
2139
  }
2042
2140
 
2043
2141
  err= ib_schema_lock_exclusive(transaction);
2044
2142
  if (err != DB_SUCCESS)
2074
2172
  ib_schema_unlock(transaction);
2075
2173
  ib_err_t rollback_err= ib_trx_rollback(transaction);
2076
2174
  assert(rollback_err == DB_SUCCESS);
2077
 
  return err;
 
2175
  return ib_err_t_to_drizzle_error(err);
2078
2176
}
2079
2177
 
2080
2178
int HailDBCursor::doStartTableScan(bool)
2081
2179
{
2082
 
  ib_err_t err;
 
2180
  ib_err_t err= DB_SUCCESS;
2083
2181
  ib_trx_t transaction;
2084
2182
 
2085
2183
  if (in_table_scan)
2090
2188
 
2091
2189
  assert(transaction != NULL);
2092
2190
 
2093
 
  ib_cursor_attach_trx(cursor, transaction);
 
2191
  if (cursor_is_sec_index)
 
2192
  {
 
2193
    err= ib_cursor_close(cursor);
 
2194
    assert(err == DB_SUCCESS);
 
2195
 
 
2196
    err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
 
2197
    cursor_is_sec_index= false;
 
2198
  }
 
2199
  else
 
2200
  {
 
2201
    ib_cursor_attach_trx(cursor, transaction);
 
2202
  }
 
2203
 
 
2204
  if (err != DB_SUCCESS)
 
2205
    return ib_err_t_to_drizzle_error(err);
2094
2206
 
2095
2207
  err= ib_cursor_set_lock_mode(cursor, ib_lock_mode);
2096
2208
  assert(err == DB_SUCCESS); // FIXME
2118
2230
 
2119
2231
  err= ib_cursor_read_row(cursor, tuple);
2120
2232
 
2121
 
  if (err != DB_SUCCESS) // FIXME
 
2233
  if (err == DB_RECORD_NOT_FOUND)
2122
2234
    return HA_ERR_END_OF_FILE;
 
2235
  if (err != DB_SUCCESS)
 
2236
    return ib_err_t_to_drizzle_error(err);
2123
2237
 
2124
2238
  int colnr= 0;
2125
2239
 
2130
2244
  for (Field **field= table->getFields() ; *field ; field++, colnr++)
2131
2245
  {
2132
2246
    if (! (**field).isReadSet())
2133
 
      continue;
 
2247
      (**field).setReadSet(); /* Fucking broken API screws us royally. */
2134
2248
 
2135
2249
    (**field).move_field_offset(row_offset);
2136
2250
 
2140
2254
    if (length == IB_SQL_NULL)
2141
2255
    {
2142
2256
      (**field).set_null();
 
2257
      (**field).move_field_offset(-row_offset);
2143
2258
      continue;
2144
2259
    }
2145
2260
    else
2183
2298
 
2184
2299
    (**field).move_field_offset(-row_offset);
2185
2300
 
 
2301
    if (err != DB_SUCCESS)
 
2302
      return ib_err_t_to_drizzle_error(err);
2186
2303
  }
2187
2304
 
2188
2305
  if (has_hidden_primary_key)
2190
2307
    err= ib_tuple_read_u64(tuple, colnr, hidden_pkey);
2191
2308
  }
2192
2309
 
2193
 
  return 0;
 
2310
  return ib_err_t_to_drizzle_error(err);
2194
2311
}
2195
2312
 
2196
2313
int HailDBCursor::rnd_next(unsigned char *buf)
2202
2319
    return previous_error;
2203
2320
 
2204
2321
  if (advance_cursor)
 
2322
  {
2205
2323
    err= ib_cursor_next(cursor);
 
2324
    if (err != DB_SUCCESS)
 
2325
      return ib_err_t_to_drizzle_error(err);
 
2326
  }
2206
2327
 
2207
2328
  tuple= ib_tuple_clear(tuple);
2208
2329
  ret= read_row_from_haildb(buf, cursor, tuple, getTable(),
2218
2339
  ib_err_t err;
2219
2340
 
2220
2341
  ib_tuple_delete(tuple);
 
2342
  tuple= NULL;
2221
2343
  err= ib_cursor_reset(cursor);
2222
2344
  assert(err == DB_SUCCESS);
2223
2345
  in_table_scan= false;
2224
2346
  previous_error= 0;
2225
 
  return 0;
 
2347
  return ib_err_t_to_drizzle_error(err);
2226
2348
}
2227
2349
 
2228
2350
int HailDBCursor::rnd_pos(unsigned char *buf, unsigned char *pos)
2236
2358
  {
2237
2359
    err= ib_col_set_value(search_tuple, 0,
2238
2360
                          ((uint64_t*)(pos)), sizeof(uint64_t));
 
2361
    if (err != DB_SUCCESS)
 
2362
      return ib_err_t_to_drizzle_error(err);
2239
2363
  }
2240
2364
  else
2241
2365
  {
2251
2375
  }
2252
2376
 
2253
2377
  err= ib_cursor_moveto(cursor, search_tuple, IB_CUR_GE, &res);
2254
 
  assert(err == DB_SUCCESS);
 
2378
  if (err != DB_SUCCESS)
 
2379
    return ib_err_t_to_drizzle_error(err);
2255
2380
 
2256
2381
  assert(res==0);
2257
2382
  if (res != 0)
2300
2425
      }
2301
2426
 
2302
2427
      String str;
2303
 
      field->val_str(&str);
 
2428
      field->val_str_internal(&str);
2304
2429
 
2305
2430
      *ref++= (char)(str.length() & 0x000000ff);
2306
2431
      *ref++= (char)((str.length()>>8) & 0x000000ff);
2379
2504
 
2380
2505
  if (flag & HA_STATUS_AUTO)
2381
2506
    stats.auto_increment_value= 1;
 
2507
 
 
2508
  if (flag & HA_STATUS_ERRKEY) {
 
2509
    const char *err_table_name;
 
2510
    const char *err_index_name;
 
2511
 
 
2512
    ib_trx_t transaction= *get_trx(getTable()->in_use);
 
2513
 
 
2514
    err= ib_get_duplicate_key(transaction, &err_table_name, &err_index_name);
 
2515
 
 
2516
    errkey= -1;
 
2517
 
 
2518
    for (unsigned int i = 0; i < getTable()->getShare()->keys; i++)
 
2519
    {
 
2520
      if (strcmp(err_index_name, getTable()->key_info[i].name) == 0)
 
2521
      {
 
2522
        errkey= i;
 
2523
        break;
 
2524
      }
 
2525
    }
 
2526
 
 
2527
  }
 
2528
 
2382
2529
  return(0);
2383
2530
}
2384
2531
 
2385
2532
int HailDBCursor::doStartIndexScan(uint32_t keynr, bool)
2386
2533
{
 
2534
  ib_err_t err;
2387
2535
  ib_trx_t transaction= *get_trx(getTable()->in_use);
2388
2536
 
2389
2537
  active_index= keynr;
2390
2538
 
2391
 
  ib_cursor_attach_trx(cursor, transaction);
2392
 
 
2393
2539
  if (active_index == 0 && ! share->has_hidden_primary_key)
2394
2540
  {
 
2541
    if (cursor_is_sec_index)
 
2542
    {
 
2543
      err= ib_cursor_close(cursor);
 
2544
      assert(err == DB_SUCCESS);
 
2545
 
 
2546
      err= ib_cursor_open_table_using_id(table_id, transaction, &cursor);
 
2547
 
 
2548
      if (err != DB_SUCCESS)
 
2549
        return ib_err_t_to_drizzle_error(err);
 
2550
 
 
2551
    }
 
2552
    else
 
2553
    {
 
2554
      ib_cursor_attach_trx(cursor, transaction);
 
2555
    }
 
2556
 
 
2557
    cursor_is_sec_index= false;
2395
2558
    tuple= ib_clust_read_tuple_create(cursor);
2396
2559
  }
2397
2560
  else
2398
2561
  {
2399
 
    ib_err_t err;
2400
2562
    ib_id_t index_id;
2401
2563
    err= ib_index_get_id(table_path_to_haildb_name(getShare()->getPath()),
2402
2564
                         getShare()->getKeyInfo(keynr).name,
2403
2565
                         &index_id);
2404
2566
    if (err != DB_SUCCESS)
2405
 
      return -1;
 
2567
      return ib_err_t_to_drizzle_error(err);
2406
2568
 
2407
2569
    err= ib_cursor_close(cursor);
2408
2570
    assert(err == DB_SUCCESS);
 
2571
 
2409
2572
    err= ib_cursor_open_index_using_id(index_id, transaction, &cursor);
2410
2573
 
2411
2574
    if (err != DB_SUCCESS)
2412
 
      return -1;
 
2575
      return ib_err_t_to_drizzle_error(err);
 
2576
 
 
2577
    cursor_is_sec_index= true;
2413
2578
 
2414
2579
    tuple= ib_clust_read_tuple_create(cursor);
2415
2580
    ib_cursor_set_cluster_access(cursor);
2416
2581
  }
2417
2582
 
2418
 
  ib_err_t err= ib_cursor_set_lock_mode(cursor, ib_lock_mode);
 
2583
  err= ib_cursor_set_lock_mode(cursor, ib_lock_mode);
2419
2584
  assert(err == DB_SUCCESS);
2420
2585
 
2421
2586
  advance_cursor= false;
2681
2846
      if (err == DB_END_OF_INDEX)
2682
2847
        return HA_ERR_END_OF_FILE;
2683
2848
      else
2684
 
        return -1; // FIXME
 
2849
        return ib_err_t_to_drizzle_error(err);
2685
2850
    }
2686
2851
  }
2687
2852
 
2908
3073
  (void)err;
2909
3074
}
2910
3075
 
 
3076
extern "C" int haildb_errmsg_callback(ib_msg_stream_t, const char *fmt, ...);
 
3077
namespace drizzled
 
3078
{
 
3079
extern bool volatile shutdown_in_progress;
 
3080
}
 
3081
 
 
3082
extern "C" int haildb_errmsg_callback(ib_msg_stream_t, const char *fmt, ...)
 
3083
{
 
3084
  bool r= false;
 
3085
  va_list args;
 
3086
  va_start(args, fmt);
 
3087
  if (! shutdown_in_progress)
 
3088
    r= plugin::ErrorMessage::vprintf(NULL, ERRMSG_LVL_WARN, fmt, args);
 
3089
  else
 
3090
    vfprintf(stderr, fmt, args);
 
3091
  va_end(args);
 
3092
 
 
3093
  return (! r==true);
 
3094
}
2911
3095
 
2912
3096
static int haildb_init(drizzled::module::Context &context)
2913
3097
{
2936
3120
  if (err != DB_SUCCESS)
2937
3121
    goto haildb_error;
2938
3122
 
 
3123
  ib_logger_set(haildb_errmsg_callback, NULL);
2939
3124
 
2940
3125
  if (not vm["data-home-dir"].as<string>().empty())
2941
3126
  {