summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_base.h3
-rw-r--r--include/myisam.h2
-rw-r--r--myisam/mi_static.c2
-rw-r--r--mysql-test/Makefile.am1
-rw-r--r--mysql-test/r/fulltext.result6
-rw-r--r--mysql-test/r/rpl_user_variables.result34
-rw-r--r--sql/field.cc7
-rw-r--r--sql/filesort.cc9
-rw-r--r--sql/ha_berkeley.cc10
-rw-r--r--sql/ha_berkeley.h27
-rw-r--r--sql/ha_heap.cc6
-rw-r--r--sql/ha_heap.h17
-rw-r--r--sql/ha_innodb.cc32
-rw-r--r--sql/ha_innodb.h35
-rw-r--r--sql/ha_isam.h16
-rw-r--r--sql/ha_isammrg.h10
-rw-r--r--sql/ha_myisam.cc7
-rw-r--r--sql/ha_myisam.h27
-rw-r--r--sql/ha_myisammrg.h24
-rw-r--r--sql/handler.cc114
-rw-r--r--sql/handler.h260
-rw-r--r--sql/item_subselect.cc8
-rw-r--r--sql/lex.h2
-rw-r--r--sql/opt_range.cc42
-rw-r--r--sql/opt_range.h2
-rw-r--r--sql/opt_sum.cc26
-rw-r--r--sql/records.cc10
-rw-r--r--sql/sql_acl.cc28
-rw-r--r--sql/sql_cache.cc12
-rw-r--r--sql/sql_delete.cc4
-rw-r--r--sql/sql_handler.cc21
-rw-r--r--sql/sql_help.cc236
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_select.cc103
-rw-r--r--sql/sql_table.cc24
-rw-r--r--sql/sql_update.cc21
-rw-r--r--sql/sql_yacc.yy18
-rw-r--r--sql/table.cc14
38 files changed, 562 insertions, 660 deletions
diff --git a/include/my_base.h b/include/my_base.h
index f912cb4278c..0ef66ef8123 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -377,7 +377,4 @@ typedef ulong ha_rows;
#define MAX_FILE_SIZE LONGLONG_MAX
#endif
-/* Currently used for saying which interfaces a Storage Engine implements */
-#define HA_ERR_NOT_IMPLEMENTED -1
-
#endif /* _my_base_h */
diff --git a/include/myisam.h b/include/myisam.h
index c99e9a30b08..02c56115dfd 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -47,7 +47,7 @@ extern "C" {
#define MI_NAME_IEXT ".MYI"
#define MI_NAME_DEXT ".MYD"
/* Max extra space to use when sorting keys */
-#define MI_MAX_TEMP_LENGTH 256*1024L*1024L
+#define MI_MAX_TEMP_LENGTH 2*1024L*1024L*1024L
/* Possible values for myisam_block_size (must be power of 2) */
#define MI_KEY_BLOCK_LENGTH 1024 /* default key block length */
diff --git a/myisam/mi_static.c b/myisam/mi_static.c
index f7d008ffbb7..f41aeff8453 100644
--- a/myisam/mi_static.c
+++ b/myisam/mi_static.c
@@ -38,7 +38,7 @@ my_bool myisam_concurrent_insert=1;
#else
my_bool myisam_concurrent_insert=0;
#endif
-my_off_t myisam_max_extra_temp_length= MI_MAX_TEMP_LENGTH;
+my_off_t myisam_max_extra_temp_length= (my_off_t)MI_MAX_TEMP_LENGTH;
my_off_t myisam_max_temp_length= MAX_FILE_SIZE;
ulong myisam_bulk_insert_tree_size=8192*1024;
ulong myisam_data_pointer_size=4;
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index bebb84c11db..8629b18a4ad 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -78,6 +78,7 @@ SUFFIXES = .sh
-e 's!@''VERSION''@!@VERSION@!' \
-e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \
-e 's!@''MYSQL_UNIX_ADDR''@!@MYSQL_UNIX_ADDR@!' \
+ -e 's!@''MYSQL_TCP_PORT''@!@MYSQL_TCP_PORT@!' \
-e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \
-e 's!@''MYSQL_SERVER_SUFFIX''@!@MYSQL_SERVER_SUFFIX@!' \
$< > $@-t
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index d13c9a9c51c..8b5e3d84b68 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -7,8 +7,8 @@ INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),
('Full-text search in MySQL', 'implements vector space model');
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
-t1 1 a 1 a A NULL NULL NULL YES FULLTEXT
-t1 1 a 2 b A NULL NULL NULL YES FULLTEXT
+t1 1 a 1 a NULL NULL NULL NULL YES FULLTEXT
+t1 1 a 2 b NULL NULL NULL NULL YES FULLTEXT
select * from t1 where MATCH(a,b) AGAINST ("collections");
a b
Only MyISAM tables support collections
@@ -223,7 +223,7 @@ id
show keys from t2;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t2 1 tig 1 ticket A NULL NULL NULL YES BTREE
-t2 1 tix 1 inhalt A NULL NULL NULL YES FULLTEXT
+t2 1 tix 1 inhalt NULL NULL NULL NULL YES FULLTEXT
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result
index 7bb5dc163ea..ce2fb9c6f9c 100644
--- a/mysql-test/r/rpl_user_variables.result
+++ b/mysql-test/r/rpl_user_variables.result
@@ -78,32 +78,32 @@ NULL
NULL
show binlog events from 141;
Log_name Pos Event_type Server_id Orig_log_pos Info
-slave-bin.000001 141 User var 2 141 @i1=12345678901234
-slave-bin.000001 184 User var 2 184 @i2=-12345678901234
-slave-bin.000001 227 User var 2 227 @i3=0
-slave-bin.000001 270 User var 2 270 @i4=-1
+slave-bin.000001 141 User var 2 141 @`i1`=12345678901234
+slave-bin.000001 184 User var 2 184 @`i2`=-12345678901234
+slave-bin.000001 227 User var 2 227 @`i3`=0
+slave-bin.000001 270 User var 2 270 @`i4`=-1
slave-bin.000001 313 Query 1 313 use `test`; insert into t1 values (@i1), (@i2), (@i3), (@i4)
-slave-bin.000001 396 User var 2 396 @r1=12.5
-slave-bin.000001 439 User var 2 439 @r2=-12.5
+slave-bin.000001 396 User var 2 396 @`r1`=12.5
+slave-bin.000001 439 User var 2 439 @`r2`=-12.5
slave-bin.000001 482 Query 1 482 use `test`; insert into t1 values (@r1), (@r2)
-slave-bin.000001 551 User var 2 551 @s1=_latin1'This is a test' COLLATE latin1_swedish_ci
-slave-bin.000001 600 User var 2 600 @s2=_latin1'' COLLATE latin1_swedish_ci
-slave-bin.000001 635 User var 2 635 @s3=_latin1'abc'def' COLLATE latin1_swedish_ci
-slave-bin.000001 677 User var 2 677 @s4=_latin1'abc\def' COLLATE latin1_swedish_ci
-slave-bin.000001 719 User var 2 719 @s5=_latin1'abc'def' COLLATE latin1_swedish_ci
+slave-bin.000001 551 User var 2 551 @`s1`=_latin1'This is a test' COLLATE latin1_swedish_ci
+slave-bin.000001 600 User var 2 600 @`s2`=_latin1'' COLLATE latin1_swedish_ci
+slave-bin.000001 635 User var 2 635 @`s3`=_latin1'abc\'def' COLLATE latin1_swedish_ci
+slave-bin.000001 677 User var 2 677 @`s4`=_latin1'abc\\def' COLLATE latin1_swedish_ci
+slave-bin.000001 719 User var 2 719 @`s5`=_latin1'abc\'def' COLLATE latin1_swedish_ci
slave-bin.000001 761 Query 1 761 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
-slave-bin.000001 851 User var 2 851 @n1=NULL
+slave-bin.000001 851 User var 2 851 @`n1`=NULL
slave-bin.000001 877 Query 1 877 use `test`; insert into t1 values (@n1)
-slave-bin.000001 939 User var 2 939 @n2=NULL
+slave-bin.000001 939 User var 2 939 @`n2`=NULL
slave-bin.000001 965 Query 1 965 use `test`; insert into t1 values (@n2)
slave-bin.000001 1027 Query 1 1027 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
-slave-bin.000001 1115 User var 2 1115 @a=2
+slave-bin.000001 1115 User var 2 1115 @`a`=2
slave-bin.000001 1157 Query 1 1157 use `test`; insert into t1 values (@a+(@b:=@a+1))
-slave-bin.000001 1229 User var 2 1229 @q=_latin1'abc' COLLATE latin1_swedish_ci
+slave-bin.000001 1229 User var 2 1229 @`q`=_latin1'abc' COLLATE latin1_swedish_ci
slave-bin.000001 1266 Query 1 1266 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
-slave-bin.000001 1370 User var 2 1370 @a=5
+slave-bin.000001 1370 User var 2 1370 @`a`=5
slave-bin.000001 1412 Query 1 1412 use `test`; insert into t1 values (@a),(@a)
-slave-bin.000001 1478 User var 2 1478 @a=NULL
+slave-bin.000001 1478 User var 2 1478 @`a`=NULL
slave-bin.000001 1503 Query 1 1503 use `test`; insert into t1 values (@a),(@a),(@a*5)
drop table t1;
stop slave;
diff --git a/sql/field.cc b/sql/field.cc
index df9b4f84ae7..44bca1ecc3c 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -433,7 +433,7 @@ void Field::store_time(TIME *ltime,timestamp_type type)
bool Field::optimize_range(uint idx)
{
- return !test(table->file->index_flags(idx) & HA_WRONG_ASCII_ORDER);
+ return test(table->file->index_flags(idx) & HA_READ_RANGE);
}
/****************************************************************************
@@ -4242,9 +4242,8 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr)
(const uchar*) b_ptr,
field_length);
}
- return field_charset->coll->strnncoll(field_charset,
- (const uchar*) a_ptr, field_length,
- (const uchar*) b_ptr, field_length);
+ return my_strnncoll(field_charset,(const uchar*) a_ptr, field_length,
+ (const uchar*) b_ptr, field_length);
}
void Field_string::sort_string(char *to,uint length)
diff --git a/sql/filesort.cc b/sql/filesort.cc
index fc8b529712c..90129dd4d51 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -330,7 +330,7 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
{
my_free((char*) tmp, MYF(0));
tmp=0;
- }
+ }
}
DBUG_RETURN(tmp);
}
@@ -373,7 +373,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
if (sort_form->key_read) // QQ Can be removed after the reset
file->extra(HA_EXTRA_KEYREAD); // QQ is removed
next_pos=(byte*) 0; /* Find records in sequence */
- file->rnd_init();
+ file->ha_rnd_init();
file->extra_opt(HA_EXTRA_CACHE,
current_thd->variables.read_buff_size);
}
@@ -415,7 +415,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
{
DBUG_PRINT("info",("Sort killed by user"));
(void) file->extra(HA_EXTRA_NO_CACHE);
- file->rnd_end();
+ file->ha_rnd_end();
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
}
if (error == 0)
@@ -435,7 +435,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
file->unlock_row();
}
(void) file->extra(HA_EXTRA_NO_CACHE); /* End cacheing of records */
- file->rnd_end();
+ if (!next_pos)
+ file->ha_rnd_end();
DBUG_PRINT("test",("error: %d indexpos: %d",error,indexpos));
if (error != HA_ERR_END_OF_FILE)
{
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 4dde893116f..be6b1e2ce9b 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -442,7 +442,6 @@ berkeley_key_cmp(TABLE *table, KEY *key_info, const char *key, uint key_length)
return 0; // Identical keys
}
-
int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
{
char name_buff[FN_REFLEN];
@@ -1350,6 +1349,7 @@ int ha_berkeley::index_end()
error=cursor->c_close(cursor);
cursor=0;
}
+ active_index=MAX_KEY;
DBUG_RETURN(error);
}
@@ -1411,7 +1411,7 @@ int ha_berkeley::index_read_idx(byte * buf, uint keynr, const byte * key,
statistic_increment(ha_read_key_count,&LOCK_status);
DBUG_ENTER("index_read_idx");
current_row.flags=DB_DBT_REALLOC;
- active_index= (uint) -1;
+ active_index=MAX_KEY;
DBUG_RETURN(read_row(key_file[keynr]->get(key_file[keynr], transaction,
pack_key(&last_key, keynr, key_buff, key,
key_len),
@@ -1482,7 +1482,7 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
bzero((char*) &row, sizeof(row));
error= read_row(cursor->c_get(cursor, &last_key, &row, DB_PREV),
(char*) buf, active_index, &row, &last_key, 1);
- }
+ }
DBUG_RETURN(error);
}
@@ -1583,12 +1583,14 @@ int ha_berkeley::index_last(byte * buf)
int ha_berkeley::rnd_init(bool scan)
{
DBUG_ENTER("rnd_init");
+ DBUG_ASSERT(active_index==MAX_KEY);
current_row.flags=DB_DBT_REALLOC;
DBUG_RETURN(index_init(primary_key));
}
int ha_berkeley::rnd_end()
{
+ active_index= MAX_KEY;
return index_end();
}
@@ -1630,7 +1632,7 @@ int ha_berkeley::rnd_pos(byte * buf, byte *pos)
statistic_increment(ha_read_rnd_count,&LOCK_status);
DBUG_ENTER("ha_berkeley::rnd_pos");
- active_index= (uint) -1; // Don't delete via cursor
+ active_index= MAX_KEY;
DBUG_RETURN(read_row(file->get(file, transaction,
get_pos(&db_pos, pos),
&current_row, 0),
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index 4bc8e3a5777..07923f8daf0 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -87,24 +87,25 @@ class ha_berkeley: public handler
public:
ha_berkeley(TABLE *table): handler(table), alloc_ptr(0),rec_buff(0), file(0),
- int_table_flags(HA_REC_NOT_IN_SEQ |
- HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | HA_FAST_KEY_READ |
- HA_NULL_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
- HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE |
- HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX |
- HA_KEY_READ_WRONG_STR | HA_FILE_BASED),
- changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0)
- {
- }
+ int_table_flags(HA_REC_NOT_IN_SEQ | HA_FAST_KEY_READ |
+ HA_NULL_IN_KEY | HA_BLOB_KEY | HA_NOT_EXACT_COUNT |
+ HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED |
+ HA_AUTO_PART_KEY | HA_TABLE_SCAN_ON_INDEX),
+ changed_rows(0),last_dup_key((uint) -1),version(0),using_ignore(0) {}
~ha_berkeley() {}
const char *table_type() const { return "BerkeleyDB"; }
+ ulong ha_berkeley::index_flags(uint idx, uint part) const
+ {
+ ulong flags=HA_READ_NEXT | HA_READ_PREV;
+ if (part == (uint)~0 ||
+ table->key_info[idx].key_part[part].field->key_type() != HA_KEYTYPE_TEXT)
+ flags|= HA_READ_ORDER | HA_KEYREAD_ONLY | HA_READ_RANGE;
+ return flags;
+ }
const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const;
ulong table_flags(void) const { return int_table_flags; }
- uint max_record_length() const { return HA_MAX_REC_LENGTH; }
- uint max_keys() const { return MAX_KEY-1; }
- uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MAX_KEY_LENGTH; }
+ uint max_supported_keys() const { return MAX_KEY-1; }
uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
ha_rows estimate_number_of_rows();
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index c375614ac95..cc828b6e6b2 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -111,6 +111,7 @@ int ha_heap::delete_row(const byte * buf)
int ha_heap::index_read(byte * buf, const byte * key, uint key_len,
enum ha_rkey_function find_flag)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_key_count, &LOCK_status);
int error = heap_rkey(file,buf,active_index, key, key_len, find_flag);
table->status = error ? STATUS_NOT_FOUND : 0;
@@ -119,6 +120,7 @@ int ha_heap::index_read(byte * buf, const byte * key, uint key_len,
int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_key_count, &LOCK_status);
int error= heap_rkey(file, buf, active_index, key, key_len,
HA_READ_PREFIX_LAST);
@@ -137,6 +139,7 @@ int ha_heap::index_read_idx(byte * buf, uint index, const byte * key,
int ha_heap::index_next(byte * buf)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_next_count,&LOCK_status);
int error=heap_rnext(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -145,6 +148,7 @@ int ha_heap::index_next(byte * buf)
int ha_heap::index_prev(byte * buf)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_prev_count,&LOCK_status);
int error=heap_rprev(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -153,6 +157,7 @@ int ha_heap::index_prev(byte * buf)
int ha_heap::index_first(byte * buf)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_first_count,&LOCK_status);
int error=heap_rfirst(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -161,6 +166,7 @@ int ha_heap::index_first(byte * buf)
int ha_heap::index_last(byte * buf)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_last_count,&LOCK_status);
int error=heap_rlast(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index f55eda91149..0c3483c7f66 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -40,21 +40,18 @@ class ha_heap: public handler
const char **bas_ext() const;
ulong table_flags() const
{
- return (HA_READ_RND_SAME | HA_FAST_KEY_READ | HA_KEYPOS_TO_RNDPOS |
- HA_NO_BLOBS | HA_NULL_KEY | HA_REC_NOT_IN_SEQ);
+ return (HA_FAST_KEY_READ | HA_NO_BLOBS | HA_NULL_IN_KEY |
+ HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME |
+ HA_CAN_INSERT_DELAYED);
}
- ulong index_flags(uint inx) const
+ ulong index_flags(uint inx, uint part) const
{
return ((table->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ?
- (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER) :
- (HA_ONLY_WHOLE_INDEX | HA_WRONG_ASCII_ORDER |
- HA_NOT_READ_PREFIX_LAST));
+ HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE :
+ HA_ONLY_WHOLE_INDEX);
}
const key_map *keys_to_use_for_scanning() { return &btree_keys; }
- uint max_record_length() const { return HA_MAX_REC_LENGTH; }
- uint max_keys() const { return MAX_KEY; }
- uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return HA_MAX_REC_LENGTH; }
+ uint max_supported_keys() const { return MAX_KEY; }
double scan_time() { return (double) (records+deleted) / 20.0+10; }
double read_time(uint index, uint ranges, ha_rows rows)
{ return (double) rows / 20.0+1; }
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index dffffd9296e..aad0ef2d9fd 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -406,7 +406,7 @@ innobase_mysql_print_thd(
May 14, 2004 probably no race any more,
but better be safe */
}
-
+
/* Use strmake to reduce the timeframe
for a race, compared to fwrite() */
i= (uint) (strmake(buf, s, len) - buf);
@@ -1435,9 +1435,6 @@ ha_innobase::open(
last_query_id = (ulong)-1;
- active_index = 0;
- active_index_before_scan = (uint)-1; /* undefined value */
-
if (!(share=get_share(name))) {
DBUG_RETURN(1);
@@ -1581,15 +1578,6 @@ ha_innobase::open(
DBUG_RETURN(0);
}
-/*********************************************************************
-Does nothing. */
-
-void
-ha_innobase::initialize(void)
-/*=========================*/
-{
-}
-
/**********************************************************************
Closes a handle to an InnoDB table. */
@@ -2654,7 +2642,7 @@ ha_innobase::index_end(void)
{
int error = 0;
DBUG_ENTER("index_end");
-
+ active_index=MAX_KEY;
DBUG_RETURN(error);
}
@@ -3125,8 +3113,6 @@ ha_innobase::rnd_init(
/* Store the active index value so that we can restore the original
value after a scan */
- active_index_before_scan = active_index;
-
if (prebuilt->clust_index_was_generated) {
err = change_active_index(MAX_KEY);
} else {
@@ -3146,19 +3132,7 @@ ha_innobase::rnd_end(void)
/*======================*/
/* out: 0 or error number */
{
- /* Restore the old active_index back; MySQL may assume that a table
- scan does not change active_index. We only restore the value if
- MySQL has called rnd_init before: sometimes MySQL seems to call
- rnd_end WITHOUT calling rnd_init. */
-
- if (active_index_before_scan != (uint)-1) {
-
- change_active_index(active_index_before_scan);
-
- active_index_before_scan = (uint)-1;
- }
-
- return(index_end());
+ return(index_end());
}
/*********************************************************************
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index c585fd9c463..3b2f04c1679 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -61,20 +61,11 @@ class ha_innobase: public handler
ulong start_of_scan; /* this is set to 1 when we are
starting a table scan but have not
yet fetched any row, else 0 */
- uint active_index_before_scan;
- /* since a table scan in InnoDB is
- always done through an index, a table
- scan may change active_index; but
- MySQL may assume that active_index
- after a table scan is the same as
- before; we store the value here so
- that we can restore the value after
- a scan */
uint last_match_mode;/* match mode of the latest search:
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */
longlong auto_inc_counter_for_this_stat;
- ulong max_row_length(const byte *buf);
+ ulong max_supported_row_length(const byte *buf);
uint store_key_val_for_row(uint keynr, char* buff, uint buff_len,
const byte* record);
@@ -87,13 +78,10 @@ class ha_innobase: public handler
public:
ha_innobase(TABLE *table): handler(table),
int_table_flags(HA_REC_NOT_IN_SEQ |
- HA_KEYPOS_TO_RNDPOS |
- HA_LASTKEY_ORDER |
- HA_NULL_KEY | HA_FAST_KEY_READ |
- HA_BLOB_KEY |
+ HA_NULL_IN_KEY | HA_FAST_KEY_READ |
+ HA_CAN_INDEX_BLOBS |
HA_CAN_SQL_HANDLER |
HA_NOT_EXACT_COUNT |
- HA_NO_WRITE_DELAYED |
HA_PRIMARY_KEY_IN_READ_INDEX |
HA_TABLE_SCAN_ON_INDEX),
last_dup_key((uint) -1),
@@ -106,14 +94,12 @@ class ha_innobase: public handler
const char *index_type(uint key_number) { return "BTREE"; }
const char** bas_ext() const;
ulong table_flags() const { return int_table_flags; }
- ulong index_flags(uint idx) const
+ ulong index_flags(uint idx, uint part) const
{
- return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER |
- HA_KEY_READ_ONLY);
+ return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE |
+ HA_KEYREAD_ONLY);
}
- uint max_record_length() const { return HA_MAX_REC_LENGTH; }
- uint max_keys() const { return MAX_KEY; }
- uint max_key_parts() const { return MAX_REF_PARTS; }
+ uint max_supported_keys() const { return MAX_KEY; }
/* An InnoDB page must store >= 2 keys;
a secondary key record must also contain the
primary key value:
@@ -121,15 +107,12 @@ class ha_innobase: public handler
less than 1 / 4 of page size which is 16 kB;
but currently MySQL does not work with keys
whose size is > MAX_KEY_LENGTH */
- uint max_key_length() const { return((MAX_KEY_LENGTH <= 3500) ?
- MAX_KEY_LENGTH : 3500);}
- uint max_key_part_length() { return((MAX_KEY_LENGTH <= 3500) ?
- MAX_KEY_LENGTH : 3500);}
+ uint max_supported_key_length() const { return 3500; }
+ uint max_supported_key_part_length() const { return 3500; }
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
bool has_transactions() { return 1;}
int open(const char *name, int mode, uint test_if_locked);
- void initialize(void);
int close(void);
double scan_time();
double read_time(uint index, uint ranges, ha_rows rows);
diff --git a/sql/ha_isam.h b/sql/ha_isam.h
index 8a887ababde..ac7a0c52548 100644
--- a/sql/ha_isam.h
+++ b/sql/ha_isam.h
@@ -32,19 +32,20 @@ class ha_isam: public handler
public:
ha_isam(TABLE *table)
:handler(table), file(0),
- int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
- HA_KEY_READ_WRONG_STR | HA_DUPP_POS |
- HA_NOT_DELETE_WITH_CACHE | HA_FILE_BASED)
+ int_table_flags(HA_READ_RND_SAME |
+ HA_DUPP_POS | HA_NOT_DELETE_WITH_CACHE | HA_FILE_BASED)
{}
~ha_isam() {}
+ ulong index_flags(uint idx, uint part) const
+ { return HA_READ_NEXT; } // but no HA_READ_PREV here!!!
const char *table_type() const { return "ISAM"; }
const char *index_type(uint key_number) { return "BTREE"; }
const char **bas_ext() const;
ulong table_flags() const { return int_table_flags; }
- uint max_record_length() const { return HA_MAX_REC_LENGTH; }
- uint max_keys() const { return N_MAXKEY; }
- uint max_key_parts() const { return N_MAXKEY_SEG; }
- uint max_key_length() const { return N_MAX_KEY_LENGTH; }
+ uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ uint max_supported_keys() const { return N_MAXKEY; }
+ uint max_supported_key_parts() const { return N_MAXKEY_SEG; }
+ uint max_supported_key_length() const { return N_MAX_KEY_LENGTH; }
uint min_record_length(uint options) const;
bool low_byte_first() const { return 0; }
@@ -66,7 +67,6 @@ class ha_isam: public handler
int rnd_next(byte *buf);
int rnd_pos(byte * buf, byte *pos);
void position(const byte *record);
- my_off_t row_position() { return nisam_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type);
diff --git a/sql/ha_isammrg.h b/sql/ha_isammrg.h
index 289277a9dac..bf4a7c329ef 100644
--- a/sql/ha_isammrg.h
+++ b/sql/ha_isammrg.h
@@ -32,14 +32,11 @@ class ha_isammrg: public handler
~ha_isammrg() {}
const char *table_type() const { return "MRG_ISAM"; }
const char **bas_ext() const;
- ulong table_flags() const { return (HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS |
+ ulong table_flags() const { return (HA_READ_RND_SAME |
HA_REC_NOT_IN_SEQ | HA_FILE_BASED); }
- ulong index_flags(uint idx) const { return HA_NOT_READ_PREFIX_LAST; }
+ ulong index_flags(uint idx, uint part) const { DBUG_ASSERT(0); return 0; }
- uint max_record_length() const { return HA_MAX_REC_LENGTH; }
- uint max_keys() const { return 0; }
- uint max_key_parts() const { return 0; }
- uint max_key_length() const { return 0; }
+ uint max_supported_keys() const { return 0; }
bool low_byte_first() const { return 0; }
uint min_record_length(uint options) const;
@@ -60,7 +57,6 @@ class ha_isammrg: public handler
int rnd_next(byte *buf);
int rnd_pos(byte * buf, byte *pos);
void position(const byte *record);
- my_off_t row_position() { return mrg_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type);
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 318e0fbb507..0ee8979e898 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -1050,6 +1050,7 @@ int ha_myisam::delete_row(const byte * buf)
int ha_myisam::index_read(byte * buf, const byte * key,
uint key_len, enum ha_rkey_function find_flag)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_key_count,&LOCK_status);
int error=mi_rkey(file,buf,active_index, key, key_len, find_flag);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -1067,6 +1068,7 @@ int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key,
int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_key_count,&LOCK_status);
int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -1075,6 +1077,7 @@ int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len)
int ha_myisam::index_next(byte * buf)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_next_count,&LOCK_status);
int error=mi_rnext(file,buf,active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -1083,6 +1086,7 @@ int ha_myisam::index_next(byte * buf)
int ha_myisam::index_prev(byte * buf)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_prev_count,&LOCK_status);
int error=mi_rprev(file,buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -1091,6 +1095,7 @@ int ha_myisam::index_prev(byte * buf)
int ha_myisam::index_first(byte * buf)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_first_count,&LOCK_status);
int error=mi_rfirst(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -1099,6 +1104,7 @@ int ha_myisam::index_first(byte * buf)
int ha_myisam::index_last(byte * buf)
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_last_count,&LOCK_status);
int error=mi_rlast(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -1109,6 +1115,7 @@ int ha_myisam::index_next_same(byte * buf,
const byte *key __attribute__((unused)),
uint length __attribute__((unused)))
{
+ DBUG_ASSERT(inited==INDEX);
statistic_increment(ha_read_next_count,&LOCK_status);
int error=mi_rnext_same(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h
index 77887220903..9069b41364d 100644
--- a/sql/ha_myisam.h
+++ b/sql/ha_myisam.h
@@ -44,10 +44,10 @@ class ha_myisam: public handler
public:
ha_myisam(TABLE *table): handler(table), file(0),
- int_table_flags(HA_READ_RND_SAME | HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
- HA_NULL_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
- HA_DUPP_POS | HA_BLOB_KEY | HA_AUTO_PART_KEY |
- HA_FILE_BASED | HA_HAS_GEOMETRY),
+ int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
+ HA_DUPP_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
+ HA_FILE_BASED | HA_CAN_GEOMETRY | HA_READ_RND_SAME |
+ HA_CAN_INSERT_DELAYED),
can_enable_indexes(1)
{}
~ha_myisam() {}
@@ -55,17 +55,15 @@ class ha_myisam: public handler
const char *index_type(uint key_number);
const char **bas_ext() const;
ulong table_flags() const { return int_table_flags; }
- ulong index_flags(uint inx) const
+ ulong index_flags(uint inx, uint part) const
{
- ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER);
- return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
- 0 : HA_KEY_READ_ONLY));
+ return ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
+ 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY);
}
- uint max_record_length() const { return HA_MAX_REC_LENGTH; }
- uint max_keys() const { return MI_MAX_KEY; }
- uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MI_MAX_KEY_LENGTH; }
- uint max_key_part_length() { return MI_MAX_KEY_LENGTH; }
+ uint max_supported_keys() const { return MI_MAX_KEY; }
+ uint max_supported_key_length() const { return MI_MAX_KEY_LENGTH; }
+ uint max_supported_key_part_length() { return MI_MAX_KEY_LENGTH; }
uint checksum() const;
int open(const char *name, int mode, uint test_if_locked);
@@ -83,7 +81,7 @@ class ha_myisam: public handler
int index_first(byte * buf);
int index_last(byte * buf);
int index_next_same(byte *buf, const byte *key, uint keylen);
- int index_end() { ft_handler=NULL; return 0; }
+ int index_end() { ft_handler=NULL; return handler::index_end(); }
int ft_init()
{
if (!ft_handler)
@@ -99,7 +97,6 @@ class ha_myisam: public handler
int rnd_pos(byte * buf, byte *pos);
int restart_rnd_next(byte *buf, byte *pos);
void position(const byte *record);
- my_off_t row_position() { return mi_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
int extra_opt(enum ha_extra_function operation, ulong cache_size);
diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h
index fd36c78202d..9a6b2a7ee14 100644
--- a/sql/ha_myisammrg.h
+++ b/sql/ha_myisammrg.h
@@ -34,21 +34,20 @@ class ha_myisammrg: public handler
const char **bas_ext() const;
ulong table_flags() const
{
- return (HA_REC_NOT_IN_SEQ | HA_READ_RND_SAME | HA_AUTO_PART_KEY |
- HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER |
- HA_NULL_KEY | HA_BLOB_KEY | HA_FILE_BASED);
+ return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_READ_RND_SAME |
+ HA_NULL_IN_KEY | HA_CAN_INDEX_BLOBS | HA_FILE_BASED |
+ HA_CAN_INSERT_DELAYED);
}
- ulong index_flags(uint inx) const
+ ulong index_flags(uint inx, uint part) const
{
- ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER);
- return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
- 0 : HA_KEY_READ_ONLY));
+ return ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
+ 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY);
}
- uint max_record_length() const { return HA_MAX_REC_LENGTH; }
- uint max_keys() const { return MI_MAX_KEY; }
- uint max_key_parts() const { return MAX_REF_PARTS; }
- uint max_key_length() const { return MAX_KEY_LENGTH; }
- virtual double scan_time()
+ uint max_supported_keys() const { return MI_MAX_KEY; }
+ uint max_supported_key_length() const { return MI_MAX_KEY_LENGTH; }
+ uint max_supported_key_part_length() { return MI_MAX_KEY_LENGTH; }
+ double scan_time()
{ return ulonglong2double(data_file_length) / IO_SIZE + file->tables; }
int open(const char *name, int mode, uint test_if_locked);
@@ -71,7 +70,6 @@ class ha_myisammrg: public handler
int rnd_pos(byte * buf, byte *pos);
void position(const byte *record);
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
- my_off_t row_position() { return myrg_position(file); }
void info(uint);
int extra(enum ha_extra_function operation);
int extra_opt(enum ha_extra_function operation, ulong cache_size);
diff --git a/sql/handler.cc b/sql/handler.cc
index 4a2948e63f8..3b694ed0eb8 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -37,8 +37,6 @@
#endif
#ifdef HAVE_INNOBASE_DB
#include "ha_innodb.h"
-#else
-#define innobase_query_caching_of_table_permitted(X,Y,Z) 1
#endif
#ifdef HAVE_NDBCLUSTER_DB
#include "ha_ndbcluster.h"
@@ -210,6 +208,18 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
}
}
+bool ha_caching_allowed(THD* thd, char* table_key,
+ uint key_length, uint8 cache_type)
+{
+#ifdef HAVE_INNOBASE_DB
+ if (cache_type == HA_CACHE_TBL_ASKTRANSACT)
+ return innobase_query_caching_of_table_permitted(thd, table_key,
+ key_length);
+ else
+#endif
+ return 1;
+}
+
int ha_init()
{
int error= 0;
@@ -856,46 +866,6 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
DBUG_RETURN(error);
}
-int handler::check(THD* thd, HA_CHECK_OPT* check_opt)
-{
- return HA_ADMIN_NOT_IMPLEMENTED;
-}
-
-int handler::backup(THD* thd, HA_CHECK_OPT* check_opt)
-{
- return HA_ADMIN_NOT_IMPLEMENTED;
-}
-
-int handler::restore(THD* thd, HA_CHECK_OPT* check_opt)
-{
- return HA_ADMIN_NOT_IMPLEMENTED;
-}
-
-int handler::repair(THD* thd, HA_CHECK_OPT* check_opt)
-{
- return HA_ADMIN_NOT_IMPLEMENTED;
-}
-
-int handler::optimize(THD* thd, HA_CHECK_OPT* check_opt)
-{
- return HA_ADMIN_NOT_IMPLEMENTED;
-}
-
-int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt)
-{
- return HA_ADMIN_NOT_IMPLEMENTED;
-}
-
-int handler::assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
-{
- return HA_ADMIN_NOT_IMPLEMENTED;
-}
-
-int handler::preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
-{
- return HA_ADMIN_NOT_IMPLEMENTED;
-}
-
/*
Read first row (only) from a table
This is never called for InnoDB or BDB tables, as these table types
@@ -913,35 +883,23 @@ int handler::read_first_row(byte * buf, uint primary_key)
If there is very few deleted rows in the table, find the first row by
scanning the table.
*/
- if (deleted < 10 || primary_key >= MAX_KEY ||
- !(index_flags(primary_key) & HA_READ_ORDER))
+ if (deleted < 10 || primary_key >= MAX_KEY)
{
- (void) rnd_init();
+ (void) ha_rnd_init(1);
while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ;
- (void) rnd_end();
+ (void) ha_rnd_end();
}
else
{
/* Find the first row through the primary key */
- (void) index_init(primary_key);
+ (void) ha_index_init(primary_key);
error=index_first(buf);
- (void) index_end();
+ (void) ha_index_end();
}
DBUG_RETURN(error);
}
-/*
- The following function is only needed for tables that may be temporary tables
- during joins
-*/
-
-int handler::restart_rnd_next(byte *buf, byte *pos)
-{
- return HA_ERR_WRONG_COMMAND;
-}
-
-
/* Set a timestamp in record */
void handler::update_timestamp(byte *record)
@@ -1156,7 +1114,7 @@ void handler::print_error(int error, myf errflag)
bool handler::get_error_message(int error, String* buf)
{
- return false;
+ return FALSE;
}
@@ -1225,28 +1183,6 @@ int handler::index_next_same(byte *buf, const byte *key, uint keylen)
}
-/*
- This is called to delete all rows in a table
- If the handler don't support this, then this function will
- return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
- by one.
-*/
-
-int handler::delete_all_rows()
-{
- return (my_errno=HA_ERR_WRONG_COMMAND);
-}
-
-bool handler::caching_allowed(THD* thd, char* table_key,
- uint key_length, uint8 cache_type)
-{
- if (cache_type == HA_CACHE_TBL_ASKTRANSACT)
- return innobase_query_caching_of_table_permitted(thd, table_key,
- key_length);
- else
- return 1;
-}
-
/****************************************************************************
** Some general functions that isn't in the handler class
****************************************************************************/
@@ -1269,8 +1205,6 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
if (update_create_info)
{
update_create_info_from_table(create_info, &table);
- if (table.file->table_flags() & HA_DROP_BEFORE_CREATE)
- table.file->delete_table(name);
}
if (lower_case_table_names == 2 &&
!(table.file->table_flags() & HA_FILE_BASED))
@@ -1527,3 +1461,15 @@ int handler::compare_key(key_range *range)
cmp= key_compare_result_on_equal;
return cmp;
}
+
+int handler::index_read_idx(byte * buf, uint index, const byte * key,
+ uint key_len, enum ha_rkey_function find_flag)
+{
+ int error= ha_index_init(index);
+ if (!error)
+ error= index_read(buf, key, key_len, find_flag);
+ if (!error)
+ error= ha_index_end();
+ return error;
+}
+
diff --git a/sql/handler.h b/sql/handler.h
index 04a437725ab..72188d2459c 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -45,51 +45,42 @@
#define HA_ADMIN_REJECT -6
/* Bits in table_flags() to show what database can do */
-#define HA_READ_RND_SAME 1 /* Read RND-record to KEY-record
- (To update with RND-read) */
-#define HA_KEYPOS_TO_RNDPOS 2 /* ha_info gives pos to record */
-#define HA_TABLE_SCAN_ON_INDEX 4 /* No separate data/index file */
-#define HA_REC_NOT_IN_SEQ 8 /* ha_info don't return recnumber;
+#define HA_READ_RND_SAME (1 << 0) /* can switch index during the scan
+ with ::rnd_same() - not used yet.
+ see mi_rsame/heap_rsame/myrg_rsame */
+#define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */
+#define HA_REC_NOT_IN_SEQ (1 << 3) /* ha_info don't return recnumber;
It returns a position to ha_r_rnd */
-#define HA_HAS_GEOMETRY (1 << 4)
+#define HA_CAN_GEOMETRY (1 << 4)
#define HA_FAST_KEY_READ (1 << 5) /* no need for a record cache in filesort */
-#define HA_KEY_READ_WRONG_STR (1 << 6) /* keyread returns converted strings */
-#define HA_NULL_KEY (1 << 7) /* One can have keys with NULL */
-#define HA_DUPP_POS (1 << 8) /* ha_position() gives dupp row */
+#define HA_NULL_IN_KEY (1 << 7) /* One can have keys with NULL */
+#define HA_DUPP_POS (1 << 8) /* ha_position() gives dup row */
#define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */
-#define HA_BLOB_KEY (1 << 10) /* key on blob */
-#define HA_AUTO_PART_KEY (1 << 11)
-#define HA_REQUIRE_PRIMARY_KEY (1 << 12)
+#define HA_CAN_INDEX_BLOBS (1 << 10)
+#define HA_AUTO_PART_KEY (1 << 11) /* auto-increment in multi-part key */
+#define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */
#define HA_NOT_EXACT_COUNT (1 << 13)
-#define HA_NO_WRITE_DELAYED (1 << 14)
+#define HA_CAN_INSERT_DELAYED (1 << 14) /* only handlers with table-level locks
+ need no special code to support
+ INSERT DELAYED */
#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
-#define HA_DROP_BEFORE_CREATE (1 << 16)
-#define HA_NOT_READ_AFTER_KEY (1 << 17)
#define HA_NOT_DELETE_WITH_CACHE (1 << 18)
-#define HA_NO_TEMP_TABLES (1 << 19)
#define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
#define HA_CAN_FULLTEXT (1 << 21)
#define HA_CAN_SQL_HANDLER (1 << 22)
#define HA_NO_AUTO_INCREMENT (1 << 23)
#define HA_HAS_CHECKSUM (1 << 24)
-/*
- Next record gives next record according last record read (even
- if database is updated after read). Not used at this point.
-*/
-#define HA_LASTKEY_ORDER (1 << 25)
-/* Table data are stored in separate files */
+/* Table data are stored in separate files (for lower_case_table_names) */
#define HA_FILE_BASED (1 << 26)
/* bits in index_flags(index_number) for what you can do with index */
-#define HA_WRONG_ASCII_ORDER 1 /* Can't use sorting through key */
-#define HA_READ_NEXT 2 /* Read next record with same key */
-#define HA_READ_PREV 4 /* Read prev. record with same key */
-#define HA_READ_ORDER 8 /* Read through record-keys in order */
+#define HA_READ_NEXT 1 /* TODO really use this flag */
+#define HA_READ_PREV 2 /* supports ::index_prev */
+#define HA_READ_ORDER 4 /* index_next/prev follow sort order */
+#define HA_READ_RANGE 8 /* can find all records in a range */
#define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
-#define HA_NOT_READ_PREFIX_LAST 32 /* No support for index_read_last() */
-#define HA_KEY_READ_ONLY 64 /* Support HA_EXTRA_KEYREAD */
-
+#define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */
/* operations for disable/enable indexes */
#define HA_KEY_SWITCH_NONUNIQ 0
@@ -108,9 +99,6 @@
#define HA_DDL_WITH_LOCK 2 /* Can create/drop with locked table */
#define HA_DDL_ONLINE 4 /* Can create/drop without lock */
-/* Return value for ddl methods */
-#define HA_DDL_NOT_IMPLEMENTED -1
-
/*
Parameters for open() (in register form->filestat)
HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
@@ -239,6 +227,18 @@ class handler :public Sql_alloc
protected:
struct st_table *table; /* The table definition */
+ virtual int index_init(uint idx) { active_index=idx; return 0; }
+ virtual int index_end() { active_index=MAX_KEY; return 0; }
+ /*
+ rnd_init() can be called two times without rnd_end() in between
+ (it only makes sense if scan=1).
+ then the second call should prepare for the new table scan (e.g
+ if rnd_init allocates the cursor, second call should position it
+ to the start of the table, no need to deallocate and allocate it again
+ */
+ virtual int rnd_init(bool scan) =0;
+ virtual int rnd_end() { return 0; }
+
public:
byte *ref; /* Pointer to current row */
byte *dupp_ref; /* Pointer to dupp row */
@@ -255,6 +255,7 @@ public:
time_t create_time; /* When table was created */
time_t check_time;
time_t update_time;
+ enum {NONE=0, INDEX, RND} inited;
/* The following are for read_range() */
key_range save_end_range, *end_range;
@@ -279,11 +280,11 @@ public:
delete_length(0), auto_increment_value(0),
records(0), deleted(0), mean_rec_length(0),
create_time(0), check_time(0), update_time(0),
- key_used_on_scan(MAX_KEY), active_index(MAX_REF_PARTS),
+ key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)), block_size(0),
- raid_type(0), ft_handler(0), implicit_emptied(0)
+ raid_type(0), ft_handler(0), implicit_emptied(0), inited(NONE)
{}
- virtual ~handler(void) {}
+ virtual ~handler(void) { /* TODO: DBUG_ASSERT(inited == NONE); */ }
int ha_open(const char *name, int mode, int test_if_locked);
void update_timestamp(byte *record);
void update_auto_increment();
@@ -299,88 +300,140 @@ public:
virtual bool has_transactions(){ return 0;}
virtual uint extra_rec_buf_length() { return 0; }
virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; }
- virtual const char *index_type(uint key_number) { return "";}
- virtual int index_init(uint idx) { active_index=idx; return 0;}
- virtual int index_end() {return 0; }
+ virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}
+
+ int ha_index_init(uint idx)
+ {
+ DBUG_ASSERT(inited==NONE);
+ inited=INDEX;
+ return index_init(idx);
+ }
+ int ha_index_end()
+ {
+ DBUG_ASSERT(inited==INDEX);
+ inited=NONE;
+ return index_end();
+ }
+ int ha_rnd_init(bool scan=1)
+ {
+ DBUG_ASSERT(inited==NONE || (inited==RND && scan));
+ inited=RND;
+ return rnd_init(scan);
+ }
+ int ha_rnd_end()
+ {
+ DBUG_ASSERT(inited==RND);
+ inited=NONE;
+ return rnd_end();
+ }
+ /* this is neseccary in many places, e.g. in HANDLER command */
+ int ha_index_or_rnd_end()
+ {
+ return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
+ }
uint get_index(void) const { return active_index; }
virtual int open(const char *name, int mode, uint test_if_locked)=0;
- virtual void initialize(void) {}
virtual int close(void)=0;
- virtual int write_row(byte * buf)=0;
- virtual int update_row(const byte * old_data, byte * new_data)=0;
- virtual int delete_row(const byte * buf)=0;
+ virtual int write_row(byte * buf) { return HA_ERR_WRONG_COMMAND; }
+ virtual int update_row(const byte * old_data, byte * new_data)
+ { return HA_ERR_WRONG_COMMAND; }
+ virtual int delete_row(const byte * buf)
+ { return HA_ERR_WRONG_COMMAND; }
virtual int index_read(byte * buf, const byte * key,
- uint key_len, enum ha_rkey_function find_flag)=0;
+ uint key_len, enum ha_rkey_function find_flag)
+ { return HA_ERR_WRONG_COMMAND; }
virtual int index_read_idx(byte * buf, uint index, const byte * key,
- uint key_len, enum ha_rkey_function find_flag)=0;
- virtual int index_next(byte * buf)=0;
- virtual int index_prev(byte * buf)=0;
- virtual int index_first(byte * buf)=0;
- virtual int index_last(byte * buf)=0;
+ uint key_len, enum ha_rkey_function find_flag);
+ virtual int index_next(byte * buf)
+ { return HA_ERR_WRONG_COMMAND; }
+ virtual int index_prev(byte * buf)
+ { return HA_ERR_WRONG_COMMAND; }
+ virtual int index_first(byte * buf)
+ { return HA_ERR_WRONG_COMMAND; }
+ virtual int index_last(byte * buf)
+ { return HA_ERR_WRONG_COMMAND; }
virtual int index_next_same(byte *buf, const byte *key, uint keylen);
virtual int index_read_last(byte * buf, const byte * key, uint key_len)
- {
- return (my_errno=HA_ERR_WRONG_COMMAND);
- }
+ { return (my_errno=HA_ERR_WRONG_COMMAND); }
virtual int read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range, bool sorted);
virtual int read_range_next();
int compare_key(key_range *range);
- virtual int ft_init()
- { return -1; }
+ virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key,
uint keylen)
{ return NULL; }
- virtual int ft_read(byte *buf) { return -1; }
- virtual int rnd_init(bool scan=1)=0;
- virtual int rnd_end() { return 0; }
+ virtual int ft_read(byte *buf) { return HA_ERR_WRONG_COMMAND; }
virtual int rnd_next(byte *buf)=0;
virtual int rnd_pos(byte * buf, byte *pos)=0;
virtual int read_first_row(byte *buf, uint primary_key);
- virtual int restart_rnd_next(byte *buf, byte *pos);
+ /*
+ The following function is only needed for tables that may be temporary
+ tables during joins
+ */
+ virtual int restart_rnd_next(byte *buf, byte *pos)
+ { return HA_ERR_WRONG_COMMAND; }
+ virtual int rnd_same(byte *buf, uint inx)
+ { return HA_ERR_WRONG_COMMAND; }
virtual ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key)
{ return (ha_rows) 10; }
virtual void position(const byte *record)=0;
- virtual my_off_t row_position() { return HA_OFFSET_ERROR; }
virtual void info(uint)=0;
- virtual int extra(enum ha_extra_function operation)=0;
+ virtual int extra(enum ha_extra_function operation)
+ { return 0; }
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
- {
- return extra(operation);
- }
+ { return extra(operation); }
virtual int reset() { return extra(HA_EXTRA_RESET); }
virtual int external_lock(THD *thd, int lock_type)=0;
virtual void unlock_row() {}
virtual int start_stmt(THD *thd) {return 0;}
- virtual int delete_all_rows();
+ /*
+ This is called to delete all rows in a table
+ If the handler don't support this, then this function will
+ return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
+ by one.
+ */
+ virtual int delete_all_rows()
+ { return (my_errno=HA_ERR_WRONG_COMMAND); }
virtual longlong get_auto_increment();
virtual void update_create_info(HA_CREATE_INFO *create_info) {}
- virtual int check(THD* thd, HA_CHECK_OPT* check_opt );
- virtual int repair(THD* thd, HA_CHECK_OPT* check_opt);
- virtual bool check_and_repair(THD *thd) {return 1;}
- virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt);
- virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt);
- virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt);
- virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
- virtual int backup(THD* thd, HA_CHECK_OPT* check_opt);
+
+ /* admin commands - called from mysql_admin_table */
+ virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
+ virtual int backup(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
/*
restore assumes .frm file must exist, and that generate_table() has been
called; It will just copy the data file and run repair.
*/
- virtual int restore(THD* thd, HA_CHECK_OPT* check_opt);
- virtual int dump(THD* thd, int fd = -1) { return ER_DUMP_NOT_IMPLEMENTED; }
+ virtual int restore(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
+ virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
+ virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
+ virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
+ virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
+ virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
+ { return HA_ADMIN_NOT_IMPLEMENTED; }
+ /* end of the list of admin commands */
+
+ virtual bool check_and_repair(THD *thd) { return HA_ERR_WRONG_COMMAND; }
+ virtual int dump(THD* thd, int fd = -1) { return HA_ERR_WRONG_COMMAND; }
virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int indexes_are_disabled(void) {return 0;}
virtual void start_bulk_insert(ha_rows rows) {}
virtual int end_bulk_insert() {return 0; }
- virtual int discard_or_import_tablespace(my_bool discard) {return -1;}
- // not implemented by default
- virtual int net_read_dump(NET* net)
- { return ER_DUMP_NOT_IMPLEMENTED; }
+ virtual int discard_or_import_tablespace(my_bool discard)
+ {return HA_ERR_WRONG_COMMAND;}
+ virtual int net_read_dump(NET* net) { return HA_ERR_WRONG_COMMAND; }
virtual char *update_table_comment(const char * comment)
{ return (char*) comment;}
virtual void append_create_info(String *packet) {}
@@ -395,38 +448,47 @@ public:
virtual const char *table_type() const =0;
virtual const char **bas_ext() const =0;
virtual ulong table_flags(void) const =0;
- virtual ulong index_flags(uint idx) const
- {
- return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEY_READ_ONLY);
- }
+ virtual ulong index_flags(uint idx, uint part=~0) const =0;
virtual ulong index_ddl_flags(KEY *wanted_index) const
- {
- return (HA_DDL_SUPPORT);
- }
+ { return (HA_DDL_SUPPORT); }
virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
- {
- my_error(ER_NOT_SUPPORTED_YET, MYF(0), "online add index");
- return (HA_DDL_NOT_IMPLEMENTED);
- }
+ { return (HA_ERR_WRONG_COMMAND); }
virtual int drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys)
- {
- my_error(ER_NOT_SUPPORTED_YET, MYF(0), "online drop index");
- return (HA_DDL_NOT_IMPLEMENTED);
- }
- virtual uint max_record_length() const =0;
- virtual uint max_keys() const =0;
- virtual uint max_key_parts() const =0;
- virtual uint max_key_length()const =0;
- virtual uint max_key_part_length() { return 255; }
+ { return (HA_ERR_WRONG_COMMAND); }
+
+ uint max_record_length() const
+ { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
+ uint max_keys() const
+ { return min(MAX_KEY, max_supported_keys()); }
+ uint max_key_parts() const
+ { return min(MAX_REF_PARTS, max_supported_key_parts()); }
+ uint max_key_length() const
+ { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
+ uint max_key_part_length()
+ { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+
+ virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ virtual uint max_supported_keys() const { return 0; }
+ virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
+ virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
+ virtual uint max_supported_key_part_length() { return 255; }
virtual uint min_record_length(uint options) const { return 1; }
+
virtual bool low_byte_first() const { return 1; }
virtual uint checksum() const { return 0; }
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; }
+ /*
+ default rename_table() and delete_table() rename/delete files with a
+ given name and extensions from bas_ext()
+ */
virtual int rename_table(const char *from, const char *to);
virtual int delete_table(const char *name);
+
virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
+
+ /* lock_count() can be more than one if the table is a MERGE */
virtual uint lock_count(void) const { return 1; }
virtual THR_LOCK_DATA **store_lock(THD *thd,
THR_LOCK_DATA **to,
@@ -438,8 +500,6 @@ public:
Is query with this table cachable (have sense only for ASKTRANSACT
tables)
*/
- static bool caching_allowed(THD* thd, char* table_key,
- uint key_length, uint8 cahe_type);
};
/* Some extern variables used with handlers */
@@ -456,6 +516,8 @@ extern TYPELIB tx_isolation_typelib;
#define ha_supports_generate(T) (T != DB_TYPE_INNODB)
+bool ha_caching_allowed(THD* thd, char* table_key,
+ uint key_length, uint8 cache_type);
enum db_type ha_resolve_by_name(const char *name, uint namelen);
const char *ha_get_storage_engine(enum db_type db_type);
handler *get_new_handler(TABLE *table, enum db_type db_type);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 4503c1b63a9..972de21ad86 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1189,7 +1189,7 @@ int subselect_single_select_engine::exec()
join->thd->where= save_where;
executed= 1;
join->thd->lex->current_select= save_select;
- DBUG_RETURN(join->error?join->error:1);
+ DBUG_RETURN(join->error ? join->error : 1);
}
if (item->engine_changed)
{
@@ -1241,6 +1241,8 @@ int subselect_uniquesubquery_engine::exec()
}
else
{
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->ref.key);
error= table->file->index_read(table->record[0],
tab->ref.key_buff,
tab->ref.key_length,HA_READ_KEY_EXACT);
@@ -1262,7 +1264,7 @@ int subselect_uniquesubquery_engine::exec()
subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
{
/* Tell handler we don't need the index anymore */
- tab->table->file->index_end();
+ tab->table->file->ha_index_end();
}
@@ -1289,6 +1291,8 @@ int subselect_indexsubquery_engine::exec()
}
else
{
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->ref.key);
error= table->file->index_read(table->record[0],
tab->ref.key_buff,
tab->ref.key_length,HA_READ_KEY_EXACT);
diff --git a/sql/lex.h b/sql/lex.h
index f8ead8a8d2d..966188e7667 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -210,7 +210,7 @@ static SYMBOL symbols[] = {
{ "IGNORE", SYM(IGNORE_SYM)},
{ "IMPORT", SYM(IMPORT)},
{ "IN", SYM(IN_SYM)},
- { "INDEX", SYM(INDEX)},
+ { "INDEX", SYM(INDEX_SYM)},
{ "INDEXES", SYM(INDEXES)},
{ "INFILE", SYM(INFILE)},
{ "INNER", SYM(INNER_SYM)},
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index a5d2450e551..4bf2f7b724e 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -413,7 +413,7 @@ QUICK_SELECT::~QUICK_SELECT()
{
if (!dont_free)
{
- file->index_end();
+ file->ha_index_end();
free_root(&alloc,MYF(0));
}
}
@@ -609,7 +609,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table_map prev_tables,
ha_rows limit, bool force_quick_range)
{
- uint basflag;
uint idx;
double scan_time;
DBUG_ENTER("test_quick_select");
@@ -623,9 +622,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
if (!cond || (specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range ||
!limit)
DBUG_RETURN(0); /* purecov: inspected */
- if (!((basflag= head->file->table_flags()) & HA_KEYPOS_TO_RNDPOS) &&
- keys_to_use.is_set_all() || keys_to_use.is_clear_all())
- DBUG_RETURN(0); /* Not smart database */
+ if (keys_to_use.is_clear_all())
+ DBUG_RETURN(0);
records=head->file->records;
if (!records)
records++; /* purecov: inspected */
@@ -651,7 +649,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
/* set up parameter that is passed to all functions */
param.thd= thd;
- param.baseflag=basflag;
+ param.baseflag=head->file->table_flags();
param.prev_tables=prev_tables | const_tables;
param.read_tables=read_tables;
param.current_table= head->map;
@@ -728,7 +726,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
found_records=check_quick_select(&param, idx, *key);
if (found_records != HA_POS_ERROR && found_records > 2 &&
head->used_keys.is_set(keynr) &&
- (head->file->index_flags(keynr) & HA_KEY_READ_ONLY))
+ (head->file->index_flags(keynr) & HA_KEYREAD_ONLY))
{
/*
We can resolve this by only reading through this key.
@@ -2356,7 +2354,7 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree)
0);
else
quick=new QUICK_SELECT(param->thd, param->table, param->real_keynr[idx]);
-
+
if (quick)
{
if (quick->error ||
@@ -2530,7 +2528,6 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref)
{
- table->file->index_end(); // Remove old cursor
QUICK_SELECT *quick=new QUICK_SELECT(thd, table, ref->key, 1);
KEY *key_info = &table->key_info[ref->key];
KEY_PART *key_part;
@@ -2691,20 +2688,12 @@ int QUICK_SELECT_GEOM::get_next()
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_SELECT *q, uint used_key_parts)
: QUICK_SELECT(*q), rev_it(rev_ranges)
{
- bool not_read_after_key = file->table_flags() & HA_NOT_READ_AFTER_KEY;
QUICK_RANGE *r;
it.rewind();
for (r = it++; r; r = it++)
{
rev_ranges.push_front(r);
- if (not_read_after_key && range_reads_after_key(r))
- {
- it.rewind(); // Reset range
- error = HA_ERR_UNSUPPORTED;
- dont_free=1; // Don't free memory from 'q'
- return;
- }
}
/* Remove EQ_RANGE flag for keys that are not using the full key */
for (r = rev_it++; r; r = rev_it++)
@@ -2774,29 +2763,10 @@ int QUICK_SELECT_DESC::get_next()
else
{
DBUG_ASSERT(range->flag & NEAR_MAX || range_reads_after_key(range));
-#ifndef NOT_IMPLEMENTED_YET
result=file->index_read(record, (byte*) range->max_key,
range->max_length,
((range->flag & NEAR_MAX) ?
HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV));
-#else
- /*
- Heikki changed Sept 11, 2002: since InnoDB does not store the cursor
- position if READ_KEY_EXACT is used to a primary key with all
- key columns specified, we must use below HA_READ_KEY_OR_NEXT,
- so that InnoDB stores the cursor position and is able to move
- the cursor one step backward after the search.
- */
- /*
- Note: even if max_key is only a prefix, HA_READ_AFTER_KEY will
- do the right thing - go past all keys which match the prefix
- */
- result=file->index_read(record, (byte*) range->max_key,
- range->max_length,
- ((range->flag & NEAR_MAX) ?
- HA_READ_KEY_OR_NEXT : HA_READ_AFTER_KEY));
- result = file->index_prev(record);
-#endif
}
if (result)
{
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 2072ded15d1..9b2e9e45bac 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -90,7 +90,7 @@ public:
int init()
{
key_part_info= head->key_info[index].key_part;
- return error=file->index_init(index);
+ return error=file->ha_index_init(index);
}
virtual int get_next();
virtual bool reverse_sorted() { return 0; }
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 8c1cd9ce1cb..75b00b97ce7 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -46,9 +46,9 @@
#include "mysql_priv.h"
#include "sql_select.h"
-static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
- Field* field, COND *cond,
- uint *range_fl, uint *key_prefix_length);
+static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, Field* field,
+ COND *cond, uint *range_fl,
+ uint *key_prefix_length);
static int reckey_in_range(bool max_fl, TABLE_REF *ref, Field* field,
COND *cond, uint range_fl, uint prefix_len);
static int maxmin_in_range(bool max_fl, Field* field, COND *cond);
@@ -166,11 +166,6 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
Item_field *item_field= ((Item_field*) expr);
TABLE *table= item_field->field->table;
- if ((table->file->table_flags() & HA_NOT_READ_AFTER_KEY))
- {
- const_result=0;
- break;
- }
/*
Look for a partial key that can be used for optimization.
If we succeed, ref.key_length will contain the length of
@@ -186,7 +181,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
const_result= 0;
break;
}
- error= table->file->index_init((uint) ref.key);
+ error= table->file->ha_index_init((uint) ref.key);
if (!ref.key_length)
error= table->file->index_first(table->record[0]);
@@ -206,7 +201,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
table->key_read= 0;
table->file->extra(HA_EXTRA_NO_KEYREAD);
}
- table->file->index_end();
+ table->file->ha_index_end();
if (error)
{
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
@@ -260,12 +255,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
const_result= 0;
break;
}
- if ((table->file->table_flags() & HA_NOT_READ_AFTER_KEY))
- {
- const_result= 0;
- break;
- }
- error= table->file->index_init((uint) ref.key);
+ error= table->file->ha_index_init((uint) ref.key);
if (!ref.key_length)
error= table->file->index_last(table->record[0]);
@@ -285,7 +275,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
table->key_read=0;
table->file->extra(HA_EXTRA_NO_KEYREAD);
}
- table->file->index_end();
+ table->file->ha_index_end();
if (error)
{
if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
@@ -648,7 +638,7 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
keyinfo != keyinfo_end;
keyinfo++,idx++)
{
- if (table->file->index_flags(idx) & HA_WRONG_ASCII_ORDER)
+ if (!(table->file->index_flags(idx) & HA_READ_ORDER))
break;
KEY_PART_INFO *part,*part_end;
diff --git a/sql/records.cc b/sql/records.cc
index ca00658cdae..104fe99de0b 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -70,7 +70,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
info->io_cache=tempfile;
reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0);
info->ref_pos=table->file->ref;
- table->file->rnd_init(0);
+ if (!table->file->inited)
+ table->file->ha_rnd_init(0);
/*
table->sort.addon_field is checked because if we use addon fields,
@@ -105,7 +106,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
else if (table->sort.record_pointers)
{
DBUG_PRINT("info",("using record_pointers"));
- table->file->rnd_init(0);
+ table->file->ha_rnd_init(0);
info->cache_pos=table->sort.record_pointers;
info->cache_end=info->cache_pos+
table->sort.found_records*info->ref_length;
@@ -116,7 +117,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
{
DBUG_PRINT("info",("using rr_sequential"));
info->read_record=rr_sequential;
- table->file->rnd_init();
+ table->file->ha_rnd_init();
/* We can use record cache if we don't update dynamic length tables */
if (!table->no_cache &&
(use_record_cache > 0 ||
@@ -142,7 +143,8 @@ void end_read_record(READ_RECORD *info)
{
filesort_free_buffers(info->table);
(void) info->file->extra(HA_EXTRA_NO_CACHE);
- (void) info->file->rnd_end();
+ if (info->read_record != rr_quick) // otherwise quick_range does it
+ (void) info->file->ha_index_or_rnd_end();
info->table=0;
}
}
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 9d1eb7bc54d..ec018a8d296 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1428,8 +1428,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1);
table->field[1]->store(combo.user.str,combo.user.length, &my_charset_latin1);
- table->file->index_init(0);
- if (table->file->index_read(table->record[0],
+ if (table->file->index_read_idx(table->record[0], 0,
(byte*) table->field[0]->ptr,0,
HA_READ_KEY_EXACT))
{
@@ -1440,7 +1439,6 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
else
my_error(ER_NO_PERMISSION_TO_CREATE_USER, MYF(0),
thd->user, thd->host_or_ip);
- error= -1;
goto end;
}
old_row_exists = 0;
@@ -1577,7 +1575,6 @@ end:
&thd->lex->mqh,
rights);
}
- table->file->index_end();
DBUG_RETURN(error);
}
@@ -1613,8 +1610,7 @@ static int replace_db_table(TABLE *table, const char *db,
table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1);
table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1);
table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1);
- table->file->index_init(0);
- if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0,
+ if (table->file->index_read_idx(table->record[0],0,(byte*) table->field[0]->ptr,0,
HA_READ_KEY_EXACT))
{
if (what == 'N')
@@ -1668,13 +1664,11 @@ static int replace_db_table(TABLE *table, const char *db,
acl_update_db(combo.user.str,combo.host.str,db,rights);
else
acl_insert_db(combo.user.str,combo.host.str,db,rights);
- table->file->index_end();
DBUG_RETURN(0);
/* This could only happen if the grant tables got corrupted */
table_error:
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
- table->file->index_end();
abort:
DBUG_RETURN(-1);
@@ -1796,8 +1790,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
col_privs->field[3]->pack_length());
key_copy(key,col_privs,0,key_len);
col_privs->field[4]->store("",0, &my_charset_latin1);
- col_privs->file->index_init(0);
- if (col_privs->file->index_read(col_privs->record[0],
+ if (col_privs->file->index_read_idx(col_privs->record[0],0,
(byte*) col_privs->field[0]->ptr,
key_len, HA_READ_KEY_EXACT))
{
@@ -1912,7 +1905,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
List_iterator <LEX_COLUMN> iter(columns);
class LEX_COLUMN *xx;
- table->file->index_init(0);
+ table->file->ha_index_init(0);
while ((xx=iter++))
{
ulong privileges = xx->rights;
@@ -1982,7 +1975,6 @@ static int replace_column_table(GRANT_TABLE *g_t,
my_hash_insert(&g_t->hash_columns,(byte*) grant_column);
}
}
- table->file->index_end();
/*
If revoke of privileges on the table level, remove all such privileges
@@ -1991,7 +1983,6 @@ static int replace_column_table(GRANT_TABLE *g_t,
if (revoke_grant)
{
- table->file->index_init(0);
if (table->file->index_read(table->record[0], (byte*) table->field[0]->ptr,
key_length, HA_READ_KEY_EXACT))
goto end;
@@ -2047,7 +2038,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
}
end:
- table->file->index_end();
+ table->file->ha_index_end();
DBUG_RETURN(result);
}
@@ -2560,15 +2551,13 @@ my_bool grant_init(THD *org_thd)
goto end;
t_table = tables[0].table; c_table = tables[1].table;
- t_table->file->index_init(0);
+ t_table->file->ha_index_init(0);
if (t_table->file->index_first(t_table->record[0]))
{
- t_table->file->index_end();
return_val= 0;
goto end_unlock;
}
grant_option= TRUE;
- t_table->file->index_end();
/* Will be restored by org_thd->store_globals() */
my_pthread_setspecific_ptr(THR_MALLOC,&memex);
@@ -2588,7 +2577,7 @@ my_bool grant_init(THD *org_thd)
{
sql_print_error("Warning: 'tables_priv' entry '%s %s@%s' "
"ignored in --skip-name-resolve mode.",
- mem_check->tname, mem_check->user,
+ mem_check->tname, mem_check->user,
mem_check->host, mem_check->host);
continue;
}
@@ -2605,6 +2594,7 @@ my_bool grant_init(THD *org_thd)
return_val=0; // Return ok
end_unlock:
+ t_table->file->ha_index_end();
mysql_unlock_tables(thd, lock);
thd->version--; // Force close to free memory
@@ -3548,12 +3538,10 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list)
record[0])))
{
tables[0].table->file->print_error(error, MYF(0));
- tables[0].table->file->index_end();
DBUG_RETURN(-1);
}
delete_dynamic_element(&acl_users, acl_userd);
}
- tables[0].table->file->index_end();
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index b9fe61ac48a..4a5a41c4b40 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1042,9 +1042,9 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
goto err_unlock; // Parse query
}
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
- if (check_tables && !handler::caching_allowed(thd, table->db(),
- table->key_length(),
- table->type()))
+ if (check_tables && !ha_caching_allowed(thd, table->db(),
+ table->key_length(),
+ table->type()))
{
DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s",
table_list.db, table_list.alias));
@@ -2685,9 +2685,9 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
for (; tables_used; tables_used= tables_used->next)
{
TABLE *table= tables_used->table;
- if (!handler::caching_allowed(thd, table->table_cache_key,
- table->key_length,
- table->file->table_cache_type()))
+ if (!ha_caching_allowed(thd, table->table_cache_key,
+ table->key_length,
+ table->file->table_cache_type()))
{
DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s",
tables_used->db, tables_used->alias));
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index f21dbb10712..2ee880e79e7 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -197,6 +197,7 @@ cleanup:
query_cache_invalidate3(thd, table_list, 1);
}
+ delete select;
transactional_table= table->file->has_transactions();
log_delayed= (transactional_table || table->tmp_table);
if (deleted && (error <= 0 || !transactional_table))
@@ -206,7 +207,7 @@ cleanup:
{
if (error <= 0)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
log_delayed);
if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1;
@@ -225,7 +226,6 @@ cleanup:
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
- delete select;
free_underlaid_joins(thd, &thd->lex->select_lex);
if (error >= 0 || thd->net.report_error)
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0);
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index fcc56cbf9c9..7dfe707a317 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -72,6 +72,7 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok)
if (*ptr)
{
+ (*ptr)->file->ha_index_or_rnd_end();
VOID(pthread_mutex_lock(&LOCK_open));
if (close_thread_table(thd, ptr))
{
@@ -94,10 +95,14 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok)
int mysql_ha_closeall(THD *thd, TABLE_LIST *tables)
{
TABLE **ptr=find_table_ptr_by_name(thd, tables->db, tables->real_name, 0);
- if (*ptr && close_thread_table(thd, ptr))
+ if (*ptr)
{
- /* Tell threads waiting for refresh that something has happened */
- VOID(pthread_cond_broadcast(&COND_refresh));
+ (*ptr)->file->ha_index_or_rnd_end();
+ if (close_thread_table(thd, ptr))
+ {
+ /* Tell threads waiting for refresh that something has happened */
+ VOID(pthread_cond_broadcast(&COND_refresh));
+ }
}
return 0;
}
@@ -136,7 +141,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
keyname,tables->alias);
return -1;
}
- table->file->index_init(keyno);
+ table->file->ha_index_or_rnd_end();
+ table->file->ha_index_init(keyno);
}
List<Item> list;
@@ -148,8 +154,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
uint num_rows;
byte *key;
uint key_len;
- LINT_INIT(key);
- LINT_INIT(key_len);
+ LINT_INIT(key);
+ LINT_INIT(key_len);
it++; // Skip first NULL field
@@ -180,7 +186,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
err=table->file->index_first(table->record[0]);
else
{
- if (!(err=table->file->rnd_init(1)))
+ table->file->ha_index_or_rnd_end();
+ if (!(err=table->file->ha_rnd_init(1)))
err=table->file->rnd_next(table->record[0]);
}
mode=RNEXT;
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 44293b8214f..de5509cff5d 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -22,8 +22,6 @@ struct st_find_field
Field *field;
};
-static void free_select(SQL_SELECT *sel);
-
/* Used fields */
static struct st_find_field init_used_fields[]=
@@ -48,9 +46,9 @@ static struct st_find_field init_used_fields[]=
enum enum_used_fields
{
help_topic_help_topic_id= 0,
- help_topic_name,
+ help_topic_name,
help_topic_help_category_id,
- help_topic_description,
+ help_topic_description,
help_topic_example,
help_category_help_category_id,
@@ -60,13 +58,13 @@ enum enum_used_fields
help_keyword_help_keyword_id,
help_keyword_name,
- help_relation_help_topic_id,
+ help_relation_help_topic_id,
help_relation_help_keyword_id
};
/*
- Fill st_find_field structure with pointers to fields
+ Fill st_find_field structure with pointers to fields
SYNOPSIS
init_fields()
@@ -90,7 +88,7 @@ static bool init_fields(THD *thd, TABLE_LIST *tables,
/* We have to use 'new' here as field will be re_linked on free */
Item_field *field= new Item_field("mysql", find_fields->table_name,
find_fields->field_name);
- if (!(find_fields->field= find_field_in_tables(thd, field, tables,
+ if (!(find_fields->field= find_field_in_tables(thd, field, tables,
&not_used, TRUE)))
DBUG_RETURN(1);
}
@@ -119,12 +117,12 @@ static bool init_fields(THD *thd, TABLE_LIST *tables,
NOTE
Field 'names' is set only if more than one topic is found.
- Fields 'name', 'description', 'example' are set only if
+ Fields 'name', 'description', 'example' are set only if
found exactly one topic.
*/
void memorize_variant_topic(THD *thd, TABLE *topics, int count,
- struct st_find_field *find_fields,
+ struct st_find_field *find_fields,
List<String> *names,
String *name, String *description, String *example)
{
@@ -136,7 +134,7 @@ void memorize_variant_topic(THD *thd, TABLE *topics, int count,
get_field(mem_root,find_fields[help_topic_description].field, description);
get_field(mem_root,find_fields[help_topic_example].field, example);
}
- else
+ else
{
if (count == 1)
names->push_back(name);
@@ -168,7 +166,7 @@ void memorize_variant_topic(THD *thd, TABLE *topics, int count,
NOTE
Field 'names' is set only if more than one topic was found.
- Fields 'name', 'description', 'example' are set only if
+ Fields 'name', 'description', 'example' are set only if
exactly one topic was found.
*/
@@ -179,12 +177,12 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields,
{
DBUG_ENTER("search_topics");
int count= 0;
-
+
READ_RECORD read_record_info;
init_read_record(&read_record_info, thd, topics, select,1,0);
while (!read_record_info.read_record(&read_record_info))
{
- if (!select->cond->val_int()) // Dosn't match like
+ if (!select->cond->val_int()) // Doesn't match like
continue;
memorize_variant_topic(thd,topics,count,find_fields,
names,name,description,example);
@@ -219,7 +217,7 @@ int search_keyword(THD *thd, TABLE *keywords, struct st_find_field *find_fields,
{
DBUG_ENTER("search_keyword");
int count= 0;
-
+
READ_RECORD read_record_info;
init_read_record(&read_record_info, thd, keywords, select,1,0);
while (!read_record_info.read_record(&read_record_info) && count<2)
@@ -256,13 +254,13 @@ int search_keyword(THD *thd, TABLE *keywords, struct st_find_field *find_fields,
description description of found topic (out)
example example for found topic (out)
- NOTE
+ NOTE
Field 'names' is set only if more than one topic was found.
- Fields 'name', 'description', 'example' are set only if
+ Fields 'name', 'description', 'example' are set only if
exactly one topic was found.
*/
-int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
+int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
struct st_find_field *find_fields, int16 key_id,
List<String> *names,
String *name, String *description, String *example)
@@ -273,7 +271,7 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
Field *rtopic_id, *rkey_id;
DBUG_ENTER("get_topics_for_keyword");
-
+
if ((iindex_topic= find_type((char*) primary_key_name,
&topics->keynames, 1+2)-1)<0 ||
(iindex_relations= find_type((char*) primary_key_name,
@@ -284,18 +282,18 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
}
rtopic_id= find_fields[help_relation_help_topic_id].field;
rkey_id= find_fields[help_relation_help_keyword_id].field;
-
- topics->file->index_init(iindex_topic);
- relations->file->index_init(iindex_relations);
-
+
+ topics->file->ha_index_init(iindex_topic);
+ relations->file->ha_index_init(iindex_relations);
+
rkey_id->store((longlong) key_id);
rkey_id->get_key_image(buff, rkey_id->pack_length(), rkey_id->charset(),
Field::itRAW);
int key_res= relations->file->index_read(relations->record[0],
(byte *)buff, rkey_id->pack_length(),
HA_READ_KEY_EXACT);
-
- for ( ;
+
+ for ( ;
!key_res && key_id == (int16) rkey_id->val_int() ;
key_res= relations->file->index_next(relations->record[0]))
{
@@ -305,7 +303,7 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
field->store((longlong) topic_id);
field->get_key_image(topic_id_buff, field->pack_length(), field->charset(),
Field::itRAW);
-
+
if (!topics->file->index_read(topics->record[0], (byte *)topic_id_buff,
field->pack_length(), HA_READ_KEY_EXACT))
{
@@ -314,50 +312,12 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations,
count++;
}
}
+ topics->file->ha_index_end();
+ relations->file->ha_index_end();
DBUG_RETURN(count);
}
/*
- Look for topics with keyword by mask
-
- SYNOPSIS
- search_topics_by_keyword()
- thd Thread handler
- keywords Table of keywords
- topics Table of topics
- relations Table of m:m relation "topic/keyword"
- find_fields Filled array of info for fields
- select Function to test for if matching help keyword.
- Normally 'help_keyword.name like 'bit%'
-
- RETURN VALUES
- # number of topics found
-
- names array of name of found topics (out)
-
- name name of found topic (out)
- description description of found topic (out)
- example example for found topic (out)
-
- NOTE
- Field 'names' is set only if more than one topic was found.
- Fields 'name', 'description', 'example' are set only if
- exactly one topic was found.
-*/
-
-int search_topics_by_keyword(THD *thd,
- TABLE *keywords, TABLE *topics, TABLE *relations,
- struct st_find_field *find_fields,
- SQL_SELECT *select, List<String> *names,
- String *name, String *description, String *example)
-{
- int key_id;
- return search_keyword(thd,keywords,find_fields,select,&key_id)!=1
- ? 0 : get_topics_for_keyword(thd,topics,relations,find_fields,key_id,
- names,name,description,example);
-}
-
-/*
Look for categories by mask
SYNOPSIS
@@ -382,10 +342,10 @@ int search_categories(THD *thd, TABLE *categories,
Field *pfname= find_fields[help_category_name].field;
Field *pcat_id= find_fields[help_category_help_category_id].field;
int count= 0;
- READ_RECORD read_record_info;
+ READ_RECORD read_record_info;
DBUG_ENTER("search_categories");
-
+
init_read_record(&read_record_info, thd, categories, select,1,0);
while (!read_record_info.read_record(&read_record_info))
{
@@ -398,7 +358,7 @@ int search_categories(THD *thd, TABLE *categories,
names->push_back(lname);
}
end_read_record(&read_record_info);
-
+
DBUG_RETURN(count);
}
@@ -423,7 +383,7 @@ void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname,
init_read_record(&read_record_info, thd, items, select,1,0);
while (!read_record_info.read_record(&read_record_info))
{
- if (!select->cond->val_int())
+ if (!select->cond->val_int())
continue;
String *name= new (&thd->mem_root) String();
get_field(&thd->mem_root,pfname,name);
@@ -436,7 +396,7 @@ void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname,
/*
Send to client answer for help request
-
+
SYNOPSIS
send_answer_1()
protocol - protocol for sending
@@ -466,10 +426,10 @@ int send_answer_1(Protocol *protocol, String *s1, String *s2, String *s3)
field_list.push_back(new Item_empty_string("name",64));
field_list.push_back(new Item_empty_string("description",1000));
field_list.push_back(new Item_empty_string("example",1000));
-
+
if (protocol->send_fields(&field_list,1))
DBUG_RETURN(1);
-
+
protocol->prepare_for_resend();
protocol->store(s1);
protocol->store(s2);
@@ -539,7 +499,7 @@ extern "C" int string_ptr_cmp(const void* ptr1, const void* ptr2)
SYNOPSIS
send_variant_2_list()
protocol Protocol for sending
- names List of names
+ names List of names
cat Value of the column <is_it_category>
source_name name of category for all items..
@@ -548,8 +508,8 @@ extern "C" int string_ptr_cmp(const void* ptr1, const void* ptr2)
0 Data was successefully send
*/
-int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
- List<String> *names,
+int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
+ List<String> *names,
const char *cat, String *source_name)
{
DBUG_ENTER("send_variant_2_list");
@@ -589,17 +549,22 @@ int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
table goal table
error code of error (out)
-
+
RETURN VALUES
- # created SQL_SELECT
+ # created SQL_SELECT
*/
-SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
+SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
TABLE *table, int *error)
{
cond->fix_fields(thd, tables, &cond); // can never fail
SQL_SELECT *res= make_select(table,0,0,cond,error);
- return (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR))) ? 0 : res;
+ if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)))
+ {
+ delete res;
+ res=0;
+ }
+ return res;
}
/*
@@ -615,9 +580,9 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
pfname field "name" in table
error code of error (out)
-
+
RETURN VALUES
- # created SQL_SELECT
+ # created SQL_SELECT
*/
SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen,
@@ -649,12 +614,10 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen,
int mysqld_help(THD *thd, const char *mask)
{
Protocol *protocol= thd->protocol;
- SQL_SELECT *select_topics_by_name= 0, *select_keyword_by_name= 0,
- *select_cat_by_name= 0, *select_topics_by_cat= 0, *select_cat_by_cat= 0,
- *select_root_cats= 0;
+ SQL_SELECT *select;
st_find_field used_fields[array_elements(init_used_fields)];
DBUG_ENTER("mysqld_help");
-
+
TABLE_LIST tables[4];
bzero((gptr)tables,sizeof(tables));
tables[0].alias= tables[0].real_name= (char*) "help_topic";
@@ -670,13 +633,13 @@ int mysqld_help(THD *thd, const char *mask)
tables[3].lock_type= TL_READ;
tables[3].next= 0;
tables[0].db= tables[1].db= tables[2].db= tables[3].db= (char*) "mysql";
-
+
List<String> topics_list, categories_list, subcategories_list;
String name, description, example;
int res, count_topics, count_categories, error;
uint mlen= strlen(mask);
MEM_ROOT *mem_root= &thd->mem_root;
-
+
if (open_and_lock_tables(thd, tables))
{
res= -1;
@@ -684,7 +647,7 @@ int mysqld_help(THD *thd, const char *mask)
}
/* Init tables and fields to be usable from items */
setup_tables(tables);
- memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
+ memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
{
res= -1;
@@ -693,39 +656,55 @@ int mysqld_help(THD *thd, const char *mask)
size_t i;
for (i=0; i<sizeof(tables)/sizeof(TABLE_LIST); i++)
tables[i].table->file->init_table_handle_for_HANDLER();
-
- if (!(select_topics_by_name=
+
+ if (!(select=
prepare_select_for_name(thd,mask,mlen,tables,tables[0].table,
- used_fields[help_topic_name].field,&error)) ||
- !(select_cat_by_name=
- prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
- used_fields[help_category_name].field,&error))||
- !(select_keyword_by_name=
- prepare_select_for_name(thd,mask,mlen,tables,tables[3].table,
- used_fields[help_keyword_name].field,&error)))
+ used_fields[help_topic_name].field,&error)))
{
res= -1;
goto end;
}
res= 1;
- count_topics= search_topics(thd,tables[0].table,used_fields,
- select_topics_by_name,&topics_list,
+ count_topics= search_topics(thd,tables[0].table,used_fields,
+ select,&topics_list,
&name, &description, &example);
+ delete select;
if (count_topics == 0)
- count_topics= search_topics_by_keyword(thd,tables[3].table,tables[0].table,
- tables[2].table,used_fields,
- select_keyword_by_name,&topics_list,
- &name,&description,&example);
-
+ {
+ int key_id;
+ if (!(select=
+ prepare_select_for_name(thd,mask,mlen,tables,tables[3].table,
+ used_fields[help_keyword_name].field,&error)))
+ {
+ res= -1;
+ goto end;
+ }
+ count_topics=search_keyword(thd,tables[3].table,used_fields,select,&key_id);
+ delete select;
+ count_topics= (count_topics != 1) ? 0 :
+ get_topics_for_keyword(thd,tables[0].table,tables[2].table,
+ used_fields,key_id,&topics_list,&name,
+ &description,&example);
+ }
+
if (count_topics == 0)
{
int16 category_id;
Field *cat_cat_id= used_fields[help_category_parent_category_id].field;
+ if (!(select=
+ prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
+ used_fields[help_category_name].field,&error)))
+ {
+ res= -1;
+ goto end;
+ }
+
count_categories= search_categories(thd, tables[1].table, used_fields,
- select_cat_by_name,
+ select,
&categories_list,&category_id);
+ delete select;
if (!count_categories)
{
if (send_header_2(protocol,FALSE))
@@ -746,22 +725,26 @@ int mysqld_help(THD *thd, const char *mask)
Item *cond_cat_by_cat=
new Item_func_equal(new Item_field(cat_cat_id),
new Item_int((int32)category_id));
- if (!(select_topics_by_cat= prepare_simple_select(thd,cond_topic_by_cat,
- tables,tables[0].table,
- &error)) ||
- !(select_cat_by_cat=
- prepare_simple_select(thd,cond_cat_by_cat,tables,
- tables[1].table,&error)))
+ if (!(select= prepare_simple_select(thd,cond_topic_by_cat,
+ tables,tables[0].table,&error)))
{
res= -1;
goto end;
}
get_all_items_for_category(thd,tables[0].table,
used_fields[help_topic_name].field,
- select_topics_by_cat,&topics_list);
+ select,&topics_list);
+ delete select;
+ if (!(select= prepare_simple_select(thd,cond_cat_by_cat,tables,
+ tables[1].table,&error)))
+ {
+ res= -1;
+ goto end;
+ }
get_all_items_for_category(thd,tables[1].table,
used_fields[help_category_name].field,
- select_cat_by_cat,&subcategories_list);
+ select,&subcategories_list);
+ delete select;
String *cat= categories_list.head();
if (send_header_2(protocol, true) ||
send_variant_2_list(mem_root,protocol,&topics_list, "N",cat) ||
@@ -780,30 +763,25 @@ int mysqld_help(THD *thd, const char *mask)
if (send_header_2(protocol, FALSE) ||
send_variant_2_list(mem_root,protocol, &topics_list, "N", 0))
goto end;
- search_categories(thd, tables[1].table, used_fields,
- select_cat_by_name,&categories_list, 0);
+ if (!(select=
+ prepare_select_for_name(thd,mask,mlen,tables,tables[1].table,
+ used_fields[help_category_name].field,&error)))
+ {
+ res= -1;
+ goto end;
+ }
+ search_categories(thd, tables[1].table, used_fields,
+ select,&categories_list, 0);
+ delete select;
/* Then send categories */
if (send_variant_2_list(mem_root,protocol, &categories_list, "Y", 0))
goto end;
}
res= 0;
-
+
send_eof(thd);
end:
- free_select(select_topics_by_name);
- free_select(select_keyword_by_name);
- free_select(select_cat_by_name);
- free_select(select_topics_by_cat);
- free_select(select_cat_by_cat);
- free_select(select_root_cats);
-
DBUG_RETURN(res);
}
-
-static void free_select(SQL_SELECT *sel)
-{
- if (sel)
- delete sel->quick;
-}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 037dd99d3b6..b5abb3b632d 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1111,7 +1111,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
thd->fatal_error(); // Abort waiting inserts
goto end;
}
- if (di->table->file->has_transactions())
+ if (!(di->table->file->table_flags() & HA_CAN_INSERT_DELAYED))
{
thd->fatal_error();
my_error(ER_ILLEGAL_HA, MYF(0), di->table_list.real_name);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index b87f88a3988..582b1d185ac 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -125,7 +125,7 @@ static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
Item *having);
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
ulong offset,Item *having);
-static int remove_dup_with_hash_index(THD *thd, TABLE *table,
+static int remove_dup_with_hash_index(THD *thd,TABLE *table,
uint field_count, Field **first_field,
ulong key_length,Item *having);
static int join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count);
@@ -616,22 +616,8 @@ JOIN::optimize()
}
if (const_tables && !thd->locked_tables &&
!(select_options & SELECT_NO_UNLOCK))
- {
- TABLE **curr_table, **end;
- for (curr_table= table, end=curr_table + const_tables ;
- curr_table != end;
- curr_table++)
- {
- /* BDB tables require that we call index_end() before doing an unlock */
- if ((*curr_table)->key_read)
- {
- (*curr_table)->key_read=0;
- (*curr_table)->file->extra(HA_EXTRA_NO_KEYREAD);
- }
- (*curr_table)->file->index_end();
- }
mysql_unlock_some_tables(thd, table, const_tables);
- }
+
if (!conds && outer_join)
{
/* Handle the case where we have an OUTER JOIN without a WHERE */
@@ -1539,6 +1525,7 @@ JOIN::cleanup()
}
}
tmp_join->tmp_join= 0;
+ tmp_table_param.copy_field=0;
DBUG_RETURN(tmp_join->cleanup());
}
@@ -3652,7 +3639,6 @@ make_join_readinfo(JOIN *join, uint options)
}
delete tab->quick;
tab->quick=0;
- table->file->index_init(tab->ref.key);
tab->read_first_record= join_read_key;
tab->read_record.read_record= join_no_more_records;
if (table->used_keys.is_set(tab->ref.key) &&
@@ -3672,7 +3658,6 @@ make_join_readinfo(JOIN *join, uint options)
}
delete tab->quick;
tab->quick=0;
- table->file->index_init(tab->ref.key);
if (table->used_keys.is_set(tab->ref.key) &&
!table->no_keyread)
{
@@ -3692,7 +3677,6 @@ make_join_readinfo(JOIN *join, uint options)
break;
case JT_FT:
table->status=STATUS_NO_RECORD;
- table->file->index_init(tab->ref.key);
tab->read_first_record= join_ft_read_first;
tab->read_record.read_record= join_ft_read_next;
break;
@@ -3762,7 +3746,6 @@ make_join_readinfo(JOIN *join, uint options)
!(tab->select && tab->select->quick))
{ // Only read index tree
tab->index=find_shortest_key(table, & table->used_keys);
- tab->table->file->index_init(tab->index);
tab->read_first_record= join_read_first;
tab->type=JT_NEXT; // Read with index_first / index_next
}
@@ -3836,9 +3819,7 @@ void JOIN_TAB::cleanup()
table->key_read= 0;
table->file->extra(HA_EXTRA_NO_KEYREAD);
}
- /* Don't free index if we are using read_record */
- if (!read_record.table)
- table->file->index_end();
+ table->file->ha_index_or_rnd_end();
/*
We need to reset this for next select
(Tested in part_of_refkey)
@@ -3864,7 +3845,7 @@ void
JOIN::join_free(bool full)
{
JOIN_TAB *tab,*end;
- DBUG_ENTER("join_free");
+ DBUG_ENTER("JOIN::join_free");
if (table)
{
@@ -3877,24 +3858,24 @@ JOIN::join_free(bool full)
free_io_cache(table[const_tables]);
filesort_free_buffers(table[const_tables]);
}
- if (!full && select_lex->uncacheable)
+ if (full || !select_lex->uncacheable)
+ {
+ for (tab= join_tab, end= tab+tables; tab != end; tab++)
+ tab->cleanup();
+ table= 0;
+ }
+ else
{
for (tab= join_tab, end= tab+tables; tab != end; tab++)
{
if (tab->table)
{
/* Don't free index if we are using read_record */
- if (!tab->read_record.table)
- tab->table->file->index_end();
+ if (tab->table->file->inited==handler::RND)
+ tab->table->file->ha_rnd_end();
}
}
}
- else
- {
- for (tab= join_tab, end= tab+tables; tab != end; tab++)
- tab->cleanup();
- table= 0;
- }
}
/*
We are not using tables anymore
@@ -4145,12 +4126,6 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
item->no_rows_in_result();
result->send_data(fields);
}
- if (tables) // Not from do_select()
- {
- /* Close open cursors */
- for (TABLE_LIST *table=tables; table ; table=table->next)
- table->table->file->index_end();
- }
result->send_eof(); // Should be safe
}
/* Update results for FOUND_ROWS */
@@ -5552,8 +5527,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
goto err1;
if (table->file->indexes_are_disabled())
new_table.file->disable_indexes(HA_KEY_SWITCH_ALL);
- table->file->index_end();
- table->file->rnd_init();
+ table->file->ha_index_or_rnd_end();
+ table->file->ha_rnd_init();
if (table->no_rows)
{
new_table.file->extra(HA_EXTRA_NO_ROWS);
@@ -5575,7 +5550,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
}
/* remove heap table and change to use myisam table */
- (void) table->file->rnd_end();
+ (void) table->file->ha_rnd_end();
(void) table->file->close();
(void) table->file->delete_table(table->real_name);
delete table->file;
@@ -5589,7 +5564,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
err:
DBUG_PRINT("error",("Got error: %d",write_err));
table->file->print_error(error,MYF(0)); // Give table is full error
- (void) table->file->rnd_end();
+ (void) table->file->ha_rnd_end();
(void) new_table.file->close();
err1:
new_table.file->delete_table(new_table.real_name);
@@ -5638,7 +5613,8 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
DBUG_PRINT("info",("Using end_update"));
end_select=end_update;
- table->file->index_init(0);
+ if (!table->file->inited)
+ table->file->ha_index_init(0);
}
else
{
@@ -5716,9 +5692,9 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
my_errno= tmp;
error= -1;
}
- if ((tmp=table->file->index_end()))
+ if ((tmp=table->file->ha_index_or_rnd_end()))
{
- DBUG_PRINT("error",("index_end() failed"));
+ DBUG_PRINT("error",("ha_index_or_rnd_end() failed"));
my_errno= tmp;
error= -1;
}
@@ -5984,6 +5960,11 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
if (!table->outer_join || error > 0)
DBUG_RETURN(error);
}
+ if (table->key_read)
+ {
+ table->key_read=0;
+ table->file->extra(HA_EXTRA_NO_KEYREAD);
+ }
}
if (tab->on_expr && !table->null_row)
{
@@ -6062,6 +6043,8 @@ join_read_key(JOIN_TAB *tab)
int error;
TABLE *table= tab->table;
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->ref.key);
if (cmp_buffer_with_ref(tab) ||
(table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
{
@@ -6087,6 +6070,8 @@ join_read_always_key(JOIN_TAB *tab)
int error;
TABLE *table= tab->table;
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->ref.key);
if (cp_buffer_from_ref(&tab->ref))
return -1;
if ((error=table->file->index_read(table->record[0],
@@ -6112,6 +6097,8 @@ join_read_last_key(JOIN_TAB *tab)
int error;
TABLE *table= tab->table;
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->ref.key);
if (cp_buffer_from_ref(&tab->ref))
return -1;
if ((error=table->file->index_read_last(table->record[0],
@@ -6220,6 +6207,8 @@ join_read_first(JOIN_TAB *tab)
tab->read_record.file=table->file;
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->index);
if ((error=tab->table->file->index_first(tab->table->record[0])))
{
if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
@@ -6257,6 +6246,8 @@ join_read_last(JOIN_TAB *tab)
tab->read_record.file=table->file;
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->index);
if ((error= tab->table->file->index_last(tab->table->record[0])))
return report_error(table, error);
return 0;
@@ -6279,6 +6270,8 @@ join_ft_read_first(JOIN_TAB *tab)
int error;
TABLE *table= tab->table;
+ if (!table->file->inited)
+ table->file->ha_index_init(tab->ref.key);
#if NOT_USED_YET
if (cp_buffer_from_ref(&tab->ref)) // as ft-key doesn't use store_key's
return -1; // see also FT_SELECT::init()
@@ -6596,7 +6589,6 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (item->maybe_null)
group->buff[-1]=item->null_value ? 1 : 0;
}
- // table->file->index_init(0);
if (!table->file->index_read(table->record[1],
join->tmp_table_param.group_buff,0,
HA_READ_KEY_EXACT))
@@ -6627,7 +6619,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
error, 0))
DBUG_RETURN(-1); // Not a table_is_full error
/* Change method to update rows */
- table->file->index_init(0);
+ table->file->ha_index_init(0);
join->join_tab[join->tables-1].next_select=end_unique_update;
}
join->send_records++;
@@ -7125,10 +7117,10 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if (tab->ref.key >= 0)
{
tab->ref.key= new_ref_key;
- table->file->index_init(new_ref_key);
}
else
{
+ select->quick->file->ha_index_end();
select->quick->index= new_ref_key;
select->quick->init();
}
@@ -7150,7 +7142,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*/
if (!select->quick->reverse_sorted())
{
- if (table->file->index_flags(ref_key) & HA_NOT_READ_PREFIX_LAST)
+ if (!(table->file->index_flags(ref_key) & HA_READ_PREV))
DBUG_RETURN(0); // Use filesort
// ORDER BY range_key DESC
QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC(select->quick,
@@ -7172,7 +7164,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
Use a traversal function that starts by reading the last row
with key part (A) and then traverse the index backwards.
*/
- if (table->file->index_flags(ref_key) & HA_NOT_READ_PREFIX_LAST)
+ if (!(table->file->index_flags(ref_key) & HA_READ_PREV))
DBUG_RETURN(0); // Use filesort
tab->read_first_record= join_read_last_key;
tab->read_record.read_record= join_read_prev_same;
@@ -7226,7 +7218,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
tab->index=nr;
tab->read_first_record= (flag > 0 ? join_read_first:
join_read_last);
- table->file->index_init(nr);
tab->type=JT_NEXT; // Read with index_first(), index_next()
if (table->used_keys.is_set(nr))
{
@@ -7487,7 +7478,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
org_record=(char*) (record=table->record[0])+offset;
new_record=(char*) table->record[1]+offset;
- file->rnd_init();
+ file->ha_rnd_init();
error=file->rnd_next(record);
for (;;)
{
@@ -7599,7 +7590,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
(*field_length++)= (*ptr)->pack_length();
}
- file->rnd_init();
+ file->ha_rnd_init();
key_pos=key_buffer;
for (;;)
{
@@ -7645,14 +7636,14 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
my_free((char*) key_buffer,MYF(0));
hash_free(&hash);
file->extra(HA_EXTRA_NO_CACHE);
- (void) file->rnd_end();
+ (void) file->ha_rnd_end();
DBUG_RETURN(0);
err:
my_free((char*) key_buffer,MYF(0));
hash_free(&hash);
file->extra(HA_EXTRA_NO_CACHE);
- (void) file->rnd_end();
+ (void) file->ha_rnd_end();
if (error)
file->print_error(error,MYF(0));
DBUG_RETURN(1);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 8682b98a69a..70b6e44d59f 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -529,7 +529,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
break;
case FIELD_TYPE_GEOMETRY:
#ifdef HAVE_SPATIAL
- if (!(file->table_flags() & HA_HAS_GEOMETRY))
+ if (!(file->table_flags() & HA_CAN_GEOMETRY))
{
my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
MYF(0), "GEOMETRY");
@@ -667,7 +667,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
continue;
}
(*key_count)++;
- tmp=max(file->max_key_parts(),MAX_REF_PARTS);
+ tmp=file->max_key_parts();
if (key->columns.elements > tmp)
{
my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
@@ -719,7 +719,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(-1);
}
}
- tmp=min(file->max_keys(), MAX_KEY);
+ tmp=file->max_keys();
if (*key_count > tmp)
{
my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
@@ -879,7 +879,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
if (f_is_blob(sql_field->pack_flag))
{
- if (!(file->table_flags() & HA_BLOB_KEY))
+ if (!(file->table_flags() & HA_CAN_INDEX_BLOBS))
{
my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0),
column->field_name);
@@ -916,7 +916,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
else
key_info->flags|= HA_NULL_PART_KEY;
- if (!(file->table_flags() & HA_NULL_KEY))
+ if (!(file->table_flags() & HA_NULL_IN_KEY))
{
my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX),
MYF(0),column->field_name);
@@ -1048,7 +1048,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
if (!(key_info->flags & HA_NULL_PART_KEY))
unique_key=1;
key_info->key_length=(uint16) key_length;
- uint max_key_length= min(file->max_key_length(), MAX_KEY_LENGTH);
+ uint max_key_length= file->max_key_length();
if (key_length > max_key_length && key->type != Key::FULLTEXT)
{
my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
@@ -1140,12 +1140,21 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
alias= table_case_name(create_info, table_name);
file=get_new_handler((TABLE*) 0, create_info->db_type);
+#ifdef NOT_USED
+ /*
+ if there is a technical reason for a handler not to have support
+ for temp. tables this code can be re-enabled.
+ Otherwise, if a handler author has a wish to prohibit usage of
+ temporary tables for his handler he should implement a check in
+ ::create() method
+ */
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
(file->table_flags() & HA_NO_TEMP_TABLES))
{
my_error(ER_ILLEGAL_HA,MYF(0),table_name);
DBUG_RETURN(-1);
}
+#endif
if (mysql_prepare_table(thd, create_info, fields,
keys, tmp_table, db_options, file,
@@ -3398,7 +3407,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
current query id */
t->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
- if (t->file->rnd_init(1))
+ if (t->file->ha_rnd_init(1))
protocol->store_null();
else
{
@@ -3426,6 +3435,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
crc+= row_crc;
}
protocol->store((ulonglong)crc);
+ t->file->ha_rnd_end();
}
}
thd->clear_error();
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 2428aac2da5..af8a9705e95 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -319,6 +319,7 @@ int mysql_update(THD *thd,
error= 1; // Aborted
end_read_record(&info);
free_io_cache(table); // If ORDER BY
+ delete select;
thd->proc_info="end";
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
@@ -358,7 +359,6 @@ int mysql_update(THD *thd,
thd->lock=0;
}
- delete select;
free_underlaid_joins(thd, &thd->lex->select_lex);
if (error >= 0)
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); /* purecov: inspected */
@@ -964,25 +964,24 @@ int multi_update::do_updates(bool from_send_error)
TABLE_LIST *cur_table;
int local_error;
ha_rows org_updated;
- TABLE *table;
+ TABLE *table, *tmp_table;
DBUG_ENTER("do_updates");
-
- do_update= 0; // Don't retry this function
+
+ do_update= 0; // Don't retry this function
if (!found)
DBUG_RETURN(0);
for (cur_table= update_tables; cur_table ; cur_table= cur_table->next)
{
byte *ref_pos;
- TABLE *tmp_table;
-
+
table = cur_table->table;
if (table == table_to_update)
continue; // Already updated
org_updated= updated;
tmp_table= tmp_tables[cur_table->shared];
tmp_table->file->extra(HA_EXTRA_CACHE); // Change to read cache
- (void) table->file->rnd_init(0);
+ (void) table->file->ha_rnd_init(0);
table->file->extra(HA_EXTRA_NO_CACHE);
/*
@@ -998,7 +997,7 @@ int multi_update::do_updates(bool from_send_error)
}
copy_field_end=copy_field_ptr;
- if ((local_error = tmp_table->file->rnd_init(1)))
+ if ((local_error = tmp_table->file->ha_rnd_init(1)))
goto err;
ref_pos= (byte*) tmp_table->field[0]->ptr;
@@ -1049,7 +1048,8 @@ int multi_update::do_updates(bool from_send_error)
else
trans_safe= 0; // Can't do safe rollback
}
- (void) table->file->rnd_end();
+ (void) table->file->ha_rnd_end();
+ (void) tmp_table->file->ha_rnd_end();
}
DBUG_RETURN(0);
@@ -1057,6 +1057,9 @@ err:
if (!from_send_error)
table->file->print_error(local_error,MYF(0));
+ (void) table->file->ha_rnd_end();
+ (void) tmp_table->file->ha_rnd_end();
+
if (updated != org_updated)
{
if (table->tmp_table != NO_TMP_TABLE)
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index dc6968bb15a..8b5eb6867db 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -255,7 +255,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token IDENT_QUOTED
%token IGNORE_SYM
%token IMPORT
-%token INDEX
+%token INDEX_SYM
%token INDEXES
%token INFILE
%token INNER_SYM
@@ -936,7 +936,7 @@ create:
}
create2
{ Lex->current_select= &Lex->select_lex; }
- | CREATE opt_unique_or_fulltext INDEX ident key_alg ON table_ident
+ | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_CREATE_INDEX;
@@ -1120,7 +1120,7 @@ create_table_option:
| INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
| DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
{ Lex->create_info.data_file_name= $4.str; }
- | INDEX DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; };
+ | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; };
storage_engines:
ident_or_text
@@ -1641,7 +1641,7 @@ constraint_key_type:
key_or_index:
KEY_SYM {}
- | INDEX {};
+ | INDEX_SYM {};
opt_key_or_index:
/* empty */ {}
@@ -1650,7 +1650,7 @@ opt_key_or_index:
keys_or_index:
KEYS {}
- | INDEX {}
+ | INDEX_SYM {}
| INDEXES {};
opt_unique_or_fulltext:
@@ -2129,7 +2129,7 @@ table_to_table:
};
keycache:
- CACHE_SYM INDEX keycache_list IN_SYM key_cache_name
+ CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_ASSIGN_TO_KEYCACHE;
@@ -2160,7 +2160,7 @@ key_cache_name:
;
preload:
- LOAD INDEX INTO CACHE_SYM
+ LOAD INDEX_SYM INTO CACHE_SYM
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_PRELOAD_KEYS;
@@ -3763,7 +3763,7 @@ drop:
lex->drop_temporary= $2;
lex->drop_if_exists= $4;
}
- | DROP INDEX ident ON table_ident {}
+ | DROP INDEX_SYM ident ON table_ident {}
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_DROP_INDEX;
@@ -5429,7 +5429,7 @@ grant_privilege:
| REFERENCES { Lex->which_columns = REFERENCES_ACL;} opt_column_list {}
| DELETE_SYM { Lex->grant |= DELETE_ACL;}
| USAGE {}
- | INDEX { Lex->grant |= INDEX_ACL;}
+ | INDEX_SYM { Lex->grant |= INDEX_ACL;}
| ALTER { Lex->grant |= ALTER_ACL;}
| CREATE { Lex->grant |= CREATE_ACL;}
| DROP { Lex->grant |= DROP_ACL;}
diff --git a/sql/table.cc b/sql/table.cc
index 73f036aed87..0bd6d094ea5 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -494,15 +494,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
for (uint key=0 ; key < outparam->keys ; key++,keyinfo++)
{
uint usable_parts=0;
- ulong index_flags;
keyinfo->name=(char*) outparam->keynames.type_names[key];
/* Fix fulltext keys for old .frm files */
if (outparam->key_info[key].flags & HA_FULLTEXT)
outparam->key_info[key].algorithm= HA_KEY_ALG_FULLTEXT;
/* This has to be done after the above fulltext correction */
- index_flags=outparam->file->index_flags(key);
- if (!(index_flags & HA_KEY_READ_ONLY))
+ if (!(outparam->file->index_flags(key) & HA_KEYREAD_ONLY))
{
outparam->read_only_keys.set_bit(key);
outparam->keys_for_keyread.clear_bit(key);
@@ -577,15 +575,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if (field->key_length() == key_part->length &&
!(field->flags & BLOB_FLAG))
{
- if ((index_flags & HA_KEY_READ_ONLY) &&
- (field->key_type() != HA_KEYTYPE_TEXT ||
- (!((ha_option & HA_KEY_READ_WRONG_STR) ||
- (field->flags & BINARY_FLAG)) &&
- !(keyinfo->flags & HA_FULLTEXT))))
+ if (outparam->file->index_flags(key, i) & HA_KEYREAD_ONLY)
field->part_of_key.set_bit(key);
- if ((field->key_type() != HA_KEYTYPE_TEXT ||
- !(keyinfo->flags & HA_FULLTEXT)) &&
- !(index_flags & HA_WRONG_ASCII_ORDER))
+ if (outparam->file->index_flags(key, i) & HA_READ_ORDER)
field->part_of_sortkey.set_bit(key);
}
if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&