00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #pragma once
00021
00022
00023
00024
00025 #include <drizzled/comp_creator.h>
00026 #include <drizzled/item/ref.h>
00027 #include <drizzled/item/field.h>
00028 #include <drizzled/item/bin_string.h>
00029 #include <drizzled/util/test.h>
00030
00031 namespace drizzled
00032 {
00033
00034 class Select_Lex;
00035 class Select_Lex_Unit;
00036 class Join;
00037 class select_result_interceptor;
00038 class subselect_engine;
00039 class subselect_hash_sj_engine;
00040 class Item_bool_func2;
00041 class Cached_item;
00042 class Item_in_optimizer;
00043 class Item_func_not_all;
00044 class Tmp_Table_Param;
00045
00046
00047
00048
00049 class Item_subselect :public Item_result_field
00050 {
00051 bool value_assigned;
00052 public:
00053
00054 Session *session;
00055
00056 Item *substitution;
00057
00058 Select_Lex_Unit *unit;
00059 protected:
00060
00061 subselect_engine *engine;
00062
00063 subselect_engine *old_engine;
00064
00065 table_map used_tables_cache;
00066
00067 uint32_t max_columns;
00068
00069 enum_parsing_place parsing_place;
00070
00071 bool have_to_be_excluded;
00072
00073 bool const_item_cache;
00074
00075 public:
00076
00077 bool engine_changed;
00078
00079 bool changed;
00080
00081
00082 bool is_correlated;
00083
00084 enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
00085 enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
00086 EXISTS_SUBS, IN_SUBS, ALL_SUBS, ANY_SUBS};
00087
00088 Item_subselect();
00089
00090 virtual subs_type substype() { return UNKNOWN_SUBS; }
00091
00092
00093
00094
00095
00096
00097 virtual void init (Select_Lex *select_lex,
00098 select_result_interceptor *result);
00099
00100 ~Item_subselect();
00101 void cleanup();
00102 virtual void reset()
00103 {
00104 null_value= 1;
00105 }
00106 virtual trans_res select_transformer(Join *join);
00107 bool assigned() { return value_assigned; }
00108 void assigned(bool a) { value_assigned= a; }
00109 enum Type type() const;
00110 bool is_null()
00111 {
00112 update_null_value();
00113 return null_value;
00114 }
00115 bool fix_fields(Session *session, Item **ref);
00116 virtual bool exec();
00117 virtual void fix_length_and_dec();
00118 table_map used_tables() const;
00119 table_map not_null_tables() const { return 0; }
00120 bool const_item() const;
00121 inline table_map get_used_tables_cache() { return used_tables_cache; }
00122 inline bool get_const_item_cache() { return const_item_cache; }
00123 Item *get_tmp_table_item(Session *session);
00124 void update_used_tables();
00125 virtual void print(String *str);
00126 virtual bool have_guarded_conds() { return false; }
00127 bool change_engine(subselect_engine *eng)
00128 {
00129 old_engine= engine;
00130 engine= eng;
00131 engine_changed= 1;
00132 return eng == 0;
00133 }
00134
00135
00136
00137
00138 bool is_evaluated() const;
00139 bool is_uncacheable() const;
00140
00141
00142
00143
00144
00145 virtual void reset_value_registration() {}
00146 enum_parsing_place place() { return parsing_place; }
00147 bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
00148
00153 Select_Lex* get_select_lex();
00154
00155 friend class select_result_interceptor;
00156 friend class Item_in_optimizer;
00157 friend bool Item_field::fix_fields(Session *, Item **);
00158 friend int Item_field::fix_outer_field(Session *, Field **, Item **);
00159 friend bool Item_ref::fix_fields(Session *, Item **);
00160 friend void mark_select_range_as_dependent(Session*,
00161 Select_Lex*, Select_Lex*,
00162 Field*, Item*, Item_ident*);
00163 };
00164
00165
00166
00167 class Item_cache;
00168 class Item_singlerow_subselect :public Item_subselect
00169 {
00170 protected:
00171 Item_cache *value, **row;
00172 public:
00173 Item_singlerow_subselect(Select_Lex *select_lex);
00174 Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
00175
00176 void cleanup();
00177 subs_type substype() { return SINGLEROW_SUBS; }
00178
00179 void reset();
00180 trans_res select_transformer(Join *join);
00181 void store(uint32_t i, Item* item);
00182 double val_real();
00183 int64_t val_int ();
00184 String *val_str (String *);
00185 type::Decimal *val_decimal(type::Decimal *);
00186 bool val_bool();
00187 enum Item_result result_type() const;
00188 enum_field_types field_type() const;
00189 void fix_length_and_dec();
00190
00191 uint32_t cols();
00192 Item* element_index(uint32_t i) { return reinterpret_cast<Item*>(row[i]); }
00193 Item** addr(uint32_t i) { return (Item**)row + i; }
00194 bool check_cols(uint32_t c);
00195 bool null_inside();
00196 void bring_value();
00197
00210 Select_Lex* invalidate_and_restore_select_lex();
00211
00212 friend class select_singlerow_subselect;
00213 };
00214
00215
00216 class Item_maxmin_subselect :public Item_singlerow_subselect
00217 {
00218 protected:
00219 bool max;
00220 bool was_values;
00221 public:
00222 Item_maxmin_subselect(Session *session, Item_subselect *parent,
00223 Select_Lex *select_lex, bool max);
00224 virtual void print(String *str);
00225 void cleanup();
00226 bool any_value() { return was_values; }
00227 void register_value() { was_values= true; }
00228 void reset_value_registration() { was_values= false; }
00229 };
00230
00231
00232
00233 class Item_exists_subselect :public Item_subselect
00234 {
00235 protected:
00236 bool value;
00237
00238 public:
00239 Item_exists_subselect(Select_Lex *select_lex);
00240 Item_exists_subselect(): Item_subselect() {}
00241
00242 subs_type substype() { return EXISTS_SUBS; }
00243 void reset()
00244 {
00245 value= 0;
00246 }
00247
00248 enum Item_result result_type() const { return INT_RESULT;}
00249 int64_t val_int();
00250 double val_real();
00251 String *val_str(String*);
00252 type::Decimal *val_decimal(type::Decimal *);
00253 bool val_bool();
00254 void fix_length_and_dec();
00255 virtual void print(String *str);
00256
00257 friend class select_exists_subselect;
00258 friend class subselect_uniquesubquery_engine;
00259 friend class subselect_indexsubquery_engine;
00260 };
00261
00262
00278 class Item_in_subselect :public Item_exists_subselect
00279 {
00280 public:
00281 Item *left_expr;
00282 protected:
00283
00284
00285
00286
00287 List<Cached_item> *left_expr_cache;
00288 bool first_execution;
00289
00290
00291
00292
00293
00294 Item *expr;
00295 Item_in_optimizer *optimizer;
00296 bool was_null;
00297 bool abort_on_null;
00298
00299 public:
00300
00301 bool *pushed_cond_guards;
00302
00303
00304 int sj_convert_priority;
00305
00306
00307
00308
00309
00310
00311 TableList *expr_join_nest;
00312
00313
00314 enum enum_exec_method {
00315 NOT_TRANSFORMED,
00316 SEMI_JOIN,
00317 IN_TO_EXISTS,
00318 MATERIALIZATION
00319 };
00320 enum_exec_method exec_method;
00321
00322 bool *get_cond_guard(int i)
00323 {
00324 return pushed_cond_guards ? pushed_cond_guards + i : NULL;
00325 }
00326 void set_cond_guard_var(int i, bool v)
00327 {
00328 if ( pushed_cond_guards)
00329 pushed_cond_guards[i]= v;
00330 }
00331 bool have_guarded_conds() { return test(pushed_cond_guards); }
00332
00333 Item_func_not_all *upper_item;
00334
00335 Item_in_subselect(Item * left_expr, Select_Lex *select_lex);
00336 Item_in_subselect()
00337 :
00338 Item_exists_subselect(),
00339 left_expr(NULL),
00340 left_expr_cache(NULL),
00341 first_execution(true),
00342 optimizer(NULL),
00343 abort_on_null(false),
00344 pushed_cond_guards(NULL),
00345 sj_convert_priority(0),
00346 expr_join_nest(NULL),
00347 exec_method(NOT_TRANSFORMED),
00348 upper_item(NULL)
00349 {}
00350 void cleanup();
00351 subs_type substype() { return IN_SUBS; }
00352 void reset()
00353 {
00354 value= 0;
00355 null_value= 0;
00356 was_null= 0;
00357 }
00358 trans_res select_transformer(Join *join);
00359 trans_res select_in_like_transformer(Join *join, const Comp_creator *func);
00360 trans_res single_value_transformer(Join *join, const Comp_creator *func);
00361 trans_res row_value_transformer(Join * join);
00362 trans_res single_value_in_to_exists_transformer(Join * join,
00363 const Comp_creator *func);
00364 trans_res row_value_in_to_exists_transformer(Join * join);
00365 virtual bool exec();
00366 int64_t val_int();
00367 double val_real();
00368 String *val_str(String*);
00369 type::Decimal *val_decimal(type::Decimal *);
00370 void update_null_value () { (void) val_bool(); }
00371 bool val_bool();
00372 void top_level_item() { abort_on_null=1; }
00373 inline bool is_top_level_item() { return abort_on_null; }
00374 bool test_limit(Select_Lex_Unit *unit);
00375 virtual void print(String *str);
00376 bool fix_fields(Session *session, Item **ref);
00377 bool setup_engine();
00378 bool init_left_expr_cache();
00379 bool is_expensive_processor(unsigned char *arg);
00380
00381 friend class Item_ref_null_helper;
00382 friend class Item_is_not_null_test;
00383 friend class Item_in_optimizer;
00384 friend class subselect_indexsubquery_engine;
00385 friend class subselect_hash_sj_engine;
00386 };
00387
00388
00389
00390 class Item_allany_subselect :public Item_in_subselect
00391 {
00392 public:
00393 chooser_compare_func_creator func_creator;
00394 Comp_creator *func;
00395 bool all;
00396
00397 Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
00398 Select_Lex *select_lex, bool all);
00399
00400
00401 subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
00402 trans_res select_transformer(Join *join);
00403 virtual void print(String *str);
00404 };
00405
00406
00407 class subselect_engine: public memory::SqlAlloc
00408 {
00409 protected:
00410 select_result_interceptor *result;
00411 Session *session;
00412 Item_subselect *item;
00413 enum Item_result res_type;
00414 enum_field_types res_field_type;
00415 bool maybe_null;
00416 public:
00417
00418 enum enum_engine_type {ABSTRACT_ENGINE, SINGLE_SELECT_ENGINE,
00419 UNION_ENGINE, UNIQUESUBQUERY_ENGINE,
00420 INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE};
00421
00422 subselect_engine(Item_subselect *si, select_result_interceptor *res)
00423 :session(NULL)
00424 {
00425 result= res;
00426 item= si;
00427 res_type= STRING_RESULT;
00428 res_field_type= DRIZZLE_TYPE_VARCHAR;
00429 maybe_null= 0;
00430 }
00431 virtual ~subselect_engine() {}
00432 virtual void cleanup()= 0;
00433
00434
00435
00436
00437
00438 void set_session(Session *session_arg);
00439 Session * get_session() { return session; }
00440 virtual int prepare()= 0;
00441 virtual void fix_length_and_dec(Item_cache** row)= 0;
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 virtual int exec()= 0;
00463 virtual uint32_t cols()= 0;
00464 virtual bool uncacheable()= 0;
00465 virtual bool uncacheable(uint32_t bit_pos)= 0;
00466 enum Item_result type() { return res_type; }
00467 enum_field_types field_type() { return res_field_type; }
00468 virtual void exclude()= 0;
00469 virtual bool may_be_null() { return maybe_null; }
00470 virtual table_map upper_select_const_tables()= 0;
00471 static table_map calc_const_tables(TableList *);
00472 virtual void print(String *str)= 0;
00473 virtual bool change_result(Item_subselect *si,
00474 select_result_interceptor *result)= 0;
00475 virtual bool no_tables()= 0;
00476 virtual bool is_executed() const { return false; }
00477
00478 virtual bool no_rows() = 0;
00479 virtual enum_engine_type engine_type() { return ABSTRACT_ENGINE; }
00480
00481 protected:
00482 void set_row(List<Item> &item_list, Item_cache **row);
00483 };
00484
00485
00486 class subselect_single_select_engine: public subselect_engine
00487 {
00488 bool prepared;
00489 bool optimized;
00490 bool executed;
00491 Select_Lex *select_lex;
00492 Join * join;
00493 public:
00494 subselect_single_select_engine(Select_Lex *select,
00495 select_result_interceptor *result,
00496 Item_subselect *item);
00497 void cleanup();
00498 int prepare();
00499 void fix_length_and_dec(Item_cache** row);
00500 int exec();
00501 uint32_t cols();
00502 bool uncacheable();
00503 bool uncacheable(uint32_t bit_pos);
00504 void exclude();
00505 table_map upper_select_const_tables();
00506 virtual void print (String *str);
00507 bool change_result(Item_subselect *si, select_result_interceptor *result);
00508 bool no_tables();
00509 bool may_be_null();
00510 bool is_executed() const { return executed; }
00511 bool no_rows();
00512 virtual enum_engine_type engine_type() { return SINGLE_SELECT_ENGINE; }
00513 bool save_join_if_explain();
00514
00515 friend class subselect_hash_sj_engine;
00516 friend class Item_in_subselect;
00517 };
00518
00519
00520 class subselect_union_engine: public subselect_engine
00521 {
00522 Select_Lex_Unit *unit;
00523 public:
00524 subselect_union_engine(Select_Lex_Unit *u,
00525 select_result_interceptor *result,
00526 Item_subselect *item);
00527 void cleanup();
00528 int prepare();
00529 void fix_length_and_dec(Item_cache** row);
00530 int exec();
00531 uint32_t cols();
00532 bool uncacheable();
00533 bool uncacheable(uint32_t bit_pos);
00534 void exclude();
00535 table_map upper_select_const_tables();
00536 virtual void print (String *str);
00537 bool change_result(Item_subselect *si, select_result_interceptor *result);
00538 bool no_tables();
00539 bool is_executed() const;
00540 bool no_rows();
00541 virtual enum_engine_type engine_type() { return UNION_ENGINE; }
00542 };
00543
00544
00545 class JoinTable;
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 class subselect_uniquesubquery_engine: public subselect_engine
00566 {
00567 protected:
00568 JoinTable *tab;
00569 Item *cond;
00570
00571
00572
00573
00574 bool empty_result_set;
00575 bool null_keypart;
00576 public:
00577
00578
00579 subselect_uniquesubquery_engine(Session *session_arg, JoinTable *tab_arg,
00580 Item_subselect *subs, Item *where)
00581 :subselect_engine(subs, 0), tab(tab_arg), cond(where)
00582 {
00583 set_session(session_arg);
00584 }
00585 void cleanup();
00586 int prepare();
00587 void fix_length_and_dec(Item_cache** row);
00588 int exec();
00589 uint32_t cols() { return 1; }
00590 bool uncacheable() { return true; }
00591 bool uncacheable(uint32_t) { return true; }
00592 void exclude();
00593 table_map upper_select_const_tables() { return 0; }
00594 virtual void print (String *str);
00595 bool change_result(Item_subselect *si, select_result_interceptor *result);
00596 bool no_tables();
00597 int scan_table();
00598 bool copy_ref_key();
00599 bool no_rows() { return empty_result_set; }
00600 virtual enum_engine_type engine_type() { return UNIQUESUBQUERY_ENGINE; }
00601 };
00602
00603
00604 class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
00605 {
00606
00607 bool check_null;
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 Item *having;
00638 public:
00639
00640
00641 subselect_indexsubquery_engine(Session *session_arg, JoinTable *tab_arg,
00642 Item_subselect *subs, Item *where,
00643 Item *having_arg, bool chk_null)
00644 :subselect_uniquesubquery_engine(session_arg, tab_arg, subs, where),
00645 check_null(chk_null),
00646 having(having_arg)
00647 {}
00648 int exec();
00649 virtual void print (String *str);
00650 virtual enum_engine_type engine_type() { return INDEXSUBQUERY_ENGINE; }
00651 };
00652
00653
00654 inline bool Item_subselect::is_evaluated() const
00655 {
00656 return engine->is_executed();
00657 }
00658
00659
00660 inline bool Item_subselect::is_uncacheable() const
00661 {
00662 return engine->uncacheable();
00663 }
00664
00665
00672 class subselect_hash_sj_engine: public subselect_uniquesubquery_engine
00673 {
00674 protected:
00675
00676 bool is_materialized;
00677
00678
00679
00680
00681
00682
00683 subselect_single_select_engine *materialize_engine;
00684
00685
00686
00687
00688 Join *materialize_join;
00689
00690 Tmp_Table_Param *tmp_param;
00691
00692 public:
00693 subselect_hash_sj_engine(Session *session_in, Item_subselect *in_predicate,
00694 subselect_single_select_engine *old_engine)
00695 :subselect_uniquesubquery_engine(session_in, NULL, in_predicate, NULL),
00696 is_materialized(false), materialize_engine(old_engine),
00697 materialize_join(NULL), tmp_param(NULL)
00698 {}
00699 ~subselect_hash_sj_engine();
00700
00701 bool init_permanent(List<Item> *tmp_columns);
00702 bool init_runtime();
00703 void cleanup();
00704 int prepare() { return 0; }
00705 int exec();
00706 virtual void print (String *str);
00707 uint32_t cols()
00708 {
00709 return materialize_engine->cols();
00710 }
00711 virtual enum_engine_type engine_type() { return HASH_SJ_ENGINE; }
00712 };
00713
00714 }
00715