1 /* Copyright (c) 2014, 2021, Oracle and/or its affiliates. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ 22 23 #ifndef FAKE_RANGE_OPT_PARAM 24 #define FAKE_RANGE_OPT_PARAM 25 26 27 #include <gmock/gmock.h> 28 #include "fake_table.h" 29 30 #include "opt_range.cc" 31 32 using ::testing::Return; 33 using ::testing::_; 34 35 class Fake_RANGE_OPT_PARAM : public RANGE_OPT_PARAM 36 { 37 KEY_PART m_key_parts[64]; 38 Mem_root_array<KEY_PART_INFO, true> m_kpis; 39 Fake_TABLE fake_table; 40 41 public: 42 43 /** 44 Creates a Fake_RANGE_OPT_PARAM and optionally a Fake_TABLE. 45 46 @note The Fake_TABLE is always created, but with zero columns if 47 number_columns is zero. However, it won't be used since 48 Fake_RANGE_OPT_PARAM::table is NULL. 49 50 @param number_columns If non-zero, a Fake_TABLE is created with 51 this many columns. 52 53 @param columns_nullable Creates nullable columns, if applicable. 54 */ Fake_RANGE_OPT_PARAM(THD * thd_arg,MEM_ROOT * alloc_arg,int number_columns,bool columns_nullable)55 Fake_RANGE_OPT_PARAM(THD *thd_arg, MEM_ROOT *alloc_arg, int number_columns, 56 bool columns_nullable) 57 : m_kpis(alloc_arg), 58 fake_table(number_columns, columns_nullable) 59 { 60 m_kpis.reserve(64); 61 62 thd= thd_arg; 63 mem_root= alloc_arg; 64 65 if (number_columns != 0) 66 { 67 table= &fake_table; 68 current_table= table->pos_in_table_list->map(); 69 } 70 else 71 { 72 table= NULL; 73 current_table= 1; 74 } 75 76 using_real_indexes= true; 77 key_parts= m_key_parts; 78 key_parts_end= m_key_parts; 79 keys= 0; 80 /* 81 Controls whether or not ranges that do not have conditions on 82 the first keypart are removed before two trees are ORed in such 83 a way that index merge is required. The value of 'true' means 84 that such ranges are removed. 85 */ 86 remove_jump_scans= true; 87 88 const Mock_HANDLER *mock_handler= &fake_table.mock_handler; 89 90 ON_CALL(*mock_handler, index_flags(_, _, true)) 91 .WillByDefault(Return(HA_READ_RANGE)); 92 } 93 add_key(List<Field> fields_in_index)94 void add_key(List<Field> fields_in_index) 95 { 96 List_iterator<Field> it(fields_in_index); 97 int cur_kp= 0; 98 99 table->key_info[keys].actual_key_parts= 0; 100 for (Field *cur_field= it++; cur_field; cur_field= it++, cur_kp++) 101 { 102 KEY_PART_INFO *kpi= m_kpis.end(); // Points past the end. 103 m_kpis.push_back(KEY_PART_INFO()); // kpi now points to a new element 104 kpi->init_from_field(cur_field); 105 106 key_parts_end->key= keys; 107 key_parts_end->part= cur_kp; 108 key_parts_end->length= kpi->store_length; 109 key_parts_end->store_length= kpi->store_length; 110 key_parts_end->field= kpi->field; 111 key_parts_end->null_bit= kpi->null_bit; 112 key_parts_end->flag= static_cast<uint8>(kpi->key_part_flag); 113 key_parts_end->image_type = Field::itRAW; 114 115 key_parts_end++; 116 table->key_info[keys].key_part[cur_kp]= *kpi; 117 table->key_info[keys].actual_key_parts++; 118 } 119 table->key_info[keys].user_defined_key_parts= 120 table->key_info[keys].actual_key_parts; 121 real_keynr[keys]= keys; 122 keys++; 123 } 124 add_key(Field * field_to_index)125 void add_key(Field *field_to_index) 126 { 127 List<Field> index_list; 128 index_list.push_back(field_to_index); 129 add_key(index_list); 130 } 131 add_key(Field * field_to_index1,Field * field_to_index2)132 void add_key(Field *field_to_index1, Field *field_to_index2) 133 { 134 List<Field> index_list; 135 index_list.push_back(field_to_index1); 136 index_list.push_back(field_to_index2); 137 add_key(index_list); 138 } 139 140 /// Creates an index over all columns in the RANGE_OPT_PARAM's table. add_key()141 void add_key() 142 { 143 List<Field> index_list; 144 for (uint i= 0; i < table->s->fields; ++i) 145 index_list.push_back(table->field[i]); 146 add_key(index_list); 147 } 148 ~Fake_RANGE_OPT_PARAM()149 ~Fake_RANGE_OPT_PARAM() 150 { 151 for (uint i= 0; i < keys; i++) 152 { 153 table->key_info[i].actual_key_parts= 0; 154 table->key_info[i].user_defined_key_parts= 0; 155 } 156 } 157 158 }; 159 160 #endif // FAKE_RANGE_OPT_PARAM 161