00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021 #include <drizzled/optimizer/range.h>
00022 #include <drizzled/optimizer/range_param.h>
00023 #include <drizzled/optimizer/sel_arg.h>
00024 #include <drizzled/util/test.h>
00025
00026 namespace drizzled {
00027
00028
00029 static void left_rotate(optimizer::SEL_ARG **root, optimizer::SEL_ARG *leaf)
00030 {
00031 optimizer::SEL_ARG *y= leaf->right;
00032 leaf->right= y->left;
00033 if (y->left != &optimizer::null_element)
00034 y->left->parent= leaf;
00035 if (! (y->parent=leaf->parent))
00036 *root= y;
00037 else
00038 *leaf->parent_ptr()= y;
00039 y->left= leaf;
00040 leaf->parent= y;
00041 }
00042
00043
00044 static void right_rotate(optimizer::SEL_ARG **root, optimizer::SEL_ARG *leaf)
00045 {
00046 optimizer::SEL_ARG *y= leaf->left;
00047 leaf->left= y->right;
00048 if (y->right != &optimizer::null_element)
00049 y->right->parent= leaf;
00050 if (! (y->parent=leaf->parent))
00051 *root= y;
00052 else
00053 *leaf->parent_ptr()= y;
00054 y->right= leaf;
00055 leaf->parent= y;
00056 }
00057
00058
00059
00060 optimizer::SEL_ARG *optimizer::SEL_ARG::clone_and(optimizer::SEL_ARG *arg)
00061 {
00062 unsigned char *new_min= NULL;
00063 unsigned char *new_max= NULL;
00064 uint8_t flag_min= 0;
00065 uint8_t flag_max= 0;
00066
00067 if (cmp_min_to_min(arg) >= 0)
00068 {
00069 new_min= min_value;
00070 flag_min= min_flag;
00071 }
00072 else
00073 {
00074 new_min=arg->min_value;
00075 flag_min=arg->min_flag;
00076 }
00077 if (cmp_max_to_max(arg) <= 0)
00078 {
00079 new_max= max_value;
00080 flag_max= max_flag;
00081 }
00082 else
00083 {
00084 new_max= arg->max_value;
00085 flag_max= arg->max_flag;
00086 }
00087 return new SEL_ARG(field, part, new_min, new_max, flag_min, flag_max, test(maybe_flag && arg->maybe_flag));
00088 }
00089
00090
00091
00092 optimizer::SEL_ARG *optimizer::SEL_ARG::clone_first(optimizer::SEL_ARG *arg)
00093 {
00094 return new SEL_ARG(field,part, min_value, arg->min_value, min_flag, arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX, maybe_flag | arg->maybe_flag);
00095 }
00096
00097
00098
00099 optimizer::SEL_ARG *optimizer::SEL_ARG::clone_last(optimizer::SEL_ARG *arg)
00100 {
00101 return new SEL_ARG(field, part, min_value, arg->max_value, min_flag, arg->max_flag, maybe_flag | arg->maybe_flag);
00102 }
00103
00104
00105
00106 bool optimizer::SEL_ARG::copy_min(optimizer::SEL_ARG *arg)
00107 {
00108 if (cmp_min_to_min(arg) > 0)
00109 {
00110 min_value= arg->min_value;
00111 min_flag=arg->min_flag;
00112 if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
00113 (NO_MAX_RANGE | NO_MIN_RANGE))
00114 {
00115 return 1;
00116 }
00117 }
00118 maybe_flag|= arg->maybe_flag;
00119 return 0;
00120 }
00121
00122
00123 bool optimizer::SEL_ARG::copy_max(optimizer::SEL_ARG *arg)
00124 {
00125 if (cmp_max_to_max(arg) <= 0)
00126 {
00127 max_value= arg->max_value;
00128 max_flag= arg->max_flag;
00129 if ((max_flag & (NO_MAX_RANGE | NO_MIN_RANGE)) ==
00130 (NO_MAX_RANGE | NO_MIN_RANGE))
00131 {
00132 return 1;
00133 }
00134 }
00135 maybe_flag|= arg->maybe_flag;
00136 return 0;
00137 }
00138
00139 void optimizer::SEL_ARG::copy_min_to_min(optimizer::SEL_ARG *arg)
00140 {
00141 min_value= arg->min_value;
00142 min_flag= arg->min_flag;
00143 }
00144
00145
00146 void optimizer::SEL_ARG::copy_min_to_max(optimizer::SEL_ARG *arg)
00147 {
00148 max_value= arg->min_value;
00149 max_flag= arg->min_flag & NEAR_MIN ? 0 : NEAR_MAX;
00150 }
00151
00152 void optimizer::SEL_ARG::copy_max_to_min(optimizer::SEL_ARG *arg)
00153 {
00154 min_value= arg->max_value;
00155 min_flag= arg->max_flag & NEAR_MAX ? 0 : NEAR_MIN;
00156 }
00157
00158
00159 int optimizer::SEL_ARG::store_min(uint32_t length, unsigned char **min_key, uint32_t min_key_flag)
00160 {
00161
00162 if ((! (min_flag & NO_MIN_RANGE) &&
00163 ! (min_key_flag & (NO_MIN_RANGE | NEAR_MIN))))
00164 {
00165 if (maybe_null && *min_value)
00166 {
00167 **min_key= 1;
00168 memset(*min_key+1, 0, length-1);
00169 }
00170 else
00171 {
00172 memcpy(*min_key,min_value,length);
00173 }
00174 (*min_key)+= length;
00175 return 1;
00176 }
00177 return 0;
00178 }
00179
00180
00181 int optimizer::SEL_ARG::store_max(uint32_t length, unsigned char **max_key, uint32_t max_key_flag)
00182 {
00183 if (! (max_flag & NO_MAX_RANGE) &&
00184 ! (max_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
00185 {
00186 if (maybe_null && *max_value)
00187 {
00188 **max_key= 1;
00189 memset(*max_key + 1, 0, length-1);
00190 }
00191 else
00192 {
00193 memcpy(*max_key,max_value,length);
00194 }
00195 (*max_key)+= length;
00196 return 1;
00197 }
00198 return 0;
00199 }
00200
00201
00202 int optimizer::SEL_ARG::store_min_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
00203 {
00204 optimizer::SEL_ARG *key_tree= first();
00205 uint32_t res= key_tree->store_min(key[key_tree->part].store_length,
00206 range_key,
00207 *range_key_flag);
00208 *range_key_flag|= key_tree->min_flag;
00209
00210 if (key_tree->next_key_part &&
00211 key_tree->next_key_part->part == key_tree->part+1 &&
00212 ! (*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
00213 key_tree->next_key_part->type == optimizer::SEL_ARG::KEY_RANGE)
00214 {
00215 res+= key_tree->next_key_part->store_min_key(key,
00216 range_key,
00217 range_key_flag);
00218 }
00219 return res;
00220 }
00221
00222 int optimizer::SEL_ARG::store_max_key(KEY_PART *key, unsigned char **range_key, uint32_t *range_key_flag)
00223 {
00224 SEL_ARG *key_tree= last();
00225 uint32_t res= key_tree->store_max(key[key_tree->part].store_length,
00226 range_key,
00227 *range_key_flag);
00228 (*range_key_flag)|= key_tree->max_flag;
00229 if (key_tree->next_key_part &&
00230 key_tree->next_key_part->part == key_tree->part+1 &&
00231 ! (*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
00232 key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
00233 res+= key_tree->next_key_part->store_max_key(key,
00234 range_key,
00235 range_key_flag);
00236 return res;
00237 }
00238
00239 optimizer::SEL_ARG::SEL_ARG(optimizer::SEL_ARG &arg)
00240 :
00241 memory::SqlAlloc()
00242 {
00243 type= arg.type;
00244 min_flag= arg.min_flag;
00245 max_flag= arg.max_flag;
00246 maybe_flag= arg.maybe_flag;
00247 maybe_null= arg.maybe_null;
00248 part= arg.part;
00249 field= arg.field;
00250 min_value= arg.min_value;
00251 max_value= arg.max_value;
00252 next_key_part= arg.next_key_part;
00253 use_count=1;
00254 elements=1;
00255 }
00256
00257
00258 void optimizer::SEL_ARG::make_root()
00259 {
00260 left= right= &optimizer::null_element;
00261 color= BLACK;
00262 next= prev =0;
00263 use_count= 0;
00264 elements= 1;
00265 }
00266
00267 optimizer::SEL_ARG::SEL_ARG(Field *f,
00268 const unsigned char *min_value_arg,
00269 const unsigned char *max_value_arg)
00270 :
00271 min_flag(0),
00272 max_flag(0),
00273 maybe_flag(0),
00274 maybe_null(f->real_maybe_null()),
00275 elements(1),
00276 use_count(1),
00277 field(f),
00278 min_value((unsigned char*) min_value_arg),
00279 max_value((unsigned char*) max_value_arg),
00280 next(0),
00281 prev(0),
00282 next_key_part(0),
00283 color(BLACK),
00284 type(KEY_RANGE)
00285 {
00286 left= right= &optimizer::null_element;
00287 }
00288
00289 optimizer::SEL_ARG::SEL_ARG(Field *field_,
00290 uint8_t part_,
00291 unsigned char *min_value_,
00292 unsigned char *max_value_,
00293 uint8_t min_flag_,
00294 uint8_t max_flag_,
00295 uint8_t maybe_flag_)
00296 :
00297 min_flag(min_flag_),
00298 max_flag(max_flag_),
00299 maybe_flag(maybe_flag_),
00300 part(part_),
00301 maybe_null(field_->real_maybe_null()),
00302 elements(1),
00303 use_count(1),
00304 field(field_),
00305 min_value(min_value_),
00306 max_value(max_value_),
00307 next(0),
00308 prev(0),
00309 next_key_part(0),
00310 color(BLACK),
00311 type(KEY_RANGE)
00312 {
00313 left= right= &optimizer::null_element;
00314 }
00315
00316 optimizer::SEL_ARG *optimizer::SEL_ARG::clone(RangeParameter *param, optimizer::SEL_ARG *new_parent, optimizer::SEL_ARG **next_arg)
00317 {
00318 optimizer::SEL_ARG *tmp= NULL;
00319
00320
00321 if (++param->alloced_sel_args > MAX_SEL_ARGS)
00322 return 0;
00323
00324 if (type != KEY_RANGE)
00325 {
00326 tmp= new (*param->mem_root) optimizer::SEL_ARG(type);
00327 tmp->prev= *next_arg;
00328 (*next_arg)->next= tmp;
00329 (*next_arg)= tmp;
00330 }
00331 else
00332 {
00333 tmp= new (*param->mem_root) optimizer::SEL_ARG(field, part, min_value, max_value, min_flag, max_flag, maybe_flag);
00334 tmp->parent= new_parent;
00335 tmp->next_key_part= next_key_part;
00336 if (left != &optimizer::null_element)
00337 if (! (tmp->left= left->clone(param, tmp, next_arg)))
00338 return 0;
00339
00340 tmp->prev= *next_arg;
00341 (*next_arg)->next= tmp;
00342 (*next_arg)= tmp;
00343
00344 if (right != &optimizer::null_element)
00345 if (! (tmp->right= right->clone(param, tmp, next_arg)))
00346 return 0;
00347 }
00348 increment_use_count(1);
00349 tmp->color= color;
00350 tmp->elements= this->elements;
00351 return tmp;
00352 }
00353
00354 optimizer::SEL_ARG *optimizer::SEL_ARG::first()
00355 {
00356 optimizer::SEL_ARG *next_arg= this;
00357 if (! next_arg->left)
00358 return 0;
00359 while (next_arg->left != &optimizer::null_element)
00360 next_arg= next_arg->left;
00361 return next_arg;
00362 }
00363
00364 optimizer::SEL_ARG *optimizer::SEL_ARG::last()
00365 {
00366 SEL_ARG *next_arg= this;
00367 if (! next_arg->right)
00368 return 0;
00369 while (next_arg->right != &optimizer::null_element)
00370 next_arg=next_arg->right;
00371 return next_arg;
00372 }
00373
00374
00375 optimizer::SEL_ARG *optimizer::SEL_ARG::clone_tree(RangeParameter *param)
00376 {
00377 optimizer::SEL_ARG tmp_link;
00378 optimizer::SEL_ARG* next_arg= NULL;
00379 next_arg= &tmp_link;
00380 optimizer::SEL_ARG* root= clone(param, (SEL_ARG *) 0, &next_arg);
00381 if (not root)
00382 return 0;
00383 next_arg->next= 0;
00384 tmp_link.next->prev= 0;
00385 if (root)
00386 root->use_count= 0;
00387 return root;
00388 }
00389
00390
00391 optimizer::SEL_ARG *
00392 optimizer::SEL_ARG::insert(optimizer::SEL_ARG *key)
00393 {
00394 optimizer::SEL_ARG *element= NULL;
00395 optimizer::SEL_ARG **par= NULL;
00396 optimizer::SEL_ARG *last_element= NULL;
00397
00398 for (element= this; element != &optimizer::null_element; )
00399 {
00400 last_element= element;
00401 if (key->cmp_min_to_min(element) > 0)
00402 {
00403 par= &element->right; element= element->right;
00404 }
00405 else
00406 {
00407 par= &element->left; element= element->left;
00408 }
00409 }
00410 *par= key;
00411 key->parent= last_element;
00412
00413 if (par == &last_element->left)
00414 {
00415 key->next= last_element;
00416 if ((key->prev=last_element->prev))
00417 key->prev->next= key;
00418 last_element->prev= key;
00419 }
00420 else
00421 {
00422 if ((key->next= last_element->next))
00423 key->next->prev= key;
00424 key->prev= last_element;
00425 last_element->next= key;
00426 }
00427 key->left= key->right= &optimizer::null_element;
00428 optimizer::SEL_ARG *root= rb_insert(key);
00429 root->use_count= this->use_count;
00430 root->elements= this->elements+1;
00431 root->maybe_flag= this->maybe_flag;
00432 return root;
00433 }
00434
00435
00436
00437
00438
00439
00440 optimizer::SEL_ARG *
00441 optimizer::SEL_ARG::find_range(optimizer::SEL_ARG *key)
00442 {
00443 optimizer::SEL_ARG *element= this;
00444 optimizer::SEL_ARG *found= NULL;
00445
00446 for (;;)
00447 {
00448 if (element == &optimizer::null_element)
00449 return found;
00450 int cmp= element->cmp_min_to_min(key);
00451 if (cmp == 0)
00452 return element;
00453 if (cmp < 0)
00454 {
00455 found= element;
00456 element= element->right;
00457 }
00458 else
00459 element= element->left;
00460 }
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 optimizer::SEL_ARG *
00478 optimizer::SEL_ARG::tree_delete(optimizer::SEL_ARG *key)
00479 {
00480 enum leaf_color remove_color;
00481 optimizer::SEL_ARG *root= NULL;
00482 optimizer::SEL_ARG *nod= NULL;
00483 optimizer::SEL_ARG **par= NULL;
00484 optimizer::SEL_ARG *fix_par= NULL;
00485
00486 root= this;
00487 this->parent= 0;
00488
00489
00490 if (key->prev)
00491 key->prev->next= key->next;
00492 if (key->next)
00493 key->next->prev= key->prev;
00494 key->increment_use_count(-1);
00495 if (! key->parent)
00496 par= &root;
00497 else
00498 par= key->parent_ptr();
00499
00500 if (key->left == &optimizer::null_element)
00501 {
00502 *par= nod= key->right;
00503 fix_par= key->parent;
00504 if (nod != &optimizer::null_element)
00505 nod->parent= fix_par;
00506 remove_color= key->color;
00507 }
00508 else if (key->right == &optimizer::null_element)
00509 {
00510 *par= nod= key->left;
00511 nod->parent= fix_par= key->parent;
00512 remove_color= key->color;
00513 }
00514 else
00515 {
00516 optimizer::SEL_ARG *tmp= key->next;
00517 nod= *tmp->parent_ptr()= tmp->right;
00518 fix_par= tmp->parent;
00519 if (nod != &optimizer::null_element)
00520 nod->parent= fix_par;
00521 remove_color= tmp->color;
00522
00523 tmp->parent= key->parent;
00524 (tmp->left= key->left)->parent= tmp;
00525 if ((tmp->right=key->right) != &optimizer::null_element)
00526 tmp->right->parent= tmp;
00527 tmp->color= key->color;
00528 *par= tmp;
00529 if (fix_par == key)
00530 fix_par= tmp;
00531 }
00532
00533 if (root == &optimizer::null_element)
00534 return 0;
00535 if (remove_color == BLACK)
00536 root= rb_delete_fixup(root, nod, fix_par);
00537
00538 root->use_count= this->use_count;
00539 root->elements= this->elements-1;
00540 root->maybe_flag= this->maybe_flag;
00541 return root;
00542 }
00543
00544
00545 optimizer::SEL_ARG *
00546 optimizer::SEL_ARG::rb_insert(optimizer::SEL_ARG *leaf)
00547 {
00548 optimizer::SEL_ARG *y= NULL;
00549 optimizer::SEL_ARG *par= NULL;
00550 optimizer::SEL_ARG *par2= NULL;
00551 optimizer::SEL_ARG *root= NULL;
00552
00553 root= this;
00554 root->parent= 0;
00555
00556 leaf->color= RED;
00557 while (leaf != root && (par= leaf->parent)->color == RED)
00558 {
00559 if (par == (par2= leaf->parent->parent)->left)
00560 {
00561 y= par2->right;
00562 if (y->color == RED)
00563 {
00564 par->color= BLACK;
00565 y->color= BLACK;
00566 leaf= par2;
00567 leaf->color= RED;
00568 }
00569 else
00570 {
00571 if (leaf == par->right)
00572 {
00573 left_rotate(&root,leaf->parent);
00574 par= leaf;
00575 }
00576 par->color= BLACK;
00577 par2->color= RED;
00578 right_rotate(&root, par2);
00579 break;
00580 }
00581 }
00582 else
00583 {
00584 y= par2->left;
00585 if (y->color == RED)
00586 {
00587 par->color= BLACK;
00588 y->color= BLACK;
00589 leaf= par2;
00590 leaf->color= RED;
00591 }
00592 else
00593 {
00594 if (leaf == par->left)
00595 {
00596 right_rotate(&root,par);
00597 par= leaf;
00598 }
00599 par->color= BLACK;
00600 par2->color= RED;
00601 left_rotate(&root, par2);
00602 break;
00603 }
00604 }
00605 }
00606 root->color= BLACK;
00607
00608 return root;
00609 }
00610
00611
00612 optimizer::SEL_ARG *optimizer::rb_delete_fixup(optimizer::SEL_ARG *root,
00613 optimizer::SEL_ARG *key,
00614 optimizer::SEL_ARG *par)
00615 {
00616 optimizer::SEL_ARG *x= NULL;
00617 optimizer::SEL_ARG *w= NULL;
00618 root->parent= 0;
00619
00620 x= key;
00621 while (x != root && x->color == optimizer::SEL_ARG::BLACK)
00622 {
00623 if (x == par->left)
00624 {
00625 w= par->right;
00626 if (w->color == optimizer::SEL_ARG::RED)
00627 {
00628 w->color= optimizer::SEL_ARG::BLACK;
00629 par->color= optimizer::SEL_ARG::RED;
00630 left_rotate(&root, par);
00631 w= par->right;
00632 }
00633 if (w->left->color == optimizer::SEL_ARG::BLACK &&
00634 w->right->color == optimizer::SEL_ARG::BLACK)
00635 {
00636 w->color= optimizer::SEL_ARG::RED;
00637 x= par;
00638 }
00639 else
00640 {
00641 if (w->right->color == optimizer::SEL_ARG::BLACK)
00642 {
00643 w->left->color= optimizer::SEL_ARG::BLACK;
00644 w->color= optimizer::SEL_ARG::RED;
00645 right_rotate(&root, w);
00646 w= par->right;
00647 }
00648 w->color= par->color;
00649 par->color= optimizer::SEL_ARG::BLACK;
00650 w->right->color= optimizer::SEL_ARG::BLACK;
00651 left_rotate(&root, par);
00652 x= root;
00653 break;
00654 }
00655 }
00656 else
00657 {
00658 w= par->left;
00659 if (w->color == optimizer::SEL_ARG::RED)
00660 {
00661 w->color= optimizer::SEL_ARG::BLACK;
00662 par->color= optimizer::SEL_ARG::RED;
00663 right_rotate(&root, par);
00664 w= par->left;
00665 }
00666 if (w->right->color == optimizer::SEL_ARG::BLACK &&
00667 w->left->color == optimizer::SEL_ARG::BLACK)
00668 {
00669 w->color= optimizer::SEL_ARG::RED;
00670 x= par;
00671 }
00672 else
00673 {
00674 if (w->left->color == SEL_ARG::BLACK)
00675 {
00676 w->right->color= optimizer::SEL_ARG::BLACK;
00677 w->color= optimizer::SEL_ARG::RED;
00678 left_rotate(&root, w);
00679 w= par->left;
00680 }
00681 w->color= par->color;
00682 par->color= optimizer::SEL_ARG::BLACK;
00683 w->left->color= optimizer::SEL_ARG::BLACK;
00684 right_rotate(&root, par);
00685 x= root;
00686 break;
00687 }
00688 }
00689 par= x->parent;
00690 }
00691 x->color= optimizer::SEL_ARG::BLACK;
00692 return root;
00693 }
00694
00695
00696 }