diff options
author | Jan Lindström <jplindst@mariadb.org> | 2014-05-09 11:43:53 +0300 |
---|---|---|
committer | Jan Lindström <jplindst@mariadb.org> | 2014-05-09 11:43:53 +0300 |
commit | dabf4715475a2f80de319a440d4153a5434b2fbf (patch) | |
tree | 46096ed191e946ce31a6a7824c6cd9d26510fc20 /storage/xtradb | |
parent | 229dad1f9b12f8e9f64b6a605bdf8e31c339d018 (diff) | |
download | mariadb-git-dabf4715475a2f80de319a440d4153a5434b2fbf.tar.gz |
MDEV-4791: Assertion range_end >= range_start fails in log0online.c
on select from I_S.INNODB_CHANGED_PAGES
Analysis: limit_lsn_range_from_condition() incorrectly parses
start_lsn and/or end_lsn conditions.
Fix from SergeyP. Added some test cases.
Diffstat (limited to 'storage/xtradb')
-rw-r--r-- | storage/xtradb/handler/i_s.cc | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 70819ba6395..4a66065788f 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -8205,38 +8205,47 @@ limit_lsn_range_from_condition( if (left->type() == Item::FIELD_ITEM && right->type() == Item::INT_ITEM) { - /* The case of start_lsn|end_lsn <|<= const, i.e. the - upper bound. */ - - tmp_result = right->val_int(); - if (((func_type == Item_func::LE_FUNC) - || (func_type == Item_func::GE_FUNC)) - && (tmp_result != IB_UINT64_MAX)) { - - tmp_result++; - } - if (tmp_result < *end_lsn) { - *end_lsn = tmp_result; + /* The case of start_lsn|end_lsn <|<= const + "end_lsn <=? const" gives a valid upper bound. + "start_lsn <=? const" is not a valid upper bound. + */ + + if (is_end_lsn) { + tmp_result = right->val_int(); + if (((func_type == Item_func::LE_FUNC) + || (func_type == Item_func::GE_FUNC)) + && (tmp_result != IB_UINT64_MAX)) { + + tmp_result++; + } + if (tmp_result < *end_lsn) { + *end_lsn = tmp_result; + } } } else if (left->type() == Item::INT_ITEM && right->type() == Item::FIELD_ITEM) { - /* The case of const <|<= start_lsn|end_lsn, i.e. the - lower bound */ + /* The case of const <|<= start_lsn|end_lsn + turning it around: start_lsn|end_lsn >|>= const + "start_lsn >=? const " is a valid loer bound. + "end_lsn >=? const" is not a valid lower bound. + */ - tmp_result = left->val_int(); - if (is_end_lsn && tmp_result != 0) { - tmp_result--; - } - if (((func_type == Item_func::LT_FUNC) - || (func_type == Item_func::GT_FUNC)) - && (tmp_result != IB_UINT64_MAX)) { + if (!is_end_lsn) { + tmp_result = left->val_int(); + if (is_end_lsn && tmp_result != 0) { + tmp_result--; + } + if (((func_type == Item_func::LT_FUNC) + || (func_type == Item_func::GT_FUNC)) + && (tmp_result != IB_UINT64_MAX)) { - tmp_result++; - } - if (tmp_result > *start_lsn) { - *start_lsn = tmp_result; + tmp_result++; + } + if (tmp_result > *start_lsn) { + *start_lsn = tmp_result; + } } } |