1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
/* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#ifndef SQL_RANGE_OPTIMIZER_REVERSE_INDEX_RANGE_SCAN_H_
#define SQL_RANGE_OPTIMIZER_REVERSE_INDEX_RANGE_SCAN_H_
#include <sys/types.h>
#include "sql/range_optimizer/index_range_scan.h"
#include "sql/range_optimizer/range_optimizer.h"
#include "sql/sql_list.h"
/**
An iterator much like IndexRangeScanIterator, but it scans in the reverse
order. This makes it at times more complicated, but since it doesn't support
being a part of a ROR scan, it is also less complicated in many ways.
One could argue that this and IndexRangeScanIterator should be factored into
a common base class with separate _ASC and _DESC classes, but they don't
actually duplicate that much code.
*/
class ReverseIndexRangeScanIterator : public TableRowIterator {
public:
ReverseIndexRangeScanIterator(THD *thd, TABLE *table, ha_rows *examined_rows,
double expected_rows, uint index,
MEM_ROOT *return_mem_root, uint mrr_flags,
Bounds_checked_array<QUICK_RANGE *> ranges,
bool using_extended_key_parts);
~ReverseIndexRangeScanIterator() override;
int Read() override;
bool Init() override;
private:
static range_seq_t quick_range_rev_seq_init(void *init_param, uint, uint);
const uint m_index; /* Index this quick select uses */
const double m_expected_rows;
ha_rows *m_examined_rows;
MEM_ROOT *mem_root;
bool inited = false;
// TODO: pre-allocate space to avoid malloc/free for small number of columns.
MY_BITMAP column_bitmap;
uint m_mrr_flags; /* Flags to be used with MRR interface */
Bounds_checked_array<QUICK_RANGE *> ranges; /* ordered array of range ptrs */
/* Members needed to use the MRR interface */
QUICK_RANGE_SEQ_CTX qr_traversal_ctx;
QUICK_RANGE *last_range; // The range we are currently scanning, or nullptr.
int current_range_idx;
/* Info about index we're scanning */
KEY_PART_INFO *key_part_info;
// Whether this reverse scan uses extended keyparts (in case of Innodb,
// secondary index is extended to include primary key).
bool m_using_extended_key_parts{false};
// To check if the index is a multi-valued index.
bool m_multi_valued_index;
bool range_reads_after_key(QUICK_RANGE *range);
int cmp_prev(QUICK_RANGE *range);
};
#endif // SQL_RANGE_OPTIMIZER_REVERSE_INDEX_RANGE_SCAN_H_
|