34
34
static optimizer::SEL_ARG *key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
35
35
static bool eq_tree(optimizer::SEL_ARG* a, optimizer::SEL_ARG *b);
37
bool optimizer::sel_trees_can_be_ored(optimizer::SEL_TREE *tree1,
38
optimizer::SEL_TREE *tree2,
39
optimizer::RangeParameter* param)
37
bool optimizer::sel_trees_can_be_ored(const SEL_TREE& tree1, const SEL_TREE& tree2, const RangeParameter& param)
41
key_map common_keys= tree1->keys_map;
42
common_keys&= tree2->keys_map;
39
key_map common_keys= tree1.keys_map;
40
common_keys&= tree2.keys_map;
44
42
if (common_keys.none())
49
45
/* trees have a common key, check if they refer to same key part */
50
optimizer::SEL_ARG **key1,**key2;
51
for (uint32_t key_no=0; key_no < param->keys; key_no++)
46
for (uint32_t key_no= 0; key_no < param.keys; key_no++)
53
if (common_keys.test(key_no))
55
key1= tree1->keys + key_no;
56
key2= tree2->keys + key_no;
57
if ((*key1)->part == (*key2)->part)
48
if (common_keys.test(key_no) && tree1.keys[key_no]->part == tree2.keys[key_no]->part)
87
75
other Error, both passed lists are unusable
90
static int imerge_list_or_list(optimizer::RangeParameter *param,
91
List<optimizer::SEL_IMERGE> *im1,
92
List<optimizer::SEL_IMERGE> *im2)
78
static int imerge_list_or_list(optimizer::RangeParameter *param, List<optimizer::SEL_IMERGE> *im1, List<optimizer::SEL_IMERGE> *im2)
94
80
optimizer::SEL_IMERGE *imerge= &im1->front();
96
82
im1->push_back(imerge);
98
return imerge->or_sel_imerge_with_checks(param, &im2->front());
84
return imerge->or_sel_imerge_with_checks(*param, im2->front());
110
static int imerge_list_or_tree(optimizer::RangeParameter *param,
111
List<optimizer::SEL_IMERGE> *im1,
112
optimizer::SEL_TREE *tree)
96
static int imerge_list_or_tree(optimizer::RangeParameter& param, List<optimizer::SEL_IMERGE>& im1, optimizer::SEL_TREE& tree)
114
optimizer::SEL_IMERGE *imerge= NULL;
115
List_iterator<optimizer::SEL_IMERGE> it(im1->begin());
116
while ((imerge= it++))
98
List_iterator<optimizer::SEL_IMERGE> it(im1.begin());
99
while (optimizer::SEL_IMERGE* imerge= it++)
118
101
if (imerge->or_sel_tree_with_checks(param, tree))
121
return im1->is_empty();
104
return im1.is_empty();
125
optimizer::SEL_TREE *
126
optimizer::tree_or(optimizer::RangeParameter *param,
127
optimizer::SEL_TREE *tree1,
128
optimizer::SEL_TREE *tree2)
108
optimizer::SEL_TREE* optimizer::tree_or(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree1, optimizer::SEL_TREE *tree2)
130
110
if (! tree1 || ! tree2)
135
if (tree1->type == optimizer::SEL_TREE::IMPOSSIBLE || tree2->type == optimizer::SEL_TREE::ALWAYS)
113
if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
140
if (tree2->type == optimizer::SEL_TREE::IMPOSSIBLE || tree1->type == optimizer::SEL_TREE::ALWAYS)
116
if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
145
if (tree1->type == optimizer::SEL_TREE::MAYBE)
119
if (tree1->type == SEL_TREE::MAYBE)
147
120
return tree1; // Can't use this
150
if (tree2->type == optimizer::SEL_TREE::MAYBE)
122
if (tree2->type == SEL_TREE::MAYBE)
155
optimizer::SEL_TREE *result= NULL;
125
SEL_TREE *result= NULL;
156
126
key_map result_keys;
157
127
result_keys.reset();
158
if (sel_trees_can_be_ored(tree1, tree2, param))
128
if (sel_trees_can_be_ored(*tree1, *tree2, *param))
160
130
/* Join the trees key per key */
161
optimizer::SEL_ARG **key1= NULL;
162
optimizer::SEL_ARG **key2= NULL;
163
optimizer::SEL_ARG **end= NULL;
164
for (key1= tree1->keys,key2= tree2->keys,end= key1+param->keys;
131
SEL_ARG** key1= tree1->keys;
132
SEL_ARG** key2= tree2->keys;
133
SEL_ARG** end= key1+param->keys;
134
for (; key1 != end; key1++, key2++)
168
136
*key1= key_or(param, *key1, *key2);
180
148
/* ok, two trees have KEY type but cannot be used without index merge */
181
149
if (tree1->merges.is_empty() && tree2->merges.is_empty())
183
if (param->remove_jump_scans)
185
bool no_trees= optimizer::remove_nonrange_trees(param, tree1);
186
no_trees= no_trees || optimizer::remove_nonrange_trees(param, tree2);
189
return (new optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS));
192
optimizer::SEL_IMERGE *merge= NULL;
151
if (param->remove_jump_scans && (remove_nonrange_trees(param, tree1) || remove_nonrange_trees(param, tree2)))
152
return new SEL_TREE(SEL_TREE::ALWAYS);
193
153
/* both trees are "range" trees, produce new index merge structure */
194
result= new optimizer::SEL_TREE();
195
merge= new optimizer::SEL_IMERGE();
154
result= new SEL_TREE();
155
SEL_IMERGE* merge= new SEL_IMERGE();
196
156
result->merges.push_back(merge);
197
if (merge->or_sel_tree(param, tree1) || merge->or_sel_tree(param, tree2))
203
result->type= tree1->type;
157
merge->or_sel_tree(param, tree1);
158
merge->or_sel_tree(param, tree2);
159
result->type= tree1->type;
206
161
else if (!tree1->merges.is_empty() && !tree2->merges.is_empty())
208
if (imerge_list_or_list(param, &tree1->merges, &tree2->merges))
209
result= new optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS);
163
result= imerge_list_or_list(param, &tree1->merges, &tree2->merges)
164
? new SEL_TREE(SEL_TREE::ALWAYS)
216
170
if (tree1->merges.is_empty())
217
171
std::swap(tree1, tree2);
219
if (param->remove_jump_scans && optimizer::remove_nonrange_trees(param, tree2))
220
return(new optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS));
173
if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
174
return new SEL_TREE(SEL_TREE::ALWAYS);
221
175
/* add tree2 to tree1->merges, checking if it collapses to ALWAYS */
222
if (imerge_list_or_tree(param, &tree1->merges, tree2))
223
result= new optimizer::SEL_TREE(optimizer::SEL_TREE::ALWAYS);
176
result= imerge_list_or_tree(*param, tree1->merges, *tree2)
177
? new SEL_TREE(SEL_TREE::ALWAYS)