[Commits] 8c1ff9c1ab7: MDEV-21794: Optimizer flag rowid_filter leads to long query
revision-id: 8c1ff9c1ab750d9b46fb8df15740bdee76ca26d5 (mariadb-10.4.11-88-g8c1ff9c1ab7) parent(s): a17a327f116302612a889af7c448ef1cd8243f28 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2020-03-13 01:06:44 +0300 message: MDEV-21794: Optimizer flag rowid_filter leads to long query Variant #2. The issue is the same as Index Condition Pushdown had: before checking pushed index condition (or rowid filter), we must check that we have not walked out of the range we are scanning. If we fail to check this, we may end up scanning till the end of the table which is a huge performance killer for queries that scan small ranges. The solution is the same as in ICP: if we haven't make the end-of-range check for ICP, make it in the Rowid Filter callback. --- include/my_compare.h | 49 +++++++++++---------- mysql-test/main/rowid_filter_innodb.result | 70 ++++++++++++++++++++++++++++++ mysql-test/main/rowid_filter_innodb.test | 43 ++++++++++++++++++ sql/handler.cc | 34 +++++++++++---- sql/handler.h | 7 +-- storage/innobase/row/row0sel.cc | 69 ++++++++++++++++------------- storage/maria/ha_maria.h | 4 +- storage/maria/ma_key.c | 22 +++++----- storage/maria/ma_rkey.c | 8 ++-- storage/maria/ma_rnext.c | 6 +-- storage/maria/ma_rnext_same.c | 6 +-- storage/maria/ma_rprev.c | 6 +-- storage/maria/maria_def.h | 2 +- storage/myisam/ha_myisam.h | 4 +- storage/myisam/mi_extra.c | 2 +- storage/myisam/mi_key.c | 17 +++----- storage/myisam/mi_rkey.c | 10 ++--- storage/myisam/mi_rnext.c | 8 ++-- storage/myisam/mi_rnext_same.c | 8 ++-- storage/myisam/mi_rprev.c | 8 ++-- storage/myisam/myisamdef.h | 8 ++-- 21 files changed, 265 insertions(+), 126 deletions(-) diff --git a/include/my_compare.h b/include/my_compare.h index 6568e5f2f27..9ae6c9582fb 100644 --- a/include/my_compare.h +++ b/include/my_compare.h @@ -127,31 +127,32 @@ extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, const uchar *a); #endif /** - Return values of index_cond_func_xxx functions. - - 0=ICP_NO_MATCH - index tuple doesn't satisfy the pushed index condition (the - engine should discard the tuple and go to the next one) - 1=ICP_MATCH - index tuple satisfies the pushed index condition (the - engine should fetch and return the record) - 2=ICP_OUT_OF_RANGE - index tuple is out range that we're scanning, e.g. this - if we're scanning "t.key BETWEEN 10 AND 20" and got a - "t.key=21" tuple (the engine should stop scanning and - return HA_ERR_END_OF_FILE right away). - 3=ICP_ABORTED_BY_USER - engine must stop scanning and should return - HA_ERR_ABORTED_BY_USER right away - -1= ICP_ERROR - Reserved for internal errors in engines. Should not be - returned by index_cond_func_xxx + Return values for pushed index condition or rowid filter check functions. + + 0=CHECK_NEG - The filter is not satisfied. The engine should discard this + index tuple and continue the scan. + 1=CHECK_POS - The filter is statisfied. Current index tuple should be + returned to the SQL layer. + 2=CHECK_OUT_OF_RANGE - the index tuple is outside of the range that we're + scanning. (Example: if we're scanning "t.key BETWEEN 10 AND + 20" and got a "t.key=21" tuple) Tthe engine should stop + scanning and return HA_ERR_END_OF_FILE right away). + 3=CHECK_ABORTED_BY_USER - the engine must stop scanning and should return + HA_ERR_ABORTED_BY_USER right away + -1=CHECK_ERROR - Reserved for internal errors in engines. Should not be + returned by ICP or rowid filter check functions. */ -typedef enum icp_result { - ICP_ERROR=-1, - ICP_NO_MATCH=0, - ICP_MATCH=1, - ICP_OUT_OF_RANGE=2, - ICP_ABORTED_BY_USER=3 -} ICP_RESULT; - -typedef ICP_RESULT (*index_cond_func_t)(void *param); -typedef int (*rowid_filter_func_t)(void *param); +typedef enum check_result { + CHECK_ERROR=-1, + CHECK_NEG=0, + CHECK_POS=1, + CHECK_OUT_OF_RANGE=2, + CHECK_ABORTED_BY_USER=3 +} check_result_t; + +typedef check_result_t (*index_cond_func_t)(void *param); +typedef check_result_t (*rowid_filter_func_t)(void *param); +typedef int (*rowid_filter_is_active_func_t)(void *param); #endif /* _my_compare_h */ diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result index 9423fb18fd9..829ad99846c 100644 --- a/mysql-test/main/rowid_filter_innodb.result +++ b/mysql-test/main/rowid_filter_innodb.result @@ -2521,6 +2521,76 @@ ORDER BY pk LIMIT 1; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra 1 SIMPLE t1 index a,b PRIMARY 4 NULL 3008 3008.00 1.36 0.00 Using where DROP TABLE t1; +# +# MDEV-21794: Optimizer flag rowid_filter leads to long query +# +create table t10(a int); +insert into t10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t11(a int); +insert into t11 select A.a + B.a* 10 + C.a * 100 from t10 A, t10 B, t10 C; +CREATE TABLE t1 ( +el_id int(10) unsigned NOT NULL , +el_index blob NOT NULL, +el_index_60 varbinary(60) NOT NULL, +filler blob, +PRIMARY KEY (el_id), +KEY el_index (el_index(60)), +KEY el_index_60 (el_index_60,el_id) +) engine=innodb; +insert into t1 +select +A.a+1000*B.a, +A.a+1000*B.a + 10000, +A.a+1000*B.a + 10000, +'filler-data-filler-data' +from +t11 A, t10 B; +# This must have key=el_index|el_index_60 +explain +select * from t1 +where el_index like '10%' and (el_index_60 like '10%' or el_index_60 like '20%'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range|filter el_index,el_index_60 el_index|el_index_60 62|62 NULL 1000 (10%) Using where; Using rowid filter +# This must show r_filtered=100%. r_filtered=10% means the bug is there. +analyze format=json +select * from t1 +where el_index like '10%' and (el_index_60 like '10%' or el_index_60 like '20%'); +ANALYZE +{ + "query_block": { + "select_id": 1, + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "table": { + "table_name": "t1", + "access_type": "range", + "possible_keys": ["el_index", "el_index_60"], + "key": "el_index", + "key_length": "62", + "used_key_parts": ["el_index"], + "rowid_filter": { + "range": { + "key": "el_index_60", + "used_key_parts": ["el_index_60"] + }, + "rows": "REPLACED", + "selectivity_pct": "REPLACED", + "r_rows": 1000, + "r_selectivity_pct": 100, + "r_buffer_size": "REPLACED", + "r_filling_time_ms": "REPLACED" + }, + "r_loops": 1, + "rows": "REPLACED", + "r_rows": 1000, + "r_total_time_ms": "REPLACED", + "filtered": "REPLACED", + "r_filtered": 100, + "attached_condition": "t1.el_index like '10%' and (t1.el_index_60 like '10%' or t1.el_index_60 like '20%')" + } + } +} +drop table t10, t11, t1; SET global innodb_stats_persistent= @stats.save; # # MDEV-21610: Using rowid filter with BKA+MRR diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test index 74349b8c6bb..36af2a30e56 100644 --- a/mysql-test/main/rowid_filter_innodb.test +++ b/mysql-test/main/rowid_filter_innodb.test @@ -380,6 +380,49 @@ SELECT * FROM t1 ORDER BY pk LIMIT 1; DROP TABLE t1; + +--echo # +--echo # MDEV-21794: Optimizer flag rowid_filter leads to long query +--echo # +create table t10(a int); +insert into t10 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t11(a int); +insert into t11 select A.a + B.a* 10 + C.a * 100 from t10 A, t10 B, t10 C; + + +CREATE TABLE t1 ( + el_id int(10) unsigned NOT NULL , + el_index blob NOT NULL, + el_index_60 varbinary(60) NOT NULL, + filler blob, + + PRIMARY KEY (el_id), + KEY el_index (el_index(60)), + KEY el_index_60 (el_index_60,el_id) +) engine=innodb; + +insert into t1 +select + A.a+1000*B.a, + A.a+1000*B.a + 10000, + A.a+1000*B.a + 10000, + 'filler-data-filler-data' +from + t11 A, t10 B; + +--echo # This must have key=el_index|el_index_60 +explain +select * from t1 +where el_index like '10%' and (el_index_60 like '10%' or el_index_60 like '20%'); + +--echo # This must show r_filtered=100%. r_filtered=10% means the bug is there. +--source include/analyze-format-and-estimates.inc +analyze format=json +select * from t1 +where el_index like '10%' and (el_index_60 like '10%' or el_index_60 like '20%'); + +drop table t10, t11, t1; SET global innodb_stats_persistent= @stats.save; --echo # diff --git a/sql/handler.cc b/sql/handler.cc index 77b7f490590..ad9320bd135 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5957,22 +5957,22 @@ int handler::compare_key2(key_range *range) const /** ICP callback - to be called by an engine to check the pushed condition */ -extern "C" enum icp_result handler_index_cond_check(void* h_arg) +extern "C" check_result_t handler_index_cond_check(void* h_arg) { handler *h= (handler*)h_arg; THD *thd= h->table->in_use; - enum icp_result res; + check_result_t res; enum thd_kill_levels abort_at= h->has_transactions() ? THD_ABORT_SOFTLY : THD_ABORT_ASAP; if (thd_kill_level(thd) > abort_at) - return ICP_ABORTED_BY_USER; + return CHECK_ABORTED_BY_USER; if (h->end_range && h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; + return CHECK_OUT_OF_RANGE; h->increment_statistics(&SSV::ha_icp_attempts); - if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == - ICP_MATCH) + if ((res= h->pushed_idx_cond->val_int()? CHECK_POS : CHECK_NEG) == + CHECK_POS) h->increment_statistics(&SSV::ha_icp_match); return res; } @@ -5983,12 +5983,30 @@ extern "C" enum icp_result handler_index_cond_check(void* h_arg) keys of the rows whose data is to be fetched against the used rowid filter */ -extern "C" int handler_rowid_filter_check(void *h_arg) +extern "C" +check_result_t handler_rowid_filter_check(void *h_arg) { handler *h= (handler*) h_arg; TABLE *tab= h->get_table(); + + /* + Check for out-of-range and killed conditions only if we haven't done it + already in the pushed index condition check + */ + if (!h->pushed_idx_cond) + { + THD *thd= h->table->in_use; + enum thd_kill_levels abort_at= h->has_transactions() ? + THD_ABORT_SOFTLY : THD_ABORT_ASAP; + if (thd_kill_level(thd) > abort_at) + return CHECK_ABORTED_BY_USER; + + if (h->end_range && h->compare_key2(h->end_range) > 0) + return CHECK_OUT_OF_RANGE; + } + h->position(tab->record[0]); - return h->pushed_rowid_filter->check((char *) h->ref); + return h->pushed_rowid_filter->check((char*)h->ref)? CHECK_POS: CHECK_NEG; } diff --git a/sql/handler.h b/sql/handler.h index 421941c0b35..4840115ec69 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2910,9 +2910,9 @@ class ha_statistics {} }; -extern "C" enum icp_result handler_index_cond_check(void* h_arg); +extern "C" check_result_t handler_index_cond_check(void* h_arg); -extern "C" int handler_rowid_filter_check(void* h_arg); +extern "C" check_result_t handler_rowid_filter_check(void* h_arg); extern "C" int handler_rowid_filter_is_active(void* h_arg); uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); @@ -4834,7 +4834,8 @@ class handler :public Sql_alloc virtual void set_lock_type(enum thr_lock_type lock); - friend enum icp_result handler_index_cond_check(void* h_arg); + friend check_result_t handler_index_cond_check(void* h_arg); + friend check_result_t handler_rowid_filter_check(void *h_arg); /** Find unique record by index or unique constrain diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 7b6df752043..95ffd20ac08 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -3877,9 +3877,9 @@ row_sel_try_search_shortcut_for_mysql( /*********************************************************************//** Check a pushed-down index condition. -@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ +@return CHECK_NEG, CHECK_POS, or CHECK_OUT_OF_RANGE */ static -ICP_RESULT +check_result_t row_search_idx_cond_check( /*======================*/ byte* mysql_rec, /*!< out: record @@ -3897,7 +3897,7 @@ row_search_idx_cond_check( if (!prebuilt->idx_cond) { if (!handler_rowid_filter_is_active(prebuilt->pk_filter)) { - return(ICP_MATCH); + return(CHECK_POS); } } else { MONITOR_INC(MONITOR_ICP_ATTEMPTS); @@ -3922,7 +3922,7 @@ row_search_idx_cond_check( rec, prebuilt->index, offsets, templ->icp_rec_field_no, templ)) { - return(ICP_NO_MATCH); + return(CHECK_NEG); } } @@ -3932,12 +3932,12 @@ row_search_idx_cond_check( index, if the case of the column has been updated in the past, or a record has been deleted and a record inserted in a different case. */ - ICP_RESULT result = prebuilt->idx_cond + check_result_t result = prebuilt->idx_cond ? handler_index_cond_check(prebuilt->idx_cond) - : ICP_MATCH; + : CHECK_POS; switch (result) { - case ICP_MATCH: + case CHECK_POS: if (handler_rowid_filter_is_active(prebuilt->pk_filter)) { ut_ad(!prebuilt->index->is_primary()); if (prebuilt->clust_index_was_generated) { @@ -3952,9 +3952,18 @@ row_search_idx_cond_check( ut_ad(len == DATA_ROW_ID_LEN); memcpy(prebuilt->row_id, data, DATA_ROW_ID_LEN); } - if (!handler_rowid_filter_check(prebuilt->pk_filter)) { - MONITOR_INC(MONITOR_ICP_MATCH); - return(ICP_NO_MATCH); + result = handler_rowid_filter_check(prebuilt->pk_filter); + switch (result) { + case CHECK_NEG: + MONITOR_INC(MONITOR_ICP_NO_MATCH); + return(result); + case CHECK_OUT_OF_RANGE: + MONITOR_INC(MONITOR_ICP_OUT_OF_RANGE); + return(result); + case CHECK_POS: + break; + default: + ut_error; } } /* Convert the remaining fields to MySQL format. @@ -3966,19 +3975,19 @@ row_search_idx_cond_check( mysql_rec, prebuilt, rec, NULL, false, prebuilt->index, offsets)) { ut_ad(dict_index_is_clust(prebuilt->index)); - return(ICP_NO_MATCH); + return(CHECK_NEG); } } MONITOR_INC(MONITOR_ICP_MATCH); return(result); - case ICP_NO_MATCH: + case CHECK_NEG: MONITOR_INC(MONITOR_ICP_NO_MATCH); return(result); - case ICP_OUT_OF_RANGE: + case CHECK_OUT_OF_RANGE: MONITOR_INC(MONITOR_ICP_OUT_OF_RANGE); return(result); - case ICP_ERROR: - case ICP_ABORTED_BY_USER: + case CHECK_ERROR: + case CHECK_ABORTED_BY_USER: return(result); } @@ -4414,12 +4423,12 @@ row_search_mvcc( switch (row_search_idx_cond_check( buf, prebuilt, rec, offsets)) { - case ICP_NO_MATCH: - case ICP_OUT_OF_RANGE: - case ICP_ABORTED_BY_USER: - case ICP_ERROR: + case CHECK_NEG: + case CHECK_OUT_OF_RANGE: + case CHECK_ABORTED_BY_USER: + case CHECK_ERROR: goto shortcut_mismatch; - case ICP_MATCH: + case CHECK_POS: goto shortcut_match; } } @@ -5198,14 +5207,14 @@ row_search_mvcc( index entry. */ switch (row_search_idx_cond_check( buf, prebuilt, rec, offsets)) { - case ICP_NO_MATCH: + case CHECK_NEG: goto next_rec; - case ICP_OUT_OF_RANGE: - case ICP_ABORTED_BY_USER: - case ICP_ERROR: + case CHECK_OUT_OF_RANGE: + case CHECK_ABORTED_BY_USER: + case CHECK_ERROR: err = DB_RECORD_NOT_FOUND; goto idx_cond_failed; - case ICP_MATCH: + case CHECK_POS: goto requires_clust_rec; } @@ -5255,17 +5264,17 @@ row_search_mvcc( /* Check if the record matches the index condition. */ switch (row_search_idx_cond_check(buf, prebuilt, rec, offsets)) { - case ICP_NO_MATCH: + case CHECK_NEG: if (did_semi_consistent_read) { row_unlock_for_mysql(prebuilt, TRUE); } goto next_rec; - case ICP_OUT_OF_RANGE: - case ICP_ABORTED_BY_USER: - case ICP_ERROR: + case CHECK_OUT_OF_RANGE: + case CHECK_ABORTED_BY_USER: + case CHECK_ERROR: err = DB_RECORD_NOT_FOUND; goto idx_cond_failed; - case ICP_MATCH: + case CHECK_POS: break; } diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h index ef0ceb1cd32..f6b00420c9c 100644 --- a/storage/maria/ha_maria.h +++ b/storage/maria/ha_maria.h @@ -32,7 +32,7 @@ #define HA_RECOVER_QUICK 8 /* Don't check rows in data file */ C_MODE_START -ICP_RESULT index_cond_func_maria(void *arg); +check_result_t index_cond_func_maria(void *arg); C_MODE_END extern TYPELIB maria_recover_typelib; @@ -187,7 +187,7 @@ class ha_maria :public handler int find_unique_row(uchar *record, uint unique_idx); private: DsMrr_impl ds_mrr; - friend ICP_RESULT index_cond_func_maria(void *arg); + friend check_result_t index_cond_func_maria(void *arg); friend void reset_thd_trn(THD *thd); }; diff --git a/storage/maria/ma_key.c b/storage/maria/ma_key.c index 9e804a1e9dc..5061f3d0143 100644 --- a/storage/maria/ma_key.c +++ b/storage/maria/ma_key.c @@ -666,20 +666,20 @@ int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS filepos) will look for column values there) RETURN - ICP_ERROR Error ; my_errno set to HA_ERR_CRASHED - ICP_NO_MATCH Index condition is not satisfied, continue scanning - ICP_MATCH Index condition is satisfied - ICP_OUT_OF_RANGE Index condition is not satisfied, end the scan. + CHECK_ERROR Error ; my_errno set to HA_ERR_CRASHED + CHECK_NEG Index condition is not satisfied, continue scanning + CHECK_POS Index condition is satisfied + CHECK_OUT_OF_RANGE Index condition is not satisfied, end the scan. my_errno set to HA_ERR_END_OF_FILE - info->cur_row.lastpos is set to HA_OFFSET_ERROR in case of ICP_ERROR or - ICP_OUT_OF_RANGE to indicate that we don't have any active row. + info->cur_row.lastpos is set to HA_OFFSET_ERROR in case of CHECK_ERROR or + CHECK_OUT_OF_RANGE to indicate that we don't have any active row. */ -ICP_RESULT ma_check_index_cond(register MARIA_HA *info, uint keynr, - uchar *record) +check_result_t ma_check_index_cond(register MARIA_HA *info, uint keynr, + uchar *record) { - ICP_RESULT res= ICP_MATCH; + check_result_t res= CHECK_POS; if (info->index_cond_func) { if (_ma_put_key_in_record(info, keynr, FALSE, record)) @@ -688,10 +688,10 @@ ICP_RESULT ma_check_index_cond(register MARIA_HA *info, uint keynr, maria_print_error(info->s, HA_ERR_CRASHED); info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */ my_errno= HA_ERR_CRASHED; - res= ICP_ERROR; + res= CHECK_ERROR; } else if ((res= info->index_cond_func(info->index_cond_func_arg)) == - ICP_OUT_OF_RANGE) + CHECK_OUT_OF_RANGE) { /* We got beyond the end of scanned range */ info->cur_row.lastpos= HA_OFFSET_ERROR; /* No active record */ diff --git a/storage/maria/ma_rkey.c b/storage/maria/ma_rkey.c index d19caaf6137..b48b0fc0c6b 100644 --- a/storage/maria/ma_rkey.c +++ b/storage/maria/ma_rkey.c @@ -34,7 +34,7 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data, HA_KEYSEG *last_used_keyseg; uint32 nextflag; MARIA_KEY key; - ICP_RESULT icp_res= ICP_MATCH; + check_result_t check= CHECK_POS; DBUG_ENTER("maria_rkey"); DBUG_PRINT("enter", ("base:%p buf:%p inx: %d search_flag: %d", info, buf, inx, search_flag)); @@ -115,7 +115,7 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data, not satisfied with an out-of-range condition. */ if ((*share->row_is_visible)(info) && - ((icp_res= ma_check_index_cond(info, inx, buf)) != ICP_NO_MATCH)) + ((check= ma_check_index_cond(info, inx, buf)) != CHECK_NEG)) break; /* The key references a concurrently inserted record. */ @@ -174,7 +174,7 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data, } } while (!(*share->row_is_visible)(info) || - ((icp_res= ma_check_index_cond(info, inx, buf)) == 0)); + ((check= ma_check_index_cond(info, inx, buf)) == 0)); } else { @@ -186,7 +186,7 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data, if (info->cur_row.lastpos == HA_OFFSET_ERROR) { - if (icp_res == ICP_OUT_OF_RANGE) + if (check == CHECK_OUT_OF_RANGE) { /* We don't want HA_ERR_END_OF_FILE in this particular case */ my_errno= HA_ERR_KEY_NOT_FOUND; diff --git a/storage/maria/ma_rnext.c b/storage/maria/ma_rnext.c index 5ea90a242fc..6fd6f89139f 100644 --- a/storage/maria/ma_rnext.c +++ b/storage/maria/ma_rnext.c @@ -30,7 +30,7 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx) uint flag; MARIA_SHARE *share= info->s; MARIA_KEYDEF *keyinfo; - ICP_RESULT icp_res= ICP_MATCH; + check_result_t check= CHECK_POS; uint update_mask= HA_STATE_NEXT_FOUND; DBUG_ENTER("maria_rnext"); @@ -107,7 +107,7 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx) if (!error) { while (!(*share->row_is_visible)(info) || - ((icp_res= ma_check_index_cond(info, inx, buf)) == ICP_NO_MATCH)) + ((check= ma_check_index_cond(info, inx, buf)) == CHECK_NEG)) { /* If we are at the last key on the key page, allow writers to @@ -135,7 +135,7 @@ int maria_rnext(MARIA_HA *info, uchar *buf, int inx) info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update|= update_mask; - if (error || icp_res != ICP_MATCH) + if (error || check != CHECK_POS) { fast_ma_writeinfo(info); if (my_errno == HA_ERR_KEY_NOT_FOUND) diff --git a/storage/maria/ma_rnext_same.c b/storage/maria/ma_rnext_same.c index b07967ca9e9..19a950d31bb 100644 --- a/storage/maria/ma_rnext_same.c +++ b/storage/maria/ma_rnext_same.c @@ -30,7 +30,7 @@ int maria_rnext_same(MARIA_HA *info, uchar *buf) int error; uint inx,not_used[2]; MARIA_KEYDEF *keyinfo; - ICP_RESULT icp_res= ICP_MATCH; + check_result_t check= CHECK_POS; DBUG_ENTER("maria_rnext_same"); if ((int) (inx= info->lastinx) < 0 || @@ -92,7 +92,7 @@ int maria_rnext_same(MARIA_HA *info, uchar *buf) } /* Skip rows that are inserted by other threads since we got a lock */ if ((info->s->row_is_visible)(info) && - ((icp_res= ma_check_index_cond(info, inx, buf)) != ICP_NO_MATCH)) + ((check= ma_check_index_cond(info, inx, buf)) != CHECK_NEG)) break; } } @@ -102,7 +102,7 @@ int maria_rnext_same(MARIA_HA *info, uchar *buf) info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update|= HA_STATE_NEXT_FOUND | HA_STATE_RNEXT_SAME; - if (error || icp_res != ICP_MATCH) + if (error || check != CHECK_POS) { fast_ma_writeinfo(info); if (my_errno == HA_ERR_KEY_NOT_FOUND) diff --git a/storage/maria/ma_rprev.c b/storage/maria/ma_rprev.c index eebc8cba0c7..15010d962bb 100644 --- a/storage/maria/ma_rprev.c +++ b/storage/maria/ma_rprev.c @@ -28,7 +28,7 @@ int maria_rprev(MARIA_HA *info, uchar *buf, int inx) register uint flag; MARIA_SHARE *share= info->s; MARIA_KEYDEF *keyinfo; - ICP_RESULT icp_res= ICP_MATCH; + check_result_t check= CHECK_POS; DBUG_ENTER("maria_rprev"); if ((inx = _ma_check_index(info,inx)) < 0) @@ -58,7 +58,7 @@ int maria_rprev(MARIA_HA *info, uchar *buf, int inx) { my_off_t cur_keypage= info->last_keypage; while (!(*share->row_is_visible)(info) || - ((icp_res= ma_check_index_cond(info, inx, buf)) == ICP_NO_MATCH)) + ((check= ma_check_index_cond(info, inx, buf)) == CHECK_NEG)) { /* If we are at the last (i.e. first?) key on the key page, @@ -86,7 +86,7 @@ int maria_rprev(MARIA_HA *info, uchar *buf, int inx) info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update|= HA_STATE_PREV_FOUND; - if (error || icp_res != ICP_MATCH) + if (error || check != CHECK_POS) { fast_ma_writeinfo(info); if (my_errno == HA_ERR_KEY_NOT_FOUND) diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 3c0574fd783..c89623daea9 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -1433,7 +1433,7 @@ extern my_bool maria_flush_log_for_page_none(PAGECACHE_IO_HOOK_ARGS *args); extern PAGECACHE *maria_log_pagecache; extern void ma_set_index_cond_func(MARIA_HA *info, index_cond_func_t func, void *func_arg); -ICP_RESULT ma_check_index_cond(MARIA_HA *info, uint keynr, uchar *record); +check_result_t ma_check_index_cond(MARIA_HA *info, uint keynr, uchar *record); extern my_bool ma_yield_and_check_if_killed(MARIA_HA *info, int inx); extern my_bool ma_killed_standalone(MARIA_HA *); diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 0af4215e8f9..70c99a617f6 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -38,7 +38,7 @@ extern const char *myisam_recover_names[]; extern ulonglong myisam_recover_options; C_MODE_START -ICP_RESULT index_cond_func_myisam(void *arg); +check_result_t index_cond_func_myisam(void *arg); C_MODE_END class ha_myisam: public handler @@ -175,5 +175,5 @@ class ha_myisam: public handler private: DsMrr_impl ds_mrr; - friend ICP_RESULT index_cond_func_myisam(void *arg); + friend check_result_t index_cond_func_myisam(void *arg); }; diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c index d1bf903bd46..67cb714e7bf 100644 --- a/storage/myisam/mi_extra.c +++ b/storage/myisam/mi_extra.c @@ -424,7 +424,7 @@ void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t func, void mi_set_rowid_filter_func(MI_INFO *info, rowid_filter_func_t check_func, - rowid_filter_func_t is_active_func, + rowid_filter_is_active_func_t is_active_func, void *func_arg) { info->rowid_filter_func= check_func; diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c index dd838a05ada..0cf920fcd15 100644 --- a/storage/myisam/mi_key.c +++ b/storage/myisam/mi_key.c @@ -501,26 +501,23 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, uchar *buf) will look for column values there) RETURN - ICP_ERROR Error - ICP_NO_MATCH Index condition is not satisfied, continue scanning - ICP_MATCH Index condition is satisfied - ICP_OUT_OF_RANGE Index condition is not satisfied, end the scan. + Check result according to enum check_result definition */ -ICP_RESULT mi_check_index_cond(register MI_INFO *info, uint keynr, - uchar *record) +check_result_t mi_check_index_cond(register MI_INFO *info, uint keynr, + uchar *record) { - ICP_RESULT res; + check_result_t res; if (_mi_put_key_in_record(info, keynr, FALSE, record)) { /* Impossible case; Can only happen if bug in code */ mi_print_error(info->s, HA_ERR_CRASHED); info->lastpos= HA_OFFSET_ERROR; /* No active record */ my_errno= HA_ERR_CRASHED; - res= ICP_ERROR; + res= CHECK_ERROR; } else if ((res= info->index_cond_func(info->index_cond_func_arg)) == - ICP_OUT_OF_RANGE) + CHECK_OUT_OF_RANGE) { /* We got beyond the end of scanned range */ info->lastpos= HA_OFFSET_ERROR; /* No active record */ @@ -530,7 +527,7 @@ ICP_RESULT mi_check_index_cond(register MI_INFO *info, uint keynr, } -int mi_check_rowid_filter(MI_INFO *info) +check_result_t mi_check_rowid_filter(MI_INFO *info) { return info->rowid_filter_func(info->rowid_filter_func_arg); } diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c index 8ef1d917f38..02dab192aa0 100644 --- a/storage/myisam/mi_rkey.c +++ b/storage/myisam/mi_rkey.c @@ -30,7 +30,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, MI_KEYDEF *keyinfo; HA_KEYSEG *last_used_keyseg; uint pack_key_length, use_key_length, nextflag; - ICP_RESULT res= ICP_NO_MATCH; + check_result_t res= CHECK_NEG; DBUG_ENTER("mi_rkey"); DBUG_PRINT("enter", ("base: %p buf: %p inx: %d search_flag: %d", info, buf, inx, search_flag)); @@ -120,9 +120,9 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, (search_flag != HA_READ_KEY_EXACT || last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) || (info->index_cond_func && - (res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH) || + (res= mi_check_index_cond(info, inx, buf)) == CHECK_NEG) || (mi_check_rowid_filter_is_active(info) && - !mi_check_rowid_filter(info))) + (res= mi_check_rowid_filter(info)) == CHECK_NEG)) { uint not_used[2]; /* @@ -162,12 +162,12 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, /* Aborted by user */ DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR && my_errno == HA_ERR_ABORTED_BY_USER); - res= ICP_ERROR; + res= CHECK_ERROR; buf= 0; /* Fast abort */ break; } } - if (res == ICP_OUT_OF_RANGE) + if (res == CHECK_OUT_OF_RANGE) { /* Change error from HA_ERR_END_OF_FILE */ DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR); diff --git a/storage/myisam/mi_rnext.c b/storage/myisam/mi_rnext.c index 9f5f4702ed2..0bfb28cd66f 100644 --- a/storage/myisam/mi_rnext.c +++ b/storage/myisam/mi_rnext.c @@ -28,7 +28,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx) { int error,changed; uint flag; - ICP_RESULT icp_res= ICP_MATCH; + check_result_t check= CHECK_POS; uint update_mask= HA_STATE_NEXT_FOUND; DBUG_ENTER("mi_rnext"); @@ -102,9 +102,9 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx) while ((info->s->concurrent_insert && info->lastpos >= info->state->data_file_length) || (info->index_cond_func && - (icp_res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH) || + (check= mi_check_index_cond(info, inx, buf)) == CHECK_NEG) || (mi_check_rowid_filter_is_active(info) && - !mi_check_rowid_filter(info))) + (check= mi_check_rowid_filter(info)) == CHECK_NEG)) { /* If we are at the last key on the key page, allow writers to @@ -137,7 +137,7 @@ int mi_rnext(MI_INFO *info, uchar *buf, int inx) info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update|= update_mask; - if (error || icp_res != ICP_MATCH) + if (error || check != CHECK_POS) { fast_mi_writeinfo(info); if (my_errno == HA_ERR_KEY_NOT_FOUND) diff --git a/storage/myisam/mi_rnext_same.c b/storage/myisam/mi_rnext_same.c index ee6b962c8c3..075e7c4d33a 100644 --- a/storage/myisam/mi_rnext_same.c +++ b/storage/myisam/mi_rnext_same.c @@ -30,7 +30,7 @@ int mi_rnext_same(MI_INFO *info, uchar *buf) int error; uint inx,not_used[2]; MI_KEYDEF *keyinfo; - ICP_RESULT icp_res= ICP_MATCH; + check_result_t check= CHECK_POS; DBUG_ENTER("mi_rnext_same"); if ((int) (inx=info->lastinx) < 0 || info->lastpos == HA_OFFSET_ERROR) @@ -95,9 +95,9 @@ int mi_rnext_same(MI_INFO *info, uchar *buf) */ if (info->lastpos < info->state->data_file_length && (!info->index_cond_func || - (icp_res= mi_check_index_cond(info, inx, buf)) != ICP_NO_MATCH) && + (check= mi_check_index_cond(info, inx, buf)) != CHECK_NEG) && (!mi_check_rowid_filter_is_active(info) || - mi_check_rowid_filter(info))) + (check= mi_check_rowid_filter(info)) != CHECK_NEG)) break; } } @@ -109,7 +109,7 @@ int mi_rnext_same(MI_INFO *info, uchar *buf) info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update|= HA_STATE_NEXT_FOUND | HA_STATE_RNEXT_SAME; - if (error || icp_res != ICP_MATCH) + if (error || check != CHECK_POS) { fast_mi_writeinfo(info); if (my_errno == HA_ERR_KEY_NOT_FOUND) diff --git a/storage/myisam/mi_rprev.c b/storage/myisam/mi_rprev.c index cac0d672765..d6700133614 100644 --- a/storage/myisam/mi_rprev.c +++ b/storage/myisam/mi_rprev.c @@ -28,7 +28,7 @@ int mi_rprev(MI_INFO *info, uchar *buf, int inx) int error,changed; register uint flag; MYISAM_SHARE *share=info->s; - ICP_RESULT icp_res= ICP_MATCH; + check_result_t check= CHECK_POS; DBUG_ENTER("mi_rprev"); if ((inx = _mi_check_index(info,inx)) < 0) @@ -59,9 +59,9 @@ int mi_rprev(MI_INFO *info, uchar *buf, int inx) while ((share->concurrent_insert && info->lastpos >= info->state->data_file_length) || (info->index_cond_func && - (icp_res= mi_check_index_cond(info, inx, buf)) == ICP_NO_MATCH) || + (check= mi_check_index_cond(info, inx, buf)) == CHECK_NEG) || (mi_check_rowid_filter_is_active(info) && - !mi_check_rowid_filter(info))) + (check= mi_check_rowid_filter(info)) == CHECK_NEG)) { /* If we are at the last (i.e. first?) key on the key page, @@ -95,7 +95,7 @@ int mi_rprev(MI_INFO *info, uchar *buf, int inx) info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); info->update|= HA_STATE_PREV_FOUND; - if (error || icp_res != ICP_MATCH) + if (error || check != CHECK_POS) { fast_mi_writeinfo(info); if (my_errno == HA_ERR_KEY_NOT_FOUND) diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index f7b61ae638c..a02f8fd6cb7 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -307,7 +307,7 @@ struct st_myisam_info index_cond_func_t index_cond_func; /* Index condition function */ void *index_cond_func_arg; /* parameter for the func */ rowid_filter_func_t rowid_filter_func; /* rowid filter check function */ - rowid_filter_func_t rowid_filter_is_active_func; /* is activefunction */ + rowid_filter_is_active_func_t rowid_filter_is_active_func; /* is activefunction */ void *rowid_filter_func_arg; /* parameter for the func */ THR_LOCK_DATA lock; uchar *rtree_recursion_state; /* For RTREE */ @@ -725,8 +725,8 @@ my_bool mi_dynmap_file(MI_INFO *info, my_off_t size); int mi_munmap_file(MI_INFO *info); void mi_remap_file(MI_INFO *info, my_off_t size); -ICP_RESULT mi_check_index_cond(MI_INFO *info, uint keynr, uchar *record); -int mi_check_rowid_filter(MI_INFO *info); +check_result_t mi_check_index_cond(MI_INFO *info, uint keynr, uchar *record); +check_result_t mi_check_rowid_filter(MI_INFO *info); int mi_check_rowid_filter_is_active(MI_INFO *info); /* Functions needed by mi_check */ int killed_ptr(HA_CHECK *param); @@ -738,7 +738,7 @@ extern void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t check_func, void *func_arg); extern void mi_set_rowid_filter_func(MI_INFO *info, rowid_filter_func_t check_func, - rowid_filter_func_t is_active_func, + rowid_filter_is_active_func_t is_active_func, void *func_arg); int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file, ulonglong *dirty_part_map);
participants (1)
-
psergey