00001 /* Copyright (C) 2000-2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 /* compare and test functions */ 00019 00020 #ifdef USE_PRAGMA_INTERFACE 00021 #pragma interface /* gcc class implementation */ 00022 #endif 00023 00024 extern Item_result item_cmp_type(Item_result a,Item_result b); 00025 class Item_bool_func2; 00026 class Arg_comparator; 00027 00028 typedef int (Arg_comparator::*arg_cmp_func)(); 00029 00030 typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg); 00031 00032 class Arg_comparator: public Sql_alloc 00033 { 00034 Item **a, **b; 00035 arg_cmp_func func; 00036 Item_bool_func2 *owner; 00037 Arg_comparator *comparators; // used only for compare_row() 00038 00039 public: 00040 DTCollation cmp_collation; 00041 00042 Arg_comparator() {}; 00043 Arg_comparator(Item **a1, Item **a2): a(a1), b(a2) {}; 00044 00045 int set_compare_func(Item_bool_func2 *owner, Item_result type); 00046 inline int set_compare_func(Item_bool_func2 *owner_arg) 00047 { 00048 return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(), 00049 (*b)->result_type())); 00050 } 00051 inline int set_cmp_func(Item_bool_func2 *owner_arg, 00052 Item **a1, Item **a2, 00053 Item_result type) 00054 { 00055 a= a1; 00056 b= a2; 00057 return set_compare_func(owner_arg, type); 00058 } 00059 inline int set_cmp_func(Item_bool_func2 *owner_arg, 00060 Item **a1, Item **a2) 00061 { 00062 return set_cmp_func(owner_arg, a1, a2, 00063 item_cmp_type((*a1)->result_type(), 00064 (*a2)->result_type())); 00065 } 00066 inline int compare() { return (this->*func)(); } 00067 00068 int compare_string(); // compare args[0] & args[1] 00069 int compare_binary_string(); // compare args[0] & args[1] 00070 int compare_real(); // compare args[0] & args[1] 00071 int compare_decimal(); // compare args[0] & args[1] 00072 int compare_int_signed(); // compare args[0] & args[1] 00073 int compare_int_signed_unsigned(); 00074 int compare_int_unsigned_signed(); 00075 int compare_int_unsigned(); 00076 int compare_row(); // compare args[0] & args[1] 00077 int compare_e_string(); // compare args[0] & args[1] 00078 int compare_e_binary_string(); // compare args[0] & args[1] 00079 int compare_e_real(); // compare args[0] & args[1] 00080 int compare_e_decimal(); // compare args[0] & args[1] 00081 int compare_e_int(); // compare args[0] & args[1] 00082 int compare_e_int_diff_signedness(); 00083 int compare_e_row(); // compare args[0] & args[1] 00084 00085 static arg_cmp_func comparator_matrix [5][2]; 00086 00087 friend class Item_func; 00088 }; 00089 00090 class Item_bool_func :public Item_int_func 00091 { 00092 public: 00093 Item_bool_func() :Item_int_func() {} 00094 Item_bool_func(Item *a) :Item_int_func(a) {} 00095 Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {} 00096 Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {} 00097 bool is_bool_func() { return 1; } 00098 void fix_length_and_dec() { decimals=0; max_length=1; } 00099 uint decimal_precision() const { return 1; } 00100 }; 00101 00102 class Item_cache; 00103 class Item_in_optimizer: public Item_bool_func 00104 { 00105 protected: 00106 Item_cache *cache; 00107 bool save_cache; 00108 public: 00109 Item_in_optimizer(Item *a, Item_in_subselect *b): 00110 Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), save_cache(0) 00111 {} 00112 bool fix_fields(THD *, Item **); 00113 bool fix_left(THD *thd, Item **ref); 00114 bool is_null(); 00115 /* 00116 Item_in_optimizer item is special boolean function. On value request 00117 (one of val, val_int or val_str methods) it evaluate left expression 00118 of IN by storing it value in cache item (one of Item_cache* items), 00119 then it test cache is it NULL. If left expression (cache) is NULL then 00120 Item_in_optimizer return NULL, else it evaluate Item_in_subselect. 00121 */ 00122 longlong val_int(); 00123 void cleanup(); 00124 const char *func_name() const { return "<in_optimizer>"; } 00125 Item_cache **get_cache() { return &cache; } 00126 void keep_top_level_cache(); 00127 }; 00128 00129 class Comp_creator 00130 { 00131 public: 00132 Comp_creator() {} /* Remove gcc warning */ 00133 virtual ~Comp_creator() {} /* Remove gcc warning */ 00134 virtual Item_bool_func2* create(Item *a, Item *b) const = 0; 00135 virtual const char* symbol(bool invert) const = 0; 00136 virtual bool eqne_op() const = 0; 00137 virtual bool l_op() const = 0; 00138 }; 00139 00140 class Eq_creator :public Comp_creator 00141 { 00142 public: 00143 Eq_creator() {} /* Remove gcc warning */ 00144 virtual ~Eq_creator() {} /* Remove gcc warning */ 00145 virtual Item_bool_func2* create(Item *a, Item *b) const; 00146 virtual const char* symbol(bool invert) const { return invert? "<>" : "="; } 00147 virtual bool eqne_op() const { return 1; } 00148 virtual bool l_op() const { return 0; } 00149 }; 00150 00151 class Ne_creator :public Comp_creator 00152 { 00153 public: 00154 Ne_creator() {} /* Remove gcc warning */ 00155 virtual ~Ne_creator() {} /* Remove gcc warning */ 00156 virtual Item_bool_func2* create(Item *a, Item *b) const; 00157 virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; } 00158 virtual bool eqne_op() const { return 1; } 00159 virtual bool l_op() const { return 0; } 00160 }; 00161 00162 class Gt_creator :public Comp_creator 00163 { 00164 public: 00165 Gt_creator() {} /* Remove gcc warning */ 00166 virtual ~Gt_creator() {} /* Remove gcc warning */ 00167 virtual Item_bool_func2* create(Item *a, Item *b) const; 00168 virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; } 00169 virtual bool eqne_op() const { return 0; } 00170 virtual bool l_op() const { return 0; } 00171 }; 00172 00173 class Lt_creator :public Comp_creator 00174 { 00175 public: 00176 Lt_creator() {} /* Remove gcc warning */ 00177 virtual ~Lt_creator() {} /* Remove gcc warning */ 00178 virtual Item_bool_func2* create(Item *a, Item *b) const; 00179 virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; } 00180 virtual bool eqne_op() const { return 0; } 00181 virtual bool l_op() const { return 1; } 00182 }; 00183 00184 class Ge_creator :public Comp_creator 00185 { 00186 public: 00187 Ge_creator() {} /* Remove gcc warning */ 00188 virtual ~Ge_creator() {} /* Remove gcc warning */ 00189 virtual Item_bool_func2* create(Item *a, Item *b) const; 00190 virtual const char* symbol(bool invert) const { return invert? "<" : ">="; } 00191 virtual bool eqne_op() const { return 0; } 00192 virtual bool l_op() const { return 0; } 00193 }; 00194 00195 class Le_creator :public Comp_creator 00196 { 00197 public: 00198 Le_creator() {} /* Remove gcc warning */ 00199 virtual ~Le_creator() {} /* Remove gcc warning */ 00200 virtual Item_bool_func2* create(Item *a, Item *b) const; 00201 virtual const char* symbol(bool invert) const { return invert? ">" : "<="; } 00202 virtual bool eqne_op() const { return 0; } 00203 virtual bool l_op() const { return 1; } 00204 }; 00205 00206 class Item_bool_func2 :public Item_int_func 00207 { /* Bool with 2 string args */ 00208 protected: 00209 Arg_comparator cmp; 00210 String tmp_value1,tmp_value2; 00211 bool abort_on_null; 00212 00213 public: 00214 Item_bool_func2(Item *a,Item *b) 00215 :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {} 00216 void fix_length_and_dec(); 00217 void set_cmp_func() 00218 { 00219 cmp.set_cmp_func(this, tmp_arg, tmp_arg+1); 00220 } 00221 optimize_type select_optimize() const { return OPTIMIZE_OP; } 00222 virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; } 00223 bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } 00224 void print(String *str) { Item_func::print_op(str); } 00225 bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); } 00226 bool is_bool_func() { return 1; } 00227 CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; } 00228 uint decimal_precision() const { return 1; } 00229 void top_level_item() { abort_on_null=1; } 00230 00231 friend class Arg_comparator; 00232 }; 00233 00234 class Item_bool_rowready_func2 :public Item_bool_func2 00235 { 00236 public: 00237 Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b) 00238 { 00239 allowed_arg_cols= 0; // Fetch this value from first argument 00240 } 00241 Item *neg_transformer(THD *thd); 00242 virtual Item *negated_item(); 00243 bool check_partition_func_processor(byte *bool_arg) { return 0;} 00244 }; 00245 00246 class Item_func_not :public Item_bool_func 00247 { 00248 public: 00249 Item_func_not(Item *a) :Item_bool_func(a) {} 00250 longlong val_int(); 00251 enum Functype functype() const { return NOT_FUNC; } 00252 const char *func_name() const { return "not"; } 00253 Item *neg_transformer(THD *thd); 00254 bool check_partition_func_processor(byte *bool_arg) { return 0;} 00255 }; 00256 00257 class Item_maxmin_subselect; 00258 00259 /* 00260 The class Item_func_trig_cond is used for guarded predicates 00261 which are employed only for internal purposes. 00262 A guarded predicates is an object consisting of an a regular or 00263 a guarded predicate P and a pointer to a boolean guard variable g. 00264 A guarded predicate P/g is evaluated to true if the value of the 00265 guard g is false, otherwise it is evaluated to the same value that 00266 the predicate P: val(P/g)= g ? val(P):true. 00267 Guarded predicates allow us to include predicates into a conjunction 00268 conditionally. Currently they are utilized for pushed down predicates 00269 in queries with outer join operations. 00270 00271 In the future, probably, it makes sense to extend this class to 00272 the objects consisting of three elements: a predicate P, a pointer 00273 to a variable g and a firing value s with following evaluation 00274 rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only 00275 one item for the objects of the form P/g1/g2... 00276 00277 Objects of this class are built only for query execution after 00278 the execution plan has been already selected. That's why this 00279 class needs only val_int out of generic methods. 00280 */ 00281 00282 class Item_func_trig_cond: public Item_bool_func 00283 { 00284 bool *trig_var; 00285 public: 00286 Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; } 00287 longlong val_int() { return *trig_var ? args[0]->val_int() : 1; } 00288 enum Functype functype() const { return TRIG_COND_FUNC; }; 00289 const char *func_name() const { return "trigcond"; }; 00290 bool const_item() const { return FALSE; } 00291 }; 00292 00293 class Item_func_not_all :public Item_func_not 00294 { 00295 /* allow to check presence of values in max/min optimization */ 00296 Item_sum_hybrid *test_sum_item; 00297 Item_maxmin_subselect *test_sub_item; 00298 00299 bool abort_on_null; 00300 public: 00301 bool show; 00302 00303 Item_func_not_all(Item *a) 00304 :Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0), 00305 show(0) 00306 {} 00307 virtual void top_level_item() { abort_on_null= 1; } 00308 bool top_level() { return abort_on_null; } 00309 longlong val_int(); 00310 enum Functype functype() const { return NOT_ALL_FUNC; } 00311 const char *func_name() const { return "<not>"; } 00312 void print(String *str); 00313 void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; }; 00314 void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; }; 00315 bool empty_underlying_subquery(); 00316 Item *neg_transformer(THD *thd); 00317 }; 00318 00319 00320 class Item_func_nop_all :public Item_func_not_all 00321 { 00322 public: 00323 00324 Item_func_nop_all(Item *a) :Item_func_not_all(a) {} 00325 longlong val_int(); 00326 const char *func_name() const { return "<nop>"; } 00327 Item *neg_transformer(THD *thd); 00328 }; 00329 00330 00331 class Item_func_eq :public Item_bool_rowready_func2 00332 { 00333 public: 00334 Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {} 00335 longlong val_int(); 00336 enum Functype functype() const { return EQ_FUNC; } 00337 enum Functype rev_functype() const { return EQ_FUNC; } 00338 cond_result eq_cmp_result() const { return COND_TRUE; } 00339 const char *func_name() const { return "="; } 00340 Item *negated_item(); 00341 }; 00342 00343 class Item_func_equal :public Item_bool_rowready_func2 00344 { 00345 public: 00346 Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}; 00347 longlong val_int(); 00348 void fix_length_and_dec(); 00349 table_map not_null_tables() const { return 0; } 00350 enum Functype functype() const { return EQUAL_FUNC; } 00351 enum Functype rev_functype() const { return EQUAL_FUNC; } 00352 cond_result eq_cmp_result() const { return COND_TRUE; } 00353 const char *func_name() const { return "<=>"; } 00354 Item *neg_transformer(THD *thd) { return 0; } 00355 }; 00356 00357 00358 class Item_func_ge :public Item_bool_rowready_func2 00359 { 00360 public: 00361 Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}; 00362 longlong val_int(); 00363 enum Functype functype() const { return GE_FUNC; } 00364 enum Functype rev_functype() const { return LE_FUNC; } 00365 cond_result eq_cmp_result() const { return COND_TRUE; } 00366 const char *func_name() const { return ">="; } 00367 Item *negated_item(); 00368 }; 00369 00370 00371 class Item_func_gt :public Item_bool_rowready_func2 00372 { 00373 public: 00374 Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}; 00375 longlong val_int(); 00376 enum Functype functype() const { return GT_FUNC; } 00377 enum Functype rev_functype() const { return LT_FUNC; } 00378 cond_result eq_cmp_result() const { return COND_FALSE; } 00379 const char *func_name() const { return ">"; } 00380 Item *negated_item(); 00381 }; 00382 00383 00384 class Item_func_le :public Item_bool_rowready_func2 00385 { 00386 public: 00387 Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}; 00388 longlong val_int(); 00389 enum Functype functype() const { return LE_FUNC; } 00390 enum Functype rev_functype() const { return GE_FUNC; } 00391 cond_result eq_cmp_result() const { return COND_TRUE; } 00392 const char *func_name() const { return "<="; } 00393 Item *negated_item(); 00394 }; 00395 00396 00397 class Item_func_lt :public Item_bool_rowready_func2 00398 { 00399 public: 00400 Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {} 00401 longlong val_int(); 00402 enum Functype functype() const { return LT_FUNC; } 00403 enum Functype rev_functype() const { return GT_FUNC; } 00404 cond_result eq_cmp_result() const { return COND_FALSE; } 00405 const char *func_name() const { return "<"; } 00406 Item *negated_item(); 00407 }; 00408 00409 00410 class Item_func_ne :public Item_bool_rowready_func2 00411 { 00412 public: 00413 Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {} 00414 longlong val_int(); 00415 enum Functype functype() const { return NE_FUNC; } 00416 cond_result eq_cmp_result() const { return COND_FALSE; } 00417 optimize_type select_optimize() const { return OPTIMIZE_KEY; } 00418 const char *func_name() const { return "<>"; } 00419 Item *negated_item(); 00420 }; 00421 00422 00423 /* 00424 The class Item_func_opt_neg is defined to factor out the functionality 00425 common for the classes Item_func_between and Item_func_in. The objects 00426 of these classes can express predicates or there negations. 00427 The alternative approach would be to create pairs Item_func_between, 00428 Item_func_notbetween and Item_func_in, Item_func_notin. 00429 00430 */ 00431 00432 class Item_func_opt_neg :public Item_int_func 00433 { 00434 public: 00435 bool negated; /* <=> the item represents NOT <func> */ 00436 bool pred_level; /* <=> [NOT] <func> is used on a predicate level */ 00437 public: 00438 Item_func_opt_neg(Item *a, Item *b, Item *c) 00439 :Item_int_func(a, b, c), negated(0), pred_level(0) {} 00440 Item_func_opt_neg(List<Item> &list) 00441 :Item_int_func(list), negated(0), pred_level(0) {} 00442 public: 00443 inline void negate() { negated= !negated; } 00444 inline void top_level_item() { pred_level= 1; } 00445 Item *neg_transformer(THD *thd) 00446 { 00447 negated= !negated; 00448 return this; 00449 } 00450 }; 00451 00452 00453 class Item_func_between :public Item_func_opt_neg 00454 { 00455 DTCollation cmp_collation; 00456 public: 00457 Item_result cmp_type; 00458 String value0,value1,value2; 00459 Item_func_between(Item *a, Item *b, Item *c) 00460 :Item_func_opt_neg(a, b, c) {} 00461 longlong val_int(); 00462 optimize_type select_optimize() const { return OPTIMIZE_KEY; } 00463 enum Functype functype() const { return BETWEEN; } 00464 const char *func_name() const { return "between"; } 00465 bool fix_fields(THD *, Item **); 00466 void fix_length_and_dec(); 00467 void print(String *str); 00468 bool is_bool_func() { return 1; } 00469 CHARSET_INFO *compare_collation() { return cmp_collation.collation; } 00470 uint decimal_precision() const { return 1; } 00471 bool check_partition_func_processor(byte *bool_arg) { return 0;} 00472 }; 00473 00474 00475 class Item_func_strcmp :public Item_bool_func2 00476 { 00477 public: 00478 Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {} 00479 longlong val_int(); 00480 optimize_type select_optimize() const { return OPTIMIZE_NONE; } 00481 const char *func_name() const { return "strcmp"; } 00482 void print(String *str) { Item_func::print(str); } 00483 bool check_partition_func_processor(byte *bool_arg) { return 0;} 00484 }; 00485 00486 00487 struct interval_range 00488 { 00489 Item_result type; 00490 double dbl; 00491 my_decimal dec; 00492 }; 00493 00494 class Item_func_interval :public Item_int_func 00495 { 00496 Item_row *row; 00497 my_bool use_decimal_comparison; 00498 interval_range *intervals; 00499 public: 00500 Item_func_interval(Item_row *a) 00501 :Item_int_func(a),row(a),intervals(0) 00502 { 00503 allowed_arg_cols= 0; // Fetch this value from first argument 00504 } 00505 longlong val_int(); 00506 void fix_length_and_dec(); 00507 const char *func_name() const { return "interval"; } 00508 uint decimal_precision() const { return 2; } 00509 }; 00510 00511 00512 class Item_func_coalesce :public Item_func_numhybrid 00513 { 00514 protected: 00515 Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {} 00516 public: 00517 Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {} 00518 double real_op(); 00519 longlong int_op(); 00520 String *str_op(String *); 00521 my_decimal *decimal_op(my_decimal *); 00522 void fix_length_and_dec(); 00523 void find_num_type() {} 00524 enum Item_result result_type () const { return hybrid_type; } 00525 const char *func_name() const { return "coalesce"; } 00526 table_map not_null_tables() const { return 0; } 00527 }; 00528 00529 00530 class Item_func_ifnull :public Item_func_coalesce 00531 { 00532 protected: 00533 enum_field_types cached_field_type; 00534 bool field_type_defined; 00535 public: 00536 Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {} 00537 double real_op(); 00538 longlong int_op(); 00539 String *str_op(String *str); 00540 my_decimal *decimal_op(my_decimal *); 00541 enum_field_types field_type() const; 00542 void fix_length_and_dec(); 00543 const char *func_name() const { return "ifnull"; } 00544 Field *tmp_table_field(TABLE *table); 00545 uint decimal_precision() const; 00546 bool check_partition_func_processor(byte *bool_arg) { return 0;} 00547 }; 00548 00549 00550 class Item_func_if :public Item_func 00551 { 00552 enum Item_result cached_result_type; 00553 public: 00554 Item_func_if(Item *a,Item *b,Item *c) 00555 :Item_func(a,b,c), cached_result_type(INT_RESULT) 00556 {} 00557 double val_real(); 00558 longlong val_int(); 00559 String *val_str(String *str); 00560 my_decimal *val_decimal(my_decimal *); 00561 enum Item_result result_type () const { return cached_result_type; } 00562 bool fix_fields(THD *, Item **); 00563 void fix_length_and_dec(); 00564 uint decimal_precision() const; 00565 const char *func_name() const { return "if"; } 00566 }; 00567 00568 00569 class Item_func_nullif :public Item_bool_func2 00570 { 00571 enum Item_result cached_result_type; 00572 public: 00573 Item_func_nullif(Item *a,Item *b) 00574 :Item_bool_func2(a,b), cached_result_type(INT_RESULT) 00575 {} 00576 double val_real(); 00577 longlong val_int(); 00578 String *val_str(String *str); 00579 my_decimal *val_decimal(my_decimal *); 00580 enum Item_result result_type () const { return cached_result_type; } 00581 void fix_length_and_dec(); 00582 uint decimal_precision() const { return args[0]->decimal_precision(); } 00583 const char *func_name() const { return "nullif"; } 00584 void print(String *str) { Item_func::print(str); } 00585 table_map not_null_tables() const { return 0; } 00586 bool is_null(); 00587 bool check_partition_func_processor(byte *bool_arg) { return 0;} 00588 }; 00589 00590 00591 class Item_func_case :public Item_func 00592 { 00593 int first_expr_num, else_expr_num; 00594 enum Item_result cached_result_type; 00595 String tmp_value; 00596 uint ncases; 00597 Item_result cmp_type; 00598 DTCollation cmp_collation; 00599 public: 00600 Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg) 00601 :Item_func(), first_expr_num(-1), else_expr_num(-1), 00602 cached_result_type(INT_RESULT) 00603 { 00604 ncases= list.elements; 00605 if (first_expr_arg) 00606 { 00607 first_expr_num= list.elements; 00608 list.push_back(first_expr_arg); 00609 } 00610 if (else_expr_arg) 00611 { 00612 else_expr_num= list.elements; 00613 list.push_back(else_expr_arg); 00614 } 00615 set_arguments(list); 00616 } 00617 double val_real(); 00618 longlong val_int(); 00619 String *val_str(String *); 00620 my_decimal *val_decimal(my_decimal *); 00621 bool fix_fields(THD *thd, Item **ref); 00622 void fix_length_and_dec(); 00623 uint decimal_precision() const; 00624 table_map not_null_tables() const { return 0; } 00625 enum Item_result result_type () const { return cached_result_type; } 00626 const char *func_name() const { return "case"; } 00627 void print(String *str); 00628 Item *find_item(String *str); 00629 CHARSET_INFO *compare_collation() { return cmp_collation.collation; } 00630 bool check_partition_func_processor(byte *bool_arg) { return 0;} 00631 }; 00632 00633 00634 /* Functions to handle the optimized IN */ 00635 00636 00637 /* A vector of values of some type */ 00638 00639 class in_vector :public Sql_alloc 00640 { 00641 public: 00642 char *base; 00643 uint size; 00644 qsort2_cmp compare; 00645 CHARSET_INFO *collation; 00646 uint count; 00647 uint used_count; 00648 in_vector() {} 00649 in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, 00650 CHARSET_INFO *cmp_coll) 00651 :base((char*) sql_calloc(elements*element_length)), 00652 size(element_length), compare(cmp_func), collation(cmp_coll), 00653 count(elements), used_count(elements) {} 00654 virtual ~in_vector() {} 00655 virtual void set(uint pos,Item *item)=0; 00656 virtual byte *get_value(Item *item)=0; 00657 void sort() 00658 { 00659 qsort2(base,used_count,size,compare,collation); 00660 } 00661 int find(Item *item); 00662 00663 /* 00664 Create an instance of Item_{type} (e.g. Item_decimal) constant object 00665 which type allows it to hold an element of this vector without any 00666 conversions. 00667 The purpose of this function is to be able to get elements of this 00668 vector in form of Item_xxx constants without creating Item_xxx object 00669 for every array element you get (i.e. this implements "FlyWeight" pattern) 00670 */ 00671 virtual Item* create_item() { return NULL; } 00672 00673 /* 00674 Store the value at position #pos into provided item object 00675 SYNOPSIS 00676 value_to_item() 00677 pos Index of value to store 00678 item Constant item to store value into. The item must be of the same 00679 type that create_item() returns. 00680 */ 00681 virtual void value_to_item(uint pos, Item *item) { } 00682 00683 /* Compare values number pos1 and pos2 for equality */ 00684 bool compare_elems(uint pos1, uint pos2) 00685 { 00686 return test(compare(collation, base + pos1*size, base + pos2*size)); 00687 } 00688 }; 00689 00690 class in_string :public in_vector 00691 { 00692 char buff[STRING_BUFFER_USUAL_SIZE]; 00693 String tmp; 00694 public: 00695 in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs); 00696 ~in_string(); 00697 void set(uint pos,Item *item); 00698 byte *get_value(Item *item); 00699 Item* create_item() 00700 { 00701 return new Item_string(collation); 00702 } 00703 void value_to_item(uint pos, Item *item) 00704 { 00705 String *str=((String*) base)+pos; 00706 Item_string *to= (Item_string*)item; 00707 to->str_value= *str; 00708 } 00709 }; 00710 00711 class in_longlong :public in_vector 00712 { 00713 longlong tmp; 00714 public: 00715 in_longlong(uint elements); 00716 void set(uint pos,Item *item); 00717 byte *get_value(Item *item); 00718 00719 Item* create_item() 00720 { 00721 /* 00722 We're created a signed INT, this may not be correct in 00723 general case (see BUG#19342). 00724 */ 00725 return new Item_int((longlong)0); 00726 } 00727 void value_to_item(uint pos, Item *item) 00728 { 00729 ((Item_int*)item)->value= ((longlong*)base)[pos]; 00730 } 00731 }; 00732 00733 class in_double :public in_vector 00734 { 00735 double tmp; 00736 public: 00737 in_double(uint elements); 00738 void set(uint pos,Item *item); 00739 byte *get_value(Item *item); 00740 Item *create_item() 00741 { 00742 return new Item_float(0.0); 00743 } 00744 void value_to_item(uint pos, Item *item) 00745 { 00746 ((Item_float*)item)->value= ((double*) base)[pos]; 00747 } 00748 00749 }; 00750 00751 class in_decimal :public in_vector 00752 { 00753 my_decimal val; 00754 public: 00755 in_decimal(uint elements); 00756 void set(uint pos, Item *item); 00757 byte *get_value(Item *item); 00758 Item *create_item() 00759 { 00760 return new Item_decimal(0, FALSE); 00761 } 00762 void value_to_item(uint pos, Item *item) 00763 { 00764 my_decimal *dec= ((my_decimal *)base) + pos; 00765 Item_decimal *item_dec= (Item_decimal*)item; 00766 item_dec->set_decimal_value(dec); 00767 } 00768 }; 00769 00770 00771 /* 00772 ** Classes for easy comparing of non const items 00773 */ 00774 00775 class cmp_item :public Sql_alloc 00776 { 00777 public: 00778 CHARSET_INFO *cmp_charset; 00779 cmp_item() { cmp_charset= &my_charset_bin; } 00780 virtual ~cmp_item() {} 00781 virtual void store_value(Item *item)= 0; 00782 virtual int cmp(Item *item)= 0; 00783 // for optimized IN with row 00784 virtual int compare(cmp_item *item)= 0; 00785 static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs); 00786 virtual cmp_item *make_same()= 0; 00787 virtual void store_value_by_template(cmp_item *tmpl, Item *item) 00788 { 00789 store_value(item); 00790 } 00791 }; 00792 00793 class cmp_item_string :public cmp_item 00794 { 00795 protected: 00796 String *value_res; 00797 public: 00798 cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; } 00799 friend class cmp_item_sort_string; 00800 friend class cmp_item_sort_string_in_static; 00801 }; 00802 00803 class cmp_item_sort_string :public cmp_item_string 00804 { 00805 protected: 00806 char value_buff[STRING_BUFFER_USUAL_SIZE]; 00807 String value; 00808 public: 00809 cmp_item_sort_string(CHARSET_INFO *cs): 00810 cmp_item_string(cs), 00811 value(value_buff, sizeof(value_buff), cs) {} 00812 void store_value(Item *item) 00813 { 00814 value_res= item->val_str(&value); 00815 } 00816 int cmp(Item *arg) 00817 { 00818 char buff[STRING_BUFFER_USUAL_SIZE]; 00819 String tmp(buff, sizeof(buff), cmp_charset), *res; 00820 res= arg->val_str(&tmp); 00821 return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) : 00822 (res ? -1 : 0)); 00823 } 00824 int compare(cmp_item *c) 00825 { 00826 cmp_item_string *cmp= (cmp_item_string *)c; 00827 return sortcmp(value_res, cmp->value_res, cmp_charset); 00828 } 00829 cmp_item *make_same(); 00830 }; 00831 00832 class cmp_item_int :public cmp_item 00833 { 00834 longlong value; 00835 public: 00836 cmp_item_int() {} /* Remove gcc warning */ 00837 void store_value(Item *item) 00838 { 00839 value= item->val_int(); 00840 } 00841 int cmp(Item *arg) 00842 { 00843 return value != arg->val_int(); 00844 } 00845 int compare(cmp_item *c) 00846 { 00847 cmp_item_int *cmp= (cmp_item_int *)c; 00848 return (value < cmp->value) ? -1 : ((value == cmp->value) ? 0 : 1); 00849 } 00850 cmp_item *make_same(); 00851 }; 00852 00853 class cmp_item_real :public cmp_item 00854 { 00855 double value; 00856 public: 00857 cmp_item_real() {} /* Remove gcc warning */ 00858 void store_value(Item *item) 00859 { 00860 value= item->val_real(); 00861 } 00862 int cmp(Item *arg) 00863 { 00864 return value != arg->val_real(); 00865 } 00866 int compare(cmp_item *c) 00867 { 00868 cmp_item_real *cmp= (cmp_item_real *)c; 00869 return (value < cmp->value)? -1 : ((value == cmp->value) ? 0 : 1); 00870 } 00871 cmp_item *make_same(); 00872 }; 00873 00874 00875 class cmp_item_decimal :public cmp_item 00876 { 00877 my_decimal value; 00878 public: 00879 cmp_item_decimal() {} /* Remove gcc warning */ 00880 void store_value(Item *item); 00881 int cmp(Item *arg); 00882 int compare(cmp_item *c); 00883 cmp_item *make_same(); 00884 }; 00885 00886 00887 class cmp_item_row :public cmp_item 00888 { 00889 cmp_item **comparators; 00890 uint n; 00891 public: 00892 cmp_item_row(): comparators(0), n(0) {} 00893 ~cmp_item_row(); 00894 void store_value(Item *item); 00895 int cmp(Item *arg); 00896 int compare(cmp_item *arg); 00897 cmp_item *make_same(); 00898 void store_value_by_template(cmp_item *tmpl, Item *); 00899 }; 00900 00901 00902 class in_row :public in_vector 00903 { 00904 cmp_item_row tmp; 00905 public: 00906 in_row(uint elements, Item *); 00907 ~in_row(); 00908 void set(uint pos,Item *item); 00909 byte *get_value(Item *item); 00910 }; 00911 00912 /* 00913 cmp_item for optimized IN with row (right part string, which never 00914 be changed) 00915 */ 00916 00917 class cmp_item_sort_string_in_static :public cmp_item_string 00918 { 00919 protected: 00920 String value; 00921 public: 00922 cmp_item_sort_string_in_static(CHARSET_INFO *cs): 00923 cmp_item_string(cs) {} 00924 void store_value(Item *item) 00925 { 00926 value_res= item->val_str(&value); 00927 } 00928 int cmp(Item *item) 00929 { 00930 // Should never be called 00931 DBUG_ASSERT(0); 00932 return 1; 00933 } 00934 int compare(cmp_item *c) 00935 { 00936 cmp_item_string *cmp= (cmp_item_string *)c; 00937 return sortcmp(value_res, cmp->value_res, cmp_charset); 00938 } 00939 cmp_item *make_same() 00940 { 00941 return new cmp_item_sort_string_in_static(cmp_charset); 00942 } 00943 }; 00944 00945 class Item_func_in :public Item_func_opt_neg 00946 { 00947 public: 00948 Item_result cmp_type; 00949 in_vector *array; 00950 cmp_item *in_item; 00951 bool have_null; 00952 DTCollation cmp_collation; 00953 00954 Item_func_in(List<Item> &list) 00955 :Item_func_opt_neg(list), array(0), in_item(0), have_null(0) 00956 { 00957 allowed_arg_cols= 0; // Fetch this value from first argument 00958 } 00959 longlong val_int(); 00960 bool fix_fields(THD *, Item **); 00961 void fix_length_and_dec(); 00962 uint decimal_precision() const { return 1; } 00963 void cleanup() 00964 { 00965 DBUG_ENTER("Item_func_in::cleanup"); 00966 Item_int_func::cleanup(); 00967 delete array; 00968 delete in_item; 00969 array= 0; 00970 in_item= 0; 00971 DBUG_VOID_RETURN; 00972 } 00973 optimize_type select_optimize() const 00974 { return array ? OPTIMIZE_KEY : OPTIMIZE_NONE; } 00975 void print(String *str); 00976 enum Functype functype() const { return IN_FUNC; } 00977 const char *func_name() const { return " IN "; } 00978 bool nulls_in_row(); 00979 bool is_bool_func() { return 1; } 00980 CHARSET_INFO *compare_collation() { return cmp_collation.collation; } 00981 bool check_partition_func_processor(byte *bool_arg) { return 0;} 00982 }; 00983 00984 /* Functions used by where clause */ 00985 00986 class Item_func_isnull :public Item_bool_func 00987 { 00988 protected: 00989 longlong cached_value; 00990 public: 00991 Item_func_isnull(Item *a) :Item_bool_func(a) {} 00992 longlong val_int(); 00993 enum Functype functype() const { return ISNULL_FUNC; } 00994 void fix_length_and_dec() 00995 { 00996 decimals=0; max_length=1; maybe_null=0; 00997 update_used_tables(); 00998 } 00999 const char *func_name() const { return "isnull"; } 01000 /* Optimize case of not_null_column IS NULL */ 01001 virtual void update_used_tables() 01002 { 01003 if (!args[0]->maybe_null) 01004 { 01005 used_tables_cache= 0; /* is always false */ 01006 const_item_cache= 1; 01007 cached_value= (longlong) 0; 01008 } 01009 else 01010 { 01011 args[0]->update_used_tables(); 01012 if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()))) 01013 { 01014 /* Remember if the value is always NULL or never NULL */ 01015 cached_value= (longlong) args[0]->is_null(); 01016 } 01017 } 01018 } 01019 table_map not_null_tables() const { return 0; } 01020 optimize_type select_optimize() const { return OPTIMIZE_NULL; } 01021 Item *neg_transformer(THD *thd); 01022 CHARSET_INFO *compare_collation() { return args[0]->collation.collation; } 01023 bool check_partition_func_processor(byte *bool_arg) { return 0;} 01024 }; 01025 01026 /* Functions used by HAVING for rewriting IN subquery */ 01027 01028 class Item_in_subselect; 01029 class Item_is_not_null_test :public Item_func_isnull 01030 { 01031 Item_in_subselect* owner; 01032 public: 01033 Item_is_not_null_test(Item_in_subselect* ow, Item *a) 01034 :Item_func_isnull(a), owner(ow) 01035 {} 01036 enum Functype functype() const { return ISNOTNULLTEST_FUNC; } 01037 longlong val_int(); 01038 const char *func_name() const { return "<is_not_null_test>"; } 01039 void update_used_tables(); 01040 /* 01041 we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE 01042 */ 01043 table_map used_tables() const 01044 { return used_tables_cache | RAND_TABLE_BIT; } 01045 bool check_partition_func_processor(byte *bool_arg) 01046 { *(bool *)bool_arg= FALSE; return 0; } 01047 }; 01048 01049 01050 class Item_func_isnotnull :public Item_bool_func 01051 { 01052 bool abort_on_null; 01053 public: 01054 Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {} 01055 longlong val_int(); 01056 enum Functype functype() const { return ISNOTNULL_FUNC; } 01057 void fix_length_and_dec() 01058 { 01059 decimals=0; max_length=1; maybe_null=0; 01060 } 01061 const char *func_name() const { return "isnotnull"; } 01062 optimize_type select_optimize() const { return OPTIMIZE_NULL; } 01063 table_map not_null_tables() const 01064 { return abort_on_null ? not_null_tables_cache : 0; } 01065 Item *neg_transformer(THD *thd); 01066 void print(String *str); 01067 CHARSET_INFO *compare_collation() { return args[0]->collation.collation; } 01068 void top_level_item() { abort_on_null=1; } 01069 bool check_partition_func_processor(byte *bool_arg) { return 0;} 01070 }; 01071 01072 01073 class Item_func_like :public Item_bool_func2 01074 { 01075 // Turbo Boyer-Moore data 01076 bool canDoTurboBM; // pattern is '%abcd%' case 01077 const char* pattern; 01078 int pattern_len; 01079 01080 // TurboBM buffers, *this is owner 01081 int* bmGs; // good suffix shift table, size is pattern_len + 1 01082 int* bmBc; // bad character shift table, size is alphabet_size 01083 01084 void turboBM_compute_suffixes(int* suff); 01085 void turboBM_compute_good_suffix_shifts(int* suff); 01086 void turboBM_compute_bad_character_shifts(); 01087 bool turboBM_matches(const char* text, int text_len) const; 01088 enum { alphabet_size = 256 }; 01089 01090 Item *escape_item; 01091 01092 bool escape_used_in_parsing; 01093 01094 public: 01095 int escape; 01096 01097 Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used) 01098 :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0), 01099 bmGs(0), bmBc(0), escape_item(escape_arg), 01100 escape_used_in_parsing(escape_used) {} 01101 longlong val_int(); 01102 enum Functype functype() const { return LIKE_FUNC; } 01103 optimize_type select_optimize() const; 01104 cond_result eq_cmp_result() const { return COND_TRUE; } 01105 const char *func_name() const { return "like"; } 01106 bool fix_fields(THD *thd, Item **ref); 01107 void cleanup(); 01108 bool check_partition_func_processor(byte *bool_arg) { return 0;} 01109 }; 01110 01111 #ifdef USE_REGEX 01112 01113 #include "my_regex.h" 01114 01115 class Item_func_regex :public Item_bool_func 01116 { 01117 my_regex_t preg; 01118 bool regex_compiled; 01119 bool regex_is_const; 01120 String prev_regexp; 01121 DTCollation cmp_collation; 01122 public: 01123 Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b), 01124 regex_compiled(0),regex_is_const(0) {} 01125 void cleanup(); 01126 longlong val_int(); 01127 bool fix_fields(THD *thd, Item **ref); 01128 const char *func_name() const { return "regexp"; } 01129 void print(String *str) { print_op(str); } 01130 CHARSET_INFO *compare_collation() { return cmp_collation.collation; } 01131 bool check_partition_func_processor(byte *bool_arg) { return 0;} 01132 }; 01133 01134 #else 01135 01136 class Item_func_regex :public Item_bool_func 01137 { 01138 public: 01139 Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b) {} 01140 longlong val_int() { return 0;} 01141 const char *func_name() const { return "regex"; } 01142 void print(String *str) { print_op(str); } 01143 }; 01144 01145 #endif /* USE_REGEX */ 01146 01147 01148 typedef class Item COND; 01149 01150 class Item_cond :public Item_bool_func 01151 { 01152 protected: 01153 List<Item> list; 01154 bool abort_on_null; 01155 table_map and_tables_cache; 01156 01157 public: 01158 /* Item_cond() is only used to create top level items */ 01159 Item_cond(): Item_bool_func(), abort_on_null(1) 01160 { const_item_cache=0; } 01161 Item_cond(Item *i1,Item *i2) 01162 :Item_bool_func(), abort_on_null(0) 01163 { 01164 list.push_back(i1); 01165 list.push_back(i2); 01166 } 01167 Item_cond(THD *thd, Item_cond *item); 01168 Item_cond(List<Item> &nlist) 01169 :Item_bool_func(), list(nlist), abort_on_null(0) {} 01170 bool add(Item *item) { return list.push_back(item); } 01171 void add_at_head(List<Item> *nlist) { list.prepand(nlist); } 01172 bool fix_fields(THD *, Item **ref); 01173 01174 enum Type type() const { return COND_ITEM; } 01175 List<Item>* argument_list() { return &list; } 01176 table_map used_tables() const; 01177 void update_used_tables(); 01178 void print(String *str); 01179 void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields); 01180 friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, 01181 COND **conds); 01182 void top_level_item() { abort_on_null=1; } 01183 void copy_andor_arguments(THD *thd, Item_cond *item); 01184 bool walk(Item_processor processor, bool walk_subquery, byte *arg); 01185 Item *transform(Item_transformer transformer, byte *arg); 01186 void traverse_cond(Cond_traverser, void *arg, traverse_order order); 01187 void neg_arguments(THD *thd); 01188 bool check_partition_func_processor(byte *bool_arg) { return 0;} 01189 }; 01190 01191 01192 /* 01193 The class Item_equal is used to represent conjunctions of equality 01194 predicates of the form field1 = field2, and field=const in where 01195 conditions and on expressions. 01196 01197 All equality predicates of the form field1=field2 contained in a 01198 conjunction are substituted for a sequence of items of this class. 01199 An item of this class Item_equal(f1,f2,...fk) represents a 01200 multiple equality f1=f2=...=fk. 01201 01202 If a conjunction contains predicates f1=f2 and f2=f3, a new item of 01203 this class is created Item_equal(f1,f2,f3) representing the multiple 01204 equality f1=f2=f3 that substitutes the above equality predicates in 01205 the conjunction. 01206 A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be 01207 substituted for the item representing the same multiple equality 01208 f1=f2=f3. 01209 An item Item_equal(f1,f2) can appear instead of a conjunction of 01210 f2=f1 and f1=f2, or instead of just the predicate f1=f2. 01211 01212 An item of the class Item_equal inherits equalities from outer 01213 conjunctive levels. 01214 01215 Suppose we have a where condition of the following form: 01216 WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)). 01217 In this case: 01218 f1=f2 will be substituted for Item_equal(f1,f2); 01219 f3=f4 and f3=f5 will be substituted for Item_equal(f3,f4,f5); 01220 f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5); 01221 01222 An object of the class Item_equal can contain an optional constant 01223 item c. Then it represents a multiple equality of the form 01224 c=f1=...=fk. 01225 01226 Objects of the class Item_equal are used for the following: 01227 01228 1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any 01229 pair of tables ti and tj as joined by an equi-condition. 01230 Thus it provide us with additional access paths from table to table. 01231 01232 2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new 01233 SARGable predicates: 01234 f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj). 01235 It also can give us additional index scans and can allow us to 01236 improve selectivity estimates. 01237 01238 3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 01239 selected execution plan for the query: if table ti is accessed 01240 before the table tj then in any predicate P in the where condition 01241 the occurrence of tj.fj is substituted for ti.fi. This can allow 01242 an evaluation of the predicate at an earlier step. 01243 01244 When feature 1 is supported they say that join transitive closure 01245 is employed. 01246 When feature 2 is supported they say that search argument transitive 01247 closure is employed. 01248 Both features are usually supported by preprocessing original query and 01249 adding additional predicates. 01250 We do not just add predicates, we rather dynamically replace some 01251 predicates that can not be used to access tables in the investigated 01252 plan for those, obtained by substitution of some fields for equal fields, 01253 that can be used. 01254 01255 Prepared Statements/Stored Procedures note: instances of class 01256 Item_equal are created only at the time a PS/SP is executed and 01257 are deleted in the end of execution. All changes made to these 01258 objects need not be registered in the list of changes of the parse 01259 tree and do not harm PS/SP re-execution. 01260 01261 Item equal objects are employed only at the optimize phase. Usually they are 01262 not supposed to be evaluated. Yet in some cases we call the method val_int() 01263 for them. We have to take care of restricting the predicate such an 01264 object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik. 01265 */ 01266 01267 class Item_equal: public Item_bool_func 01268 { 01269 List<Item_field> fields; /* list of equal field items */ 01270 Item *const_item; /* optional constant item equal to fields items */ 01271 cmp_item *eval_item; 01272 bool cond_false; 01273 DTCollation cmp_collation; 01274 public: 01275 inline Item_equal() 01276 : Item_bool_func(), const_item(0), eval_item(0), cond_false(0) 01277 { const_item_cache=0 ;} 01278 Item_equal(Item_field *f1, Item_field *f2); 01279 Item_equal(Item *c, Item_field *f); 01280 Item_equal(Item_equal *item_equal); 01281 inline Item* get_const() { return const_item; } 01282 void add(Item *c); 01283 void add(Item_field *f); 01284 uint members(); 01285 bool contains(Field *field); 01286 Item_field* get_first() { return fields.head(); } 01287 void merge(Item_equal *item); 01288 void update_const(); 01289 enum Functype functype() const { return MULT_EQUAL_FUNC; } 01290 longlong val_int(); 01291 const char *func_name() const { return "multiple equal"; } 01292 optimize_type select_optimize() const { return OPTIMIZE_EQUAL; } 01293 void sort(Item_field_cmpfunc cmp, void *arg); 01294 friend class Item_equal_iterator; 01295 void fix_length_and_dec(); 01296 bool fix_fields(THD *thd, Item **ref); 01297 void update_used_tables(); 01298 bool walk(Item_processor processor, bool walk_subquery, byte *arg); 01299 Item *transform(Item_transformer transformer, byte *arg); 01300 void print(String *str); 01301 CHARSET_INFO *compare_collation() 01302 { return fields.head()->collation.collation; } 01303 }; 01304 01305 class COND_EQUAL: public Sql_alloc 01306 { 01307 public: 01308 uint max_members; /* max number of members the current level 01309 list and all lower level lists */ 01310 COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */ 01311 List<Item_equal> current_level; /* list of multiple equalities of 01312 the current and level */ 01313 COND_EQUAL() 01314 { 01315 max_members= 0; 01316 upper_levels= 0; 01317 } 01318 }; 01319 01320 01321 class Item_equal_iterator : public List_iterator_fast<Item_field> 01322 { 01323 public: 01324 inline Item_equal_iterator(Item_equal &item_equal) 01325 :List_iterator_fast<Item_field> (item_equal.fields) 01326 {} 01327 inline Item_field* operator++(int) 01328 { 01329 Item_field *item= (*(List_iterator_fast<Item_field> *) this)++; 01330 return item; 01331 } 01332 inline void rewind(void) 01333 { 01334 List_iterator_fast<Item_field>::rewind(); 01335 } 01336 }; 01337 01338 class Item_cond_and :public Item_cond 01339 { 01340 public: 01341 COND_EQUAL cond_equal; /* contains list of Item_equal objects for 01342 the current and level and reference 01343 to multiple equalities of upper and levels */ 01344 Item_cond_and() :Item_cond() {} 01345 Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {} 01346 Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {} 01347 Item_cond_and(List<Item> &list): Item_cond(list) {} 01348 enum Functype functype() const { return COND_AND_FUNC; } 01349 longlong val_int(); 01350 const char *func_name() const { return "and"; } 01351 table_map not_null_tables() const 01352 { return abort_on_null ? not_null_tables_cache: and_tables_cache; } 01353 Item* copy_andor_structure(THD *thd) 01354 { 01355 Item_cond_and *item; 01356 if ((item= new Item_cond_and(thd, this))) 01357 item->copy_andor_arguments(thd, this); 01358 return item; 01359 } 01360 Item *neg_transformer(THD *thd); 01361 }; 01362 01363 class Item_cond_or :public Item_cond 01364 { 01365 public: 01366 Item_cond_or() :Item_cond() {} 01367 Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {} 01368 Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {} 01369 Item_cond_or(List<Item> &list): Item_cond(list) {} 01370 enum Functype functype() const { return COND_OR_FUNC; } 01371 longlong val_int(); 01372 const char *func_name() const { return "or"; } 01373 table_map not_null_tables() const { return and_tables_cache; } 01374 Item* copy_andor_structure(THD *thd) 01375 { 01376 Item_cond_or *item; 01377 if ((item= new Item_cond_or(thd, this))) 01378 item->copy_andor_arguments(thd, this); 01379 return item; 01380 } 01381 Item *neg_transformer(THD *thd); 01382 }; 01383 01384 01385 /* 01386 XOR is Item_cond, not an Item_int_func because we could like to 01387 optimize (a XOR b) later on. It's low prio, though 01388 */ 01389 01390 class Item_cond_xor :public Item_cond 01391 { 01392 public: 01393 Item_cond_xor() :Item_cond() {} 01394 Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {} 01395 enum Functype functype() const { return COND_XOR_FUNC; } 01396 /* TODO: remove the next line when implementing XOR optimization */ 01397 enum Type type() const { return FUNC_ITEM; } 01398 longlong val_int(); 01399 const char *func_name() const { return "xor"; } 01400 void top_level_item() {} 01401 }; 01402 01403 01404 /* Some useful inline functions */ 01405 01406 inline Item *and_conds(Item *a, Item *b) 01407 { 01408 if (!b) return a; 01409 if (!a) return b; 01410 return new Item_cond_and(a, b); 01411 } 01412 01413 Item *and_expressions(Item *a, Item *b, Item **org_item);
1.4.7

