00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <drizzled/sql_base.h>
00023 #include <drizzled/sql_select.h>
00024 #include <drizzled/memory/sql_alloc.h>
00025 #include <drizzled/optimizer/range.h>
00026 #include <drizzled/optimizer/range_param.h>
00027 #include <drizzled/optimizer/sel_arg.h>
00028 #include <drizzled/optimizer/sel_tree.h>
00029 #include <drizzled/optimizer/sel_imerge.h>
00030
00031 using namespace std;
00032 using namespace drizzled;
00033
00034 static optimizer::SEL_ARG *key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2);
00035 static bool eq_tree(optimizer::SEL_ARG* a, optimizer::SEL_ARG *b);
00036
00037 bool optimizer::sel_trees_can_be_ored(const SEL_TREE& tree1, const SEL_TREE& tree2, const RangeParameter& param)
00038 {
00039 key_map common_keys= tree1.keys_map;
00040 common_keys&= tree2.keys_map;
00041
00042 if (common_keys.none())
00043 return false;
00044
00045
00046 for (uint32_t key_no= 0; key_no < param.keys; key_no++)
00047 {
00048 if (common_keys.test(key_no) && tree1.keys[key_no]->part == tree2.keys[key_no]->part)
00049 return true;
00050 }
00051 return false;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 static int imerge_list_or_list(optimizer::RangeParameter *param, List<optimizer::SEL_IMERGE> *im1, List<optimizer::SEL_IMERGE> *im2)
00079 {
00080 optimizer::SEL_IMERGE *imerge= &im1->front();
00081 im1->clear();
00082 im1->push_back(imerge);
00083
00084 return imerge->or_sel_imerge_with_checks(*param, im2->front());
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 static int imerge_list_or_tree(optimizer::RangeParameter& param, List<optimizer::SEL_IMERGE>& im1, optimizer::SEL_TREE& tree)
00097 {
00098 List_iterator<optimizer::SEL_IMERGE> it(im1.begin());
00099 while (optimizer::SEL_IMERGE* imerge= it++)
00100 {
00101 if (imerge->or_sel_tree_with_checks(param, tree))
00102 it.remove();
00103 }
00104 return im1.is_empty();
00105 }
00106
00107
00108 optimizer::SEL_TREE* optimizer::tree_or(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree1, optimizer::SEL_TREE *tree2)
00109 {
00110 if (! tree1 || ! tree2)
00111 return 0;
00112
00113 if (tree1->type == SEL_TREE::IMPOSSIBLE || tree2->type == SEL_TREE::ALWAYS)
00114 return tree2;
00115
00116 if (tree2->type == SEL_TREE::IMPOSSIBLE || tree1->type == SEL_TREE::ALWAYS)
00117 return tree1;
00118
00119 if (tree1->type == SEL_TREE::MAYBE)
00120 return tree1;
00121
00122 if (tree2->type == SEL_TREE::MAYBE)
00123 return tree2;
00124
00125 SEL_TREE *result= NULL;
00126 key_map result_keys;
00127 result_keys.reset();
00128 if (sel_trees_can_be_ored(*tree1, *tree2, *param))
00129 {
00130
00131 SEL_ARG** key1= tree1->keys;
00132 SEL_ARG** key2= tree2->keys;
00133 SEL_ARG** end= key1+param->keys;
00134 for (; key1 != end; key1++, key2++)
00135 {
00136 *key1= key_or(param, *key1, *key2);
00137 if (*key1)
00138 {
00139 result= tree1;
00140 result_keys.set(key1 - tree1->keys);
00141 }
00142 }
00143 if (result)
00144 result->keys_map= result_keys;
00145 }
00146 else
00147 {
00148
00149 if (tree1->merges.is_empty() && tree2->merges.is_empty())
00150 {
00151 if (param->remove_jump_scans && (remove_nonrange_trees(param, tree1) || remove_nonrange_trees(param, tree2)))
00152 return new SEL_TREE(SEL_TREE::ALWAYS);
00153
00154 result= new SEL_TREE();
00155 SEL_IMERGE* merge= new SEL_IMERGE();
00156 result->merges.push_back(merge);
00157 merge->or_sel_tree(param, tree1);
00158 merge->or_sel_tree(param, tree2);
00159 result->type= tree1->type;
00160 }
00161 else if (!tree1->merges.is_empty() && !tree2->merges.is_empty())
00162 {
00163 result= imerge_list_or_list(param, &tree1->merges, &tree2->merges)
00164 ? new SEL_TREE(SEL_TREE::ALWAYS)
00165 : tree1;
00166 }
00167 else
00168 {
00169
00170 if (tree1->merges.is_empty())
00171 std::swap(tree1, tree2);
00172
00173 if (param->remove_jump_scans && remove_nonrange_trees(param, tree2))
00174 return new SEL_TREE(SEL_TREE::ALWAYS);
00175
00176 result= imerge_list_or_tree(*param, tree1->merges, *tree2)
00177 ? new SEL_TREE(SEL_TREE::ALWAYS)
00178 : tree1;
00179 }
00180 }
00181 return result;
00182 }
00183
00184
00185 static optimizer::SEL_ARG *
00186 key_or(optimizer::RangeParameter *param, optimizer::SEL_ARG *key1, optimizer::SEL_ARG *key2)
00187 {
00188 if (! key1)
00189 {
00190 if (key2)
00191 {
00192 key2->use_count--;
00193 key2->free_tree();
00194 }
00195 return 0;
00196 }
00197 if (! key2)
00198 {
00199 key1->use_count--;
00200 key1->free_tree();
00201 return 0;
00202 }
00203 key1->use_count--;
00204 key2->use_count--;
00205
00206 if (key1->part != key2->part)
00207 {
00208 key1->free_tree();
00209 key2->free_tree();
00210 return 0;
00211 }
00212
00213
00214 if (key1->type == optimizer::SEL_ARG::MAYBE_KEY)
00215 {
00216 key2->free_tree();
00217 key1->use_count++;
00218 return key1;
00219 }
00220 if (key2->type == optimizer::SEL_ARG::MAYBE_KEY)
00221 {
00222 key1->free_tree();
00223 key2->use_count++;
00224 return key2;
00225 }
00226
00227 if (key1->use_count > 0)
00228 {
00229 if (key2->use_count == 0 || key1->elements > key2->elements)
00230 {
00231 std::swap(key1,key2);
00232 }
00233 if (key1->use_count > 0 || !(key1=key1->clone_tree(param)))
00234 return 0;
00235 }
00236
00237
00238 bool key2_shared= key2->use_count != 0;
00239 key1->maybe_flag|= key2->maybe_flag;
00240
00241 for (key2=key2->first(); key2; )
00242 {
00243 optimizer::SEL_ARG *tmp= key1->find_range(key2);
00244 int cmp;
00245
00246 if (! tmp)
00247 {
00248 tmp=key1->first();
00249 cmp= -1;
00250 }
00251 else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
00252 {
00253 optimizer::SEL_ARG *next= tmp->next;
00254 if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
00255 {
00256
00257 optimizer::SEL_ARG *key2_next=key2->next;
00258 if (key2_shared)
00259 {
00260 key2=new optimizer::SEL_ARG(*key2);
00261 key2->increment_use_count(key1->use_count+1);
00262 key2->next= key2_next;
00263 }
00264 key2->copy_min(tmp);
00265 if (! (key1=key1->tree_delete(tmp)))
00266 {
00267 key1= key2;
00268 key1->make_root();
00269 key2= key2_next;
00270 break;
00271 }
00272 }
00273 if (! (tmp= next))
00274 break;
00275 }
00276 if (cmp < 0)
00277 {
00278 int tmp_cmp;
00279 if ((tmp_cmp= tmp->cmp_min_to_max(key2)) > 0)
00280 {
00281 if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
00282 {
00283 tmp->copy_min_to_min(key2);
00284 key1->merge_flags(key2);
00285 if (tmp->min_flag & NO_MIN_RANGE &&
00286 tmp->max_flag & NO_MAX_RANGE)
00287 {
00288 if (key1->maybe_flag)
00289 return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
00290 return 0;
00291 }
00292 key2->increment_use_count(-1);
00293 key2= key2->next;
00294 continue;
00295 }
00296 else
00297 {
00298 optimizer::SEL_ARG *next= key2->next;
00299 if (key2_shared)
00300 {
00301 optimizer::SEL_ARG *cpy= new optimizer::SEL_ARG(*key2);
00302 if (! cpy)
00303 return 0;
00304 key1= key1->insert(cpy);
00305 key2->increment_use_count(key1->use_count+1);
00306 }
00307 else
00308 key1= key1->insert(key2);
00309 key2= next;
00310 continue;
00311 }
00312 }
00313 }
00314
00315
00316 if (eq_tree(tmp->next_key_part,key2->next_key_part))
00317 {
00318 if (tmp->is_same(key2))
00319 {
00320 tmp->merge_flags(key2);
00321 key2->increment_use_count(-1);
00322 }
00323 else
00324 {
00325 optimizer::SEL_ARG *last= tmp;
00326 while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
00327 eq_tree(last->next->next_key_part,key2->next_key_part))
00328 {
00329 optimizer::SEL_ARG *save= last;
00330 last= last->next;
00331 key1= key1->tree_delete(save);
00332 }
00333 last->copy_min(tmp);
00334 if (last->copy_min(key2) || last->copy_max(key2))
00335 {
00336 key1->free_tree();
00337 for (; key2; key2= key2->next)
00338 key2->increment_use_count(-1);
00339 if (key1->maybe_flag)
00340 return new optimizer::SEL_ARG(optimizer::SEL_ARG::MAYBE_KEY);
00341 return 0;
00342 }
00343 }
00344 key2= key2->next;
00345 continue;
00346 }
00347
00348 if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
00349 {
00350 optimizer::SEL_ARG *new_arg= tmp->clone_first(key2);
00351 if ((new_arg->next_key_part= key1->next_key_part))
00352 new_arg->increment_use_count(key1->use_count+1);
00353 tmp->copy_min_to_min(key2);
00354 key1= key1->insert(new_arg);
00355 }
00356
00357
00358 optimizer::SEL_ARG key(*key2);
00359 for (;;)
00360 {
00361 if (tmp->cmp_min_to_min(&key) > 0)
00362 {
00363 optimizer::SEL_ARG *new_arg= key.clone_first(tmp);
00364 if ((new_arg->next_key_part=key.next_key_part))
00365 new_arg->increment_use_count(key1->use_count+1);
00366 key1= key1->insert(new_arg);
00367 }
00368 if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
00369 {
00370 tmp->maybe_flag|= key.maybe_flag;
00371 key.increment_use_count(key1->use_count+1);
00372 tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
00373 if (! cmp)
00374 break;
00375 key.copy_max_to_min(tmp);
00376 if (! (tmp= tmp->next))
00377 {
00378 optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
00379 if (! tmp2)
00380 return 0;
00381 key1= key1->insert(tmp2);
00382 key2= key2->next;
00383 goto end;
00384 }
00385 if (tmp->cmp_min_to_max(&key) > 0)
00386 {
00387 optimizer::SEL_ARG *tmp2= new optimizer::SEL_ARG(key);
00388 if (! tmp2)
00389 return 0;
00390 key1= key1->insert(tmp2);
00391 break;
00392 }
00393 }
00394 else
00395 {
00396 optimizer::SEL_ARG *new_arg= tmp->clone_last(&key);
00397 tmp->copy_max_to_min(&key);
00398 tmp->increment_use_count(key1->use_count+1);
00399
00400 key.increment_use_count(1);
00401 new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
00402 key1= key1->insert(new_arg);
00403 break;
00404 }
00405 }
00406 key2= key2->next;
00407 }
00408
00409 end:
00410 while (key2)
00411 {
00412 optimizer::SEL_ARG *next= key2->next;
00413 if (key2_shared)
00414 {
00415 optimizer::SEL_ARG *tmp= new optimizer::SEL_ARG(*key2);
00416 if (! tmp)
00417 return 0;
00418 key2->increment_use_count(key1->use_count+1);
00419 key1= key1->insert(tmp);
00420 }
00421 else
00422 key1= key1->insert(key2);
00423 key2= next;
00424 }
00425 key1->use_count++;
00426 return key1;
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 bool optimizer::remove_nonrange_trees(optimizer::RangeParameter *param, optimizer::SEL_TREE *tree)
00485 {
00486 bool res= true;
00487 for (uint32_t i= 0; i < param->keys; i++)
00488 {
00489 if (tree->keys[i])
00490 {
00491 if (tree->keys[i]->part)
00492 {
00493 tree->keys[i]= NULL;
00494 tree->keys_map.reset(i);
00495 }
00496 else
00497 res= false;
00498 }
00499 }
00500 return res;
00501 }
00502
00503
00504
00505 static bool eq_tree(optimizer::SEL_ARG *a, optimizer::SEL_ARG *b)
00506 {
00507 if (a == b)
00508 return true;
00509
00510 if (! a || ! b || ! a->is_same(b))
00511 {
00512 return false;
00513 }
00514
00515 if (a->left != &optimizer::null_element && b->left != &optimizer::null_element)
00516 {
00517 if (! eq_tree(a->left,b->left))
00518 return false;
00519 }
00520 else if (a->left != &optimizer::null_element || b->left != &optimizer::null_element)
00521 {
00522 return false;
00523 }
00524
00525 if (a->right != &optimizer::null_element && b->right != &optimizer::null_element)
00526 {
00527 if (! eq_tree(a->right,b->right))
00528 return false;
00529 }
00530 else if (a->right != &optimizer::null_element || b->right != &optimizer::null_element)
00531 {
00532 return false;
00533 }
00534
00535 if (a->next_key_part != b->next_key_part)
00536 {
00537 if (! a->next_key_part != ! b->next_key_part ||
00538 ! eq_tree(a->next_key_part, b->next_key_part))
00539 return false;
00540 }
00541
00542 return true;
00543 }