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