~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/cursor.cc

  • Committer: Eric Day
  • Date: 2009-10-31 21:53:33 UTC
  • mfrom: (1200 staging)
  • mto: This revision was merged to the branch mainline in revision 1202.
  • Revision ID: eday@oddments.org-20091031215333-j94bjoanwmi68p6f
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 */
19
19
 
20
20
/**
21
 
  @file handler.cc
 
21
  @file Cursor.cc
22
22
 
23
23
  Handler-calling-functions
24
24
*/
66
66
 
67
67
 
68
68
/**
69
 
  Register handler error messages for use with my_error().
 
69
  Register Cursor error messages for use with my_error().
70
70
 
71
71
  @retval
72
72
    0           OK
92
92
  SETMSG(HA_ERR_WRONG_INDEX,            "Wrong index given to function");
93
93
  SETMSG(HA_ERR_CRASHED,                ER(ER_NOT_KEYFILE));
94
94
  SETMSG(HA_ERR_WRONG_IN_RECORD,        ER(ER_CRASHED_ON_USAGE));
95
 
  SETMSG(HA_ERR_OUT_OF_MEM,             "Table handler out of memory");
 
95
  SETMSG(HA_ERR_OUT_OF_MEM,             "Table Cursor out of memory");
96
96
  SETMSG(HA_ERR_NOT_A_TABLE,            "Incorrect file format '%.64s'");
97
97
  SETMSG(HA_ERR_WRONG_COMMAND,          "Command not supported");
98
98
  SETMSG(HA_ERR_OLD_FILE,               ER(ER_OLD_KEYFILE));
134
134
 
135
135
 
136
136
/**
137
 
  Unregister handler error messages.
 
137
  Unregister Cursor error messages.
138
138
 
139
139
  @retval
140
140
    0           OK
391
391
  in it unless the engine says so. Thus, in order to be
392
392
  a part of a transaction, the engine must "register" itself.
393
393
  This is done by invoking trans_register_ha() server call.
394
 
  Normally the engine registers itself whenever handler::external_lock()
 
394
  Normally the engine registers itself whenever Cursor::external_lock()
395
395
  is called. trans_register_ha() can be invoked many times: if
396
396
  an engine is already registered, the call does nothing.
397
397
  In case autocommit is not set, the engine must register itself
402
402
  Note, that although the registration interface in itself is
403
403
  fairly clear, the current usage practice often leads to undesired
404
404
  effects. E.g. since a call to trans_register_ha() in most engines
405
 
  is embedded into implementation of handler::external_lock(), some
 
405
  is embedded into implementation of Cursor::external_lock(), some
406
406
  DDL statements start a transaction (at least from the server
407
407
  point of view) even though they are not expected to. E.g.
408
408
  CREATE TABLE does not start a transaction, since
409
 
  handler::external_lock() is never called during CREATE TABLE. But
410
 
  CREATE TABLE ... SELECT does, since handler::external_lock() is
 
409
  Cursor::external_lock() is never called during CREATE TABLE. But
 
410
  CREATE TABLE ... SELECT does, since Cursor::external_lock() is
411
411
  called for the table that is being selected from. This has no
412
412
  practical effects currently, but must be kept in mind
413
413
  nevertheless.
416
416
  of the work.
417
417
 
418
418
  During statement execution, whenever any of data-modifying
419
 
  PSEA API methods is used, e.g. handler::write_row() or
420
 
  handler::update_row(), the read-write flag is raised in the
 
419
  PSEA API methods is used, e.g. Cursor::write_row() or
 
420
  Cursor::update_row(), the read-write flag is raised in the
421
421
  statement transaction for the involved engine.
422
422
  Currently All PSEA calls are "traced", and the data can not be
423
423
  changed in a way other than issuing a PSEA call. Important:
690
690
      session->transaction.cleanup();
691
691
    }
692
692
  }
 
693
  if (error == 0)
 
694
  {
 
695
    if (is_real_trans)
 
696
    {
 
697
      /* 
 
698
        * We commit the normal transaction by finalizing the transaction message
 
699
        * and propogating the message to all registered replicators.
 
700
        */
 
701
      ReplicationServices &replication_services= ReplicationServices::singleton();
 
702
      replication_services.commitNormalTransaction(session);
 
703
    }
 
704
  }
693
705
  return error;
694
706
}
695
707
 
943
955
 
944
956
 
945
957
/****************************************************************************
946
 
** General handler functions
 
958
** General Cursor functions
947
959
****************************************************************************/
948
 
handler::~handler(void)
 
960
Cursor::~Cursor(void)
949
961
{
950
962
  assert(locked == false);
951
963
  /* TODO: assert(inited == NONE); */
952
964
}
953
965
 
954
966
 
955
 
handler *handler::clone(MEM_ROOT *mem_root)
 
967
Cursor *Cursor::clone(MEM_ROOT *mem_root)
956
968
{
957
 
  handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
 
969
  Cursor *new_handler= table->s->db_type()->getCursor(table->s, mem_root);
 
970
 
958
971
  /*
959
 
    Allocate handler->ref here because otherwise ha_open will allocate it
 
972
    Allocate Cursor->ref here because otherwise ha_open will allocate it
960
973
    on this->table->mem_root and we will not be able to reclaim that memory
961
 
    when the clone handler object is destroyed.
 
974
    when the clone Cursor object is destroyed.
962
975
  */
963
976
  if (!(new_handler->ref= (unsigned char*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
964
977
    return NULL;
970
983
  return NULL;
971
984
}
972
985
 
973
 
int handler::ha_index_init(uint32_t idx, bool sorted)
 
986
int Cursor::ha_index_init(uint32_t idx, bool sorted)
974
987
{
975
988
  int result;
976
989
  assert(inited == NONE);
980
993
  return result;
981
994
}
982
995
 
983
 
int handler::ha_index_end()
 
996
int Cursor::ha_index_end()
984
997
{
985
998
  assert(inited==INDEX);
986
999
  inited=NONE;
988
1001
  return(index_end());
989
1002
}
990
1003
 
991
 
int handler::ha_rnd_init(bool scan)
 
1004
int Cursor::ha_rnd_init(bool scan)
992
1005
{
993
1006
  int result;
994
1007
  assert(inited==NONE || (inited==RND && scan));
997
1010
  return result;
998
1011
}
999
1012
 
1000
 
int handler::ha_rnd_end()
 
1013
int Cursor::ha_rnd_end()
1001
1014
{
1002
1015
  assert(inited==RND);
1003
1016
  inited=NONE;
1004
1017
  return(rnd_end());
1005
1018
}
1006
1019
 
1007
 
int handler::ha_index_or_rnd_end()
 
1020
int Cursor::ha_index_or_rnd_end()
1008
1021
{
1009
1022
  return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
1010
1023
}
1011
1024
 
1012
 
handler::Table_flags handler::ha_table_flags() const
 
1025
Cursor::Table_flags Cursor::ha_table_flags() const
1013
1026
{
1014
1027
  return cached_table_flags;
1015
1028
}
1016
1029
 
1017
 
void handler::ha_start_bulk_insert(ha_rows rows)
 
1030
void Cursor::ha_start_bulk_insert(ha_rows rows)
1018
1031
{
1019
1032
  estimation_rows_to_insert= rows;
1020
1033
  start_bulk_insert(rows);
1021
1034
}
1022
1035
 
1023
 
int handler::ha_end_bulk_insert()
 
1036
int Cursor::ha_end_bulk_insert()
1024
1037
{
1025
1038
  estimation_rows_to_insert= 0;
1026
1039
  return end_bulk_insert();
1027
1040
}
1028
1041
 
1029
 
void handler::change_table_ptr(Table *table_arg, TableShare *share)
 
1042
void Cursor::change_table_ptr(Table *table_arg, TableShare *share)
1030
1043
{
1031
1044
  table= table_arg;
1032
1045
  table_share= share;
1033
1046
}
1034
1047
 
1035
 
const key_map *handler::keys_to_use_for_scanning()
 
1048
const key_map *Cursor::keys_to_use_for_scanning()
1036
1049
{
1037
1050
  return &key_map_empty;
1038
1051
}
1039
1052
 
1040
 
bool handler::has_transactions()
 
1053
bool Cursor::has_transactions()
1041
1054
{
1042
1055
  return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0;
1043
1056
}
1044
1057
 
1045
 
void handler::ha_statistic_increment(ulong SSV::*offset) const
 
1058
void Cursor::ha_statistic_increment(ulong SSV::*offset) const
1046
1059
{
1047
1060
  status_var_increment(table->in_use->status_var.*offset);
1048
1061
}
1049
1062
 
1050
 
void **handler::ha_data(Session *session) const
 
1063
void **Cursor::ha_data(Session *session) const
1051
1064
{
1052
1065
  return session_ha_data(session, engine);
1053
1066
}
1054
1067
 
1055
 
Session *handler::ha_session(void) const
 
1068
Session *Cursor::ha_session(void) const
1056
1069
{
1057
1070
  assert(!table || !table->in_use || table->in_use == current_session);
1058
1071
  return (table && table->in_use) ? table->in_use : current_session;
1059
1072
}
1060
1073
 
1061
1074
 
1062
 
bool handler::is_fatal_error(int error, uint32_t flags)
 
1075
bool Cursor::is_fatal_error(int error, uint32_t flags)
1063
1076
{
1064
1077
  if (!error ||
1065
1078
      ((flags & HA_CHECK_DUP_KEY) &&
1070
1083
}
1071
1084
 
1072
1085
 
1073
 
ha_rows handler::records() { return stats.records; }
 
1086
ha_rows Cursor::records() { return stats.records; }
1074
1087
 
1075
1088
/**
1076
 
  Open database-handler.
 
1089
  Open database-Cursor.
1077
1090
 
1078
1091
  Try O_RDONLY if cannot open as O_RDWR
1079
1092
  Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
1080
1093
*/
1081
 
int handler::ha_open(Table *table_arg, const char *name, int mode,
 
1094
int Cursor::ha_open(Table *table_arg, const char *name, int mode,
1082
1095
                     int test_if_locked)
1083
1096
{
1084
1097
  int error;
1106
1119
      table->db_stat|=HA_READ_ONLY;
1107
1120
    (void) extra(HA_EXTRA_NO_READCHECK);        // Not needed in SQL
1108
1121
 
1109
 
    /* ref is already allocated for us if we're called from handler::clone() */
 
1122
    /* ref is already allocated for us if we're called from Cursor::clone() */
1110
1123
    if (!ref && !(ref= (unsigned char*) alloc_root(&table->mem_root,
1111
1124
                                          ALIGN_SIZE(ref_length)*2)))
1112
1125
    {
1127
1140
  handlers for random position
1128
1141
*/
1129
1142
 
1130
 
int handler::rnd_pos_by_record(unsigned char *record)
 
1143
int Cursor::rnd_pos_by_record(unsigned char *record)
1131
1144
{
1132
1145
  register int error;
1133
1146
 
1146
1159
  This is never called for InnoDB tables, as these table types
1147
1160
  has the HA_STATS_RECORDS_IS_EXACT set.
1148
1161
*/
1149
 
int handler::read_first_row(unsigned char * buf, uint32_t primary_key)
 
1162
int Cursor::read_first_row(unsigned char * buf, uint32_t primary_key)
1150
1163
{
1151
1164
  register int error;
1152
1165
 
1198
1211
}
1199
1212
 
1200
1213
 
1201
 
void handler::adjust_next_insert_id_after_explicit_value(uint64_t nr)
 
1214
void Cursor::adjust_next_insert_id_after_explicit_value(uint64_t nr)
1202
1215
{
1203
1216
  /*
1204
1217
    If we have set Session::next_insert_id previously and plan to insert an
1272
1285
    reserved for us.
1273
1286
 
1274
1287
  - In both cases, for the following rows we use those reserved values without
1275
 
    calling the handler again (we just progress in the interval, computing
 
1288
    calling the Cursor again (we just progress in the interval, computing
1276
1289
    each new value from the previous one). Until we have exhausted them, then
1277
1290
    we either take the next provided interval or call get_auto_increment()
1278
1291
    again to reserve a new interval.
1319
1332
#define AUTO_INC_DEFAULT_NB_MAX_BITS 16
1320
1333
#define AUTO_INC_DEFAULT_NB_MAX ((1 << AUTO_INC_DEFAULT_NB_MAX_BITS) - 1)
1321
1334
 
1322
 
int handler::update_auto_increment()
 
1335
int Cursor::update_auto_increment()
1323
1336
{
1324
1337
  uint64_t nr, nb_reserved_values;
1325
1338
  bool append= false;
1364
1377
    else
1365
1378
    {
1366
1379
      /*
1367
 
        handler::estimation_rows_to_insert was set by
1368
 
        handler::ha_start_bulk_insert(); if 0 it means "unknown".
 
1380
        Cursor::estimation_rows_to_insert was set by
 
1381
        Cursor::ha_start_bulk_insert(); if 0 it means "unknown".
1369
1382
      */
1370
1383
      uint32_t nb_already_reserved_intervals=
1371
1384
        session->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements();
1467
1480
 
1468
1481
 
1469
1482
/**
1470
 
  Reserves an interval of auto_increment values from the handler.
 
1483
  Reserves an interval of auto_increment values from the Cursor.
1471
1484
 
1472
1485
  offset and increment means that we want values to be of the form
1473
1486
  offset + N * increment, where N>=0 is integer.
1478
1491
  @param offset
1479
1492
  @param increment
1480
1493
  @param nb_desired_values   how many values we want
1481
 
  @param first_value         (OUT) the first value reserved by the handler
1482
 
  @param nb_reserved_values  (OUT) how many values the handler reserved
 
1494
  @param first_value         (OUT) the first value reserved by the Cursor
 
1495
  @param nb_reserved_values  (OUT) how many values the Cursor reserved
1483
1496
*/
1484
 
void handler::get_auto_increment(uint64_t ,
 
1497
void Cursor::get_auto_increment(uint64_t ,
1485
1498
                                 uint64_t ,
1486
1499
                                 uint64_t ,
1487
1500
                                 uint64_t *first_value,
1498
1511
    error=index_last(table->record[1]);
1499
1512
    /*
1500
1513
      MySQL implicitely assumes such method does locking (as MySQL decides to
1501
 
      use nr+increment without checking again with the handler, in
1502
 
      handler::update_auto_increment()), so reserves to infinite.
 
1514
      use nr+increment without checking again with the Cursor, in
 
1515
      Cursor::update_auto_increment()), so reserves to infinite.
1503
1516
    */
1504
1517
    *nb_reserved_values= UINT64_MAX;
1505
1518
  }
1532
1545
}
1533
1546
 
1534
1547
 
1535
 
void handler::ha_release_auto_increment()
 
1548
void Cursor::ha_release_auto_increment()
1536
1549
{
1537
1550
  release_auto_increment();
1538
1551
  insert_id_for_cur_row= 0;
1549
1562
}
1550
1563
 
1551
1564
 
1552
 
void handler::print_keydup_error(uint32_t key_nr, const char *msg)
 
1565
void Cursor::print_keydup_error(uint32_t key_nr, const char *msg)
1553
1566
{
1554
1567
  /* Write the duplicated key in the error message */
1555
1568
  char key[MAX_KEY_LENGTH];
1578
1591
 
1579
1592
 
1580
1593
/**
1581
 
  Print error that we got from handler function.
 
1594
  Print error that we got from Cursor function.
1582
1595
 
1583
1596
  @note
1584
1597
    In case of delete table it's only safe to use the following parts of
1586
1599
    - table->s->path
1587
1600
    - table->alias
1588
1601
*/
1589
 
void handler::print_error(int error, myf errflag)
 
1602
void Cursor::print_error(int error, myf errflag)
1590
1603
{
1591
 
  int textno=ER_GET_ERRNO;
 
1604
  int textno= ER_GET_ERRNO;
1592
1605
  switch (error) {
1593
1606
  case EACCES:
1594
1607
    textno=ER_OPEN_AS_READONLY;
1746
1759
    return;
1747
1760
  default:
1748
1761
    {
1749
 
      /* The error was "unknown" to this function.
1750
 
         Ask handler if it has got a message for this error */
 
1762
      /* 
 
1763
        The error was "unknown" to this function.
 
1764
        Ask Cursor if it has got a message for this error 
 
1765
      */
1751
1766
      bool temporary= false;
1752
1767
      String str;
1753
1768
      temporary= get_error_message(error, &str);
1772
1787
 
1773
1788
 
1774
1789
/**
1775
 
  Return an error message specific to this handler.
 
1790
  Return an error message specific to this Cursor.
1776
1791
 
1777
 
  @param error  error code previously returned by handler
 
1792
  @param error  error code previously returned by Cursor
1778
1793
  @param buf    pointer to String where to add error message
1779
1794
 
1780
1795
  @return
1781
1796
    Returns true if this is a temporary error
1782
1797
*/
1783
 
bool handler::get_error_message(int , String* )
 
1798
bool Cursor::get_error_message(int , String* )
1784
1799
{
1785
1800
  return false;
1786
1801
}
1787
1802
 
1788
1803
 
1789
1804
/* Code left, but Drizzle has no legacy yet (while MySQL did) */
1790
 
int handler::check_old_types()
 
1805
int Cursor::check_old_types()
1791
1806
{
1792
1807
  return 0;
1793
1808
}
1796
1811
  @return
1797
1812
    key if error because of duplicated keys
1798
1813
*/
1799
 
uint32_t handler::get_dup_key(int error)
 
1814
uint32_t Cursor::get_dup_key(int error)
1800
1815
{
1801
1816
  table->file->errkey  = (uint32_t) -1;
1802
1817
  if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
1806
1821
  return(table->file->errkey);
1807
1822
}
1808
1823
 
1809
 
void handler::drop_table(const char *)
 
1824
void Cursor::drop_table(const char *)
1810
1825
{
1811
1826
  close();
1812
1827
}
1827
1842
  @retval
1828
1843
    HA_ADMIN_NOT_IMPLEMENTED
1829
1844
*/
1830
 
int handler::ha_check(Session *, HA_CHECK_OPT *)
 
1845
int Cursor::ha_check(Session *, HA_CHECK_OPT *)
1831
1846
{
1832
1847
  return HA_ADMIN_OK;
1833
1848
}
1839
1854
 
1840
1855
inline
1841
1856
void
1842
 
handler::mark_trx_read_write()
 
1857
Cursor::mark_trx_read_write()
1843
1858
{
1844
1859
  Ha_trx_info *ha_info= &ha_session()->ha_data[engine->getSlot()].ha_info[0];
1845
1860
  /*
1859
1874
/**
1860
1875
  Bulk update row: public interface.
1861
1876
 
1862
 
  @sa handler::bulk_update_row()
 
1877
  @sa Cursor::bulk_update_row()
1863
1878
*/
1864
1879
 
1865
1880
int
1866
 
handler::ha_bulk_update_row(const unsigned char *old_data, unsigned char *new_data,
 
1881
Cursor::ha_bulk_update_row(const unsigned char *old_data, unsigned char *new_data,
1867
1882
                            uint32_t *dup_key_found)
1868
1883
{
1869
1884
  mark_trx_read_write();
1875
1890
/**
1876
1891
  Delete all rows: public interface.
1877
1892
 
1878
 
  @sa handler::delete_all_rows()
 
1893
  @sa Cursor::delete_all_rows()
1879
1894
*/
1880
1895
 
1881
1896
int
1882
 
handler::ha_delete_all_rows()
 
1897
Cursor::ha_delete_all_rows()
1883
1898
{
1884
1899
  mark_trx_read_write();
1885
1900
 
1890
1905
/**
1891
1906
  Reset auto increment: public interface.
1892
1907
 
1893
 
  @sa handler::reset_auto_increment()
 
1908
  @sa Cursor::reset_auto_increment()
1894
1909
*/
1895
1910
 
1896
1911
int
1897
 
handler::ha_reset_auto_increment(uint64_t value)
 
1912
Cursor::ha_reset_auto_increment(uint64_t value)
1898
1913
{
1899
1914
  mark_trx_read_write();
1900
1915
 
1905
1920
/**
1906
1921
  Optimize table: public interface.
1907
1922
 
1908
 
  @sa handler::optimize()
 
1923
  @sa Cursor::optimize()
1909
1924
*/
1910
1925
 
1911
1926
int
1912
 
handler::ha_optimize(Session* session, HA_CHECK_OPT* check_opt)
 
1927
Cursor::ha_optimize(Session* session, HA_CHECK_OPT* check_opt)
1913
1928
{
1914
1929
  mark_trx_read_write();
1915
1930
 
1920
1935
/**
1921
1936
  Analyze table: public interface.
1922
1937
 
1923
 
  @sa handler::analyze()
 
1938
  @sa Cursor::analyze()
1924
1939
*/
1925
1940
 
1926
1941
int
1927
 
handler::ha_analyze(Session* session, HA_CHECK_OPT* check_opt)
 
1942
Cursor::ha_analyze(Session* session, HA_CHECK_OPT* check_opt)
1928
1943
{
1929
1944
  mark_trx_read_write();
1930
1945
 
1934
1949
/**
1935
1950
  Disable indexes: public interface.
1936
1951
 
1937
 
  @sa handler::disable_indexes()
 
1952
  @sa Cursor::disable_indexes()
1938
1953
*/
1939
1954
 
1940
1955
int
1941
 
handler::ha_disable_indexes(uint32_t mode)
 
1956
Cursor::ha_disable_indexes(uint32_t mode)
1942
1957
{
1943
1958
  mark_trx_read_write();
1944
1959
 
1949
1964
/**
1950
1965
  Enable indexes: public interface.
1951
1966
 
1952
 
  @sa handler::enable_indexes()
 
1967
  @sa Cursor::enable_indexes()
1953
1968
*/
1954
1969
 
1955
1970
int
1956
 
handler::ha_enable_indexes(uint32_t mode)
 
1971
Cursor::ha_enable_indexes(uint32_t mode)
1957
1972
{
1958
1973
  mark_trx_read_write();
1959
1974
 
1964
1979
/**
1965
1980
  Discard or import tablespace: public interface.
1966
1981
 
1967
 
  @sa handler::discard_or_import_tablespace()
 
1982
  @sa Cursor::discard_or_import_tablespace()
1968
1983
*/
1969
1984
 
1970
1985
int
1971
 
handler::ha_discard_or_import_tablespace(bool discard)
 
1986
Cursor::ha_discard_or_import_tablespace(bool discard)
1972
1987
{
1973
1988
  mark_trx_read_write();
1974
1989
 
1978
1993
/**
1979
1994
  Drop table in the engine: public interface.
1980
1995
 
1981
 
  @sa handler::drop_table()
 
1996
  @sa Cursor::drop_table()
1982
1997
*/
1983
1998
 
1984
1999
void
1985
 
handler::closeMarkForDelete(const char *name)
 
2000
Cursor::closeMarkForDelete(const char *name)
1986
2001
{
1987
2002
  mark_trx_read_write();
1988
2003
 
1991
2006
 
1992
2007
/**
1993
2008
  Tell the storage engine that it is allowed to "disable transaction" in the
1994
 
  handler. It is a hint that ACID is not required - it is used in NDB for
 
2009
  Cursor. It is a hint that ACID is not required - it is used in NDB for
1995
2010
  ALTER Table, for example, when data are copied to temporary table.
1996
2011
  A storage engine may treat this hint any way it likes. NDB for example
1997
2012
  starts to commit every now and then automatically.
2017
2032
  return error;
2018
2033
}
2019
2034
 
2020
 
int handler::index_next_same(unsigned char *buf, const unsigned char *key, uint32_t keylen)
 
2035
int Cursor::index_next_same(unsigned char *buf, const unsigned char *key, uint32_t keylen)
2021
2036
{
2022
2037
  int error;
2023
2038
  if (!(error=index_next(buf)))
2024
2039
  {
2025
 
    my_ptrdiff_t ptrdiff= buf - table->record[0];
 
2040
    ptrdiff_t ptrdiff= buf - table->record[0];
2026
2041
    unsigned char *save_record_0= NULL;
2027
2042
    KEY *key_info= NULL;
2028
2043
    KEY_PART_INFO *key_part;
2069
2084
 
2070
2085
 
2071
2086
/****************************************************************************
2072
 
** Some general functions that isn't in the handler class
 
2087
** Some general functions that isn't in the Cursor class
2073
2088
****************************************************************************/
2074
2089
 
2075
 
 
2076
 
void st_ha_check_opt::init()
2077
 
{
2078
 
  flags= 0; 
2079
 
  use_frm= false;
2080
 
}
2081
 
 
2082
2090
/**
2083
2091
  Calculate cost of 'index only' scan for given index and number of records
2084
2092
 
2088
2096
  @note
2089
2097
    It is assumed that we will read trough the whole key range and that all
2090
2098
    key blocks are half full (normally things are much better). It is also
2091
 
    assumed that each time we read the next key from the index, the handler
 
2099
    assumed that each time we read the next key from the index, the Cursor
2092
2100
    performs a random seek, thus the cost is proportional to the number of
2093
2101
    blocks read.
2094
2102
 
2095
2103
  @todo
2096
 
    Consider joining this function and handler::read_time() into one
2097
 
    handler::read_time(keynr, records, ranges, bool index_only) function.
 
2104
    Consider joining this function and Cursor::read_time() into one
 
2105
    Cursor::read_time(keynr, records, ranges, bool index_only) function.
2098
2106
 
2099
2107
  @return
2100
2108
    Estimated cost of 'index only' scan
2101
2109
*/
2102
2110
 
2103
 
double handler::index_only_read_time(uint32_t keynr, double key_records)
 
2111
double Cursor::index_only_read_time(uint32_t keynr, double key_records)
2104
2112
{
2105
2113
  uint32_t keys_per_block= (stats.block_size/2/
2106
2114
                        (table->key_info[keynr].key_length + ref_length) + 1);
2145
2153
*/
2146
2154
 
2147
2155
ha_rows
2148
 
handler::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
 
2156
Cursor::multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
2149
2157
                                     void *seq_init_param,
2150
2158
                                     uint32_t ,
2151
2159
                                     uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
2236
2244
    other Error or can't perform the requested scan
2237
2245
*/
2238
2246
 
2239
 
int handler::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t n_rows,
 
2247
int Cursor::multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t n_rows,
2240
2248
                                   uint32_t *bufsz, uint32_t *flags, COST_VECT *cost)
2241
2249
{
2242
2250
  *bufsz= 0; /* Default implementation doesn't need a buffer */
2281
2289
    also hold:
2282
2290
    The caller will guarantee that if "seq->init == mrr_ranges_array_init"
2283
2291
    then seq_init_param is an array of n_ranges KEY_MULTI_RANGE structures.
2284
 
    This property will only be used by NDB handler until WL#2623 is done.
 
2292
    This property will only be used by NDB Cursor until WL#2623 is done.
2285
2293
 
2286
2294
    Buffer memory management is done according to the following scenario:
2287
2295
    The caller allocates the buffer and provides it to the callee by filling
2297
2305
*/
2298
2306
 
2299
2307
int
2300
 
handler::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
 
2308
Cursor::multi_range_read_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
2301
2309
                               uint32_t n_ranges, uint32_t mode,
2302
2310
                               HANDLER_BUFFER *)
2303
2311
{
2322
2330
  @retval other  Error code
2323
2331
*/
2324
2332
 
2325
 
int handler::multi_range_read_next(char **range_info)
 
2333
int Cursor::multi_range_read_next(char **range_info)
2326
2334
{
2327
2335
  int result= 0;
2328
2336
  int range_res= 0;
2376
2384
}
2377
2385
 
2378
2386
 
2379
 
/**
2380
 
  Get cost of reading nrows table records in a "disk sweep"
2381
 
 
2382
 
  A disk sweep read is a sequence of handler->rnd_pos(rowid) calls that made
2383
 
  for an ordered sequence of rowids.
2384
 
 
2385
 
  We assume hard disk IO. The read is performed as follows:
2386
 
 
2387
 
   1. The disk head is moved to the needed cylinder
2388
 
   2. The controller waits for the plate to rotate
2389
 
   3. The data is transferred
2390
 
 
2391
 
  Time to do #3 is insignificant compared to #2+#1.
2392
 
 
2393
 
  Time to move the disk head is proportional to head travel distance.
2394
 
 
2395
 
  Time to wait for the plate to rotate depends on whether the disk head
2396
 
  was moved or not.
2397
 
 
2398
 
  If disk head wasn't moved, the wait time is proportional to distance
2399
 
  between the previous block and the block we're reading.
2400
 
 
2401
 
  If the head was moved, we don't know how much we'll need to wait for the
2402
 
  plate to rotate. We assume the wait time to be a variate with a mean of
2403
 
  0.5 of full rotation time.
2404
 
 
2405
 
  Our cost units are "random disk seeks". The cost of random disk seek is
2406
 
  actually not a constant, it depends one range of cylinders we're going
2407
 
  to access. We make it constant by introducing a fuzzy concept of "typical
2408
 
  datafile length" (it's fuzzy as it's hard to tell whether it should
2409
 
  include index file, temp.tables etc). Then random seek cost is:
2410
 
 
2411
 
    1 = half_rotation_cost + move_cost * 1/3 * typical_data_file_length
2412
 
 
2413
 
  We define half_rotation_cost as DISK_SEEK_BASE_COST=0.9.
2414
 
 
2415
 
  @param table             Table to be accessed
2416
 
  @param nrows             Number of rows to retrieve
2417
 
  @param interrupted       true <=> Assume that the disk sweep will be
2418
 
                           interrupted by other disk IO. false - otherwise.
2419
 
  @param cost         OUT  The cost.
2420
 
*/
2421
 
 
2422
 
void get_sweep_read_cost(Table *table, ha_rows nrows, bool interrupted,
2423
 
                         COST_VECT *cost)
2424
 
{
2425
 
  cost->zero();
2426
 
  if (table->file->primary_key_is_clustered())
2427
 
  {
2428
 
    cost->io_count= table->file->read_time(table->s->primary_key,
2429
 
                                           (uint32_t) nrows, nrows);
2430
 
  }
2431
 
  else
2432
 
  {
2433
 
    double n_blocks=
2434
 
      ceil(uint64_t2double(table->file->stats.data_file_length) / IO_SIZE);
2435
 
    double busy_blocks=
2436
 
      n_blocks * (1.0 - pow(1.0 - 1.0/n_blocks, rows2double(nrows)));
2437
 
    if (busy_blocks < 1.0)
2438
 
      busy_blocks= 1.0;
2439
 
 
2440
 
    cost->io_count= busy_blocks;
2441
 
 
2442
 
    if (!interrupted)
2443
 
    {
2444
 
      /* Assume reading is done in one 'sweep' */
2445
 
      cost->avg_io_cost= (DISK_SEEK_BASE_COST +
2446
 
                          DISK_SEEK_PROP_COST*n_blocks/busy_blocks);
2447
 
    }
2448
 
  }
2449
 
}
2450
 
 
2451
 
 
2452
2387
/* **************************************************************************
2453
2388
 * DS-MRR implementation ends
2454
2389
 ***************************************************************************/
2471
2406
  @retval
2472
2407
    \#                  Error code
2473
2408
*/
2474
 
int handler::read_range_first(const key_range *start_key,
2475
 
                              const key_range *end_key,
2476
 
                              bool eq_range_arg,
2477
 
                              bool )
 
2409
int Cursor::read_range_first(const key_range *start_key,
 
2410
                             const key_range *end_key,
 
2411
                             bool eq_range_arg,
 
2412
                             bool )
2478
2413
{
2479
2414
  int result;
2480
2415
 
2518
2453
  @retval
2519
2454
    \#                  Error code
2520
2455
*/
2521
 
int handler::read_range_next()
 
2456
int Cursor::read_range_next()
2522
2457
{
2523
2458
  int result;
2524
2459
 
2551
2486
    - -1  : Key is less than range
2552
2487
    - 1   : Key is larger than range
2553
2488
*/
2554
 
int handler::compare_key(key_range *range)
 
2489
int Cursor::compare_key(key_range *range)
2555
2490
{
2556
2491
  int cmp;
2557
2492
  if (!range || in_range_check_pushed_down)
2568
2503
  This is used by index condition pushdown implementation.
2569
2504
*/
2570
2505
 
2571
 
int handler::compare_key2(key_range *range)
 
2506
int Cursor::compare_key2(key_range *range)
2572
2507
{
2573
2508
  int cmp;
2574
2509
  if (!range)
2579
2514
  return cmp;
2580
2515
}
2581
2516
 
2582
 
int handler::index_read_idx_map(unsigned char * buf, uint32_t index,
 
2517
int Cursor::index_read_idx_map(unsigned char * buf, uint32_t index,
2583
2518
                                const unsigned char * key,
2584
2519
                                key_part_map keypart_map,
2585
2520
                                enum ha_rkey_function find_flag)
2598
2533
  Check if the conditions for row-based binlogging is correct for the table.
2599
2534
 
2600
2535
  A row in the given table should be replicated if:
2601
 
  - Row-based replication is enabled in the current thread
2602
 
  - The binlog is enabled
2603
2536
  - It is not a temporary table
2604
 
  - The binary log is open
2605
 
  - The database the table resides in shall be binlogged (binlog_*_db rules)
2606
 
  - table is not mysql.event
2607
2537
*/
2608
2538
 
2609
2539
static bool log_row_for_replication(Table* table,
2610
 
                           const unsigned char *before_record,
2611
 
                           const unsigned char *after_record)
 
2540
                                    const unsigned char *before_record,
 
2541
                                    const unsigned char *after_record)
2612
2542
{
2613
2543
  ReplicationServices &replication_services= ReplicationServices::singleton();
2614
2544
  Session *const session= table->in_use;
2615
2545
 
 
2546
  if (table->s->tmp_table || ! replication_services.isActive())
 
2547
    return false;
 
2548
 
2616
2549
  switch (session->lex->sql_command)
2617
2550
  {
2618
2551
  case SQLCOM_REPLACE:
 
2552
  case SQLCOM_REPLACE_SELECT:
 
2553
    /*
 
2554
     * This is a total hack because of the code that is
 
2555
     * in write_record() in sql_insert.cc. During
 
2556
     * a REPLACE statement, a call to ha_write_row() is
 
2557
     * called.  If it fails, then a call to ha_delete_row()
 
2558
     * is called, followed by a repeat of the original
 
2559
     * call to ha_write_row().  So, log_row_for_replication
 
2560
     * could be called either once or twice for a REPLACE
 
2561
     * statement.  The below looks at the values of before_record
 
2562
     * and after_record to determine which call to this
 
2563
     * function is for the delete or the insert, since NULL
 
2564
     * is passed for after_record for the delete and NULL is
 
2565
     * passed for before_record for the insert...
 
2566
     *
 
2567
     * In addition, there is an optimization that allows an
 
2568
     * engine to convert the above delete + insert into an
 
2569
     * update, so we must also check for this case below...
 
2570
     */
 
2571
    if (after_record == NULL)
 
2572
    {
 
2573
      replication_services.deleteRecord(session, table);
 
2574
      /* 
 
2575
       * We set the "current" statement message to NULL.  This triggers
 
2576
       * the replication services component to generate a new statement
 
2577
       * message for the inserted record which will come next.
 
2578
       */
 
2579
      replication_services.finalizeStatement(*session->getStatementMessage(), session);
 
2580
    }
 
2581
    else
 
2582
    {
 
2583
      if (before_record == NULL)
 
2584
        replication_services.insertRecord(session, table);
 
2585
      else
 
2586
        replication_services.updateRecord(session, table, before_record, after_record);
 
2587
    }
 
2588
    break;
2619
2589
  case SQLCOM_INSERT:
2620
 
  case SQLCOM_REPLACE_SELECT:
2621
2590
  case SQLCOM_INSERT_SELECT:
2622
 
  case SQLCOM_CREATE_TABLE:
2623
 
    replication_services.insertRecord(session, table);
 
2591
    /*
 
2592
     * The else block below represents an 
 
2593
     * INSERT ... ON DUPLICATE KEY UPDATE that
 
2594
     * has hit a key conflict and actually done
 
2595
     * an update.
 
2596
     */
 
2597
    if (before_record == NULL)
 
2598
      replication_services.insertRecord(session, table);
 
2599
    else
 
2600
      replication_services.updateRecord(session, table, before_record, after_record);
2624
2601
    break;
2625
2602
 
2626
2603
  case SQLCOM_UPDATE:
2630
2607
  case SQLCOM_DELETE:
2631
2608
    replication_services.deleteRecord(session, table);
2632
2609
    break;
2633
 
 
2634
 
    /*
2635
 
      For everything else we ignore the event (since it just involves a temp table)
2636
 
    */
2637
2610
  default:
2638
2611
    break;
2639
2612
  }
2640
2613
 
2641
 
  return false; //error;
 
2614
  return false;
2642
2615
}
2643
2616
 
2644
 
int handler::ha_external_lock(Session *session, int lock_type)
 
2617
int Cursor::ha_external_lock(Session *session, int lock_type)
2645
2618
{
2646
2619
  /*
2647
2620
    Whether this is lock or unlock, this should be true, and is to verify that
2664
2637
 
2665
2638
 
2666
2639
/**
2667
 
  Check handler usage and reset state of file to after 'open'
 
2640
  Check Cursor usage and reset state of file to after 'open'
2668
2641
*/
2669
 
int handler::ha_reset()
 
2642
int Cursor::ha_reset()
2670
2643
{
2671
2644
  /* Check that we have called all proper deallocation functions */
2672
2645
  assert((unsigned char*) table->def_read_set.getBitmap() +
2684
2657
}
2685
2658
 
2686
2659
 
2687
 
int handler::ha_write_row(unsigned char *buf)
 
2660
int Cursor::ha_write_row(unsigned char *buf)
2688
2661
{
2689
2662
  int error;
2690
2663
 
2692
2665
   * If we have a timestamp column, update it to the current time 
2693
2666
   * 
2694
2667
   * @TODO Technically, the below two lines can be take even further out of the
2695
 
   * handler interface and into the fill_record() method.
 
2668
   * Cursor interface and into the fill_record() method.
2696
2669
   */
2697
2670
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
2698
2671
    table->timestamp_field->set_time();
2704
2677
    return error;
2705
2678
  }
2706
2679
 
2707
 
  if (unlikely(log_row_for_replication(table, 0, buf)))
 
2680
  if (unlikely(log_row_for_replication(table, NULL, buf)))
2708
2681
    return HA_ERR_RBR_LOGGING_FAILED;
2709
2682
 
2710
2683
  return 0;
2711
2684
}
2712
2685
 
2713
2686
 
2714
 
int handler::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
 
2687
int Cursor::ha_update_row(const unsigned char *old_data, unsigned char *new_data)
2715
2688
{
2716
2689
  int error;
2717
2690
 
2734
2707
  return 0;
2735
2708
}
2736
2709
 
2737
 
int handler::ha_delete_row(const unsigned char *buf)
 
2710
int Cursor::ha_delete_row(const unsigned char *buf)
2738
2711
{
2739
2712
  int error;
2740
2713
 
2743
2716
  if (unlikely(error= delete_row(buf)))
2744
2717
    return error;
2745
2718
 
2746
 
  if (unlikely(log_row_for_replication(table, buf, 0)))
 
2719
  if (unlikely(log_row_for_replication(table, buf, NULL)))
2747
2720
    return HA_ERR_RBR_LOGGING_FAILED;
2748
2721
 
2749
2722
  return 0;