~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to sql/item_subselect.h

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
/* subselect Item */
 
17
 
 
18
#ifdef USE_PRAGMA_INTERFACE
 
19
#pragma interface                       /* gcc class implementation */
 
20
#endif
 
21
 
 
22
class st_select_lex;
 
23
class st_select_lex_unit;
 
24
class JOIN;
 
25
class select_subselect;
 
26
class subselect_engine;
 
27
class Item_bool_func2;
 
28
 
 
29
/* base class for subselects */
 
30
 
 
31
class Item_subselect :public Item_result_field
 
32
{
 
33
  my_bool value_assigned; /* value already assigned to subselect */
 
34
protected:
 
35
  /* thread handler, will be assigned in fix_fields only */
 
36
  THD *thd;
 
37
  /* substitution instead of subselect in case of optimization */
 
38
  Item *substitution;
 
39
  /* unit of subquery */
 
40
  st_select_lex_unit *unit;
 
41
  /* engine that perform execution of subselect (single select or union) */
 
42
  subselect_engine *engine;
 
43
  /* old engine if engine was changed */
 
44
  subselect_engine *old_engine;
 
45
  /* cache of used external tables */
 
46
  table_map used_tables_cache;
 
47
  /* allowed number of columns (1 for single value subqueries) */
 
48
  uint max_columns;
 
49
  /* where subquery is placed */
 
50
  enum_parsing_place parsing_place;
 
51
  /* work with 'substitution' */
 
52
  bool have_to_be_excluded;
 
53
  /* cache of constant state */
 
54
  bool const_item_cache;
 
55
 
 
56
public:
 
57
  /* changed engine indicator */
 
58
  bool engine_changed;
 
59
  /* subquery is transformed */
 
60
  bool changed;
 
61
 
 
62
  /* TRUE <=> The underlying SELECT is correlated w.r.t some ancestor select */
 
63
  bool is_correlated; 
 
64
 
 
65
  enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
 
66
  enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
 
67
                  EXISTS_SUBS, IN_SUBS, ALL_SUBS, ANY_SUBS};
 
68
 
 
69
  Item_subselect();
 
70
 
 
71
  virtual subs_type substype() { return UNKNOWN_SUBS; }
 
72
 
 
73
  /*
 
74
     We need this method, because some compilers do not allow 'this'
 
75
     pointer in constructor initialization list, but we need pass pointer
 
76
     to subselect Item class to select_subselect classes constructor.
 
77
  */
 
78
  virtual void init (st_select_lex *select_lex,
 
79
                     select_subselect *result);
 
80
 
 
81
  ~Item_subselect();
 
82
  void cleanup();
 
83
  virtual void reset()
 
84
  {
 
85
    null_value= 1;
 
86
  }
 
87
  virtual trans_res select_transformer(JOIN *join);
 
88
  bool assigned() { return value_assigned; }
 
89
  void assigned(bool a) { value_assigned= a; }
 
90
  enum Type type() const;
 
91
  bool is_null()
 
92
  {
 
93
    update_null_value();
 
94
    return null_value;
 
95
  }
 
96
  bool fix_fields(THD *thd, Item **ref);
 
97
  virtual bool exec();
 
98
  virtual void fix_length_and_dec();
 
99
  table_map used_tables() const;
 
100
  table_map not_null_tables() const { return 0; }
 
101
  bool const_item() const;
 
102
  inline table_map get_used_tables_cache() { return used_tables_cache; }
 
103
  inline bool get_const_item_cache() { return const_item_cache; }
 
104
  Item *get_tmp_table_item(THD *thd);
 
105
  void update_used_tables();
 
106
  virtual void print(String *str, enum_query_type query_type);
 
107
  virtual bool have_guarded_conds() { return FALSE; }
 
108
  bool change_engine(subselect_engine *eng)
 
109
  {
 
110
    old_engine= engine;
 
111
    engine= eng;
 
112
    engine_changed= 1;
 
113
    return eng == 0;
 
114
  }
 
115
  /*
 
116
    True if this subquery has been already evaluated. Implemented only for
 
117
    single select and union subqueries only.
 
118
  */
 
119
  bool is_evaluated() const;
 
120
  bool is_uncacheable() const;
 
121
 
 
122
  /*
 
123
    Used by max/min subquery to initialize value presence registration
 
124
    mechanism. Engine call this method before rexecution query.
 
125
  */
 
126
  virtual void reset_value_registration() {}
 
127
  enum_parsing_place place() { return parsing_place; }
 
128
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
 
129
 
 
130
  /**
 
131
    Get the SELECT_LEX structure associated with this Item.
 
132
    @return the SELECT_LEX structure associated with this Item
 
133
  */
 
134
  st_select_lex* get_select_lex();
 
135
  const char *func_name() const { DBUG_ASSERT(0); return "subselect"; }
 
136
 
 
137
  friend class select_subselect;
 
138
  friend class Item_in_optimizer;
 
139
  friend bool Item_field::fix_fields(THD *, Item **);
 
140
  friend int  Item_field::fix_outer_field(THD *, Field **, Item **);
 
141
  friend bool Item_ref::fix_fields(THD *, Item **);
 
142
  friend void mark_select_range_as_dependent(THD*,
 
143
                                             st_select_lex*, st_select_lex*,
 
144
                                             Field*, Item*, Item_ident*);
 
145
};
 
146
 
 
147
/* single value subselect */
 
148
 
 
149
class Item_cache;
 
150
class Item_singlerow_subselect :public Item_subselect
 
151
{
 
152
protected:
 
153
  Item_cache *value, **row;
 
154
public:
 
155
  Item_singlerow_subselect(st_select_lex *select_lex);
 
156
  Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
 
157
 
 
158
  void cleanup();
 
159
  subs_type substype() { return SINGLEROW_SUBS; }
 
160
 
 
161
  void reset();
 
162
  trans_res select_transformer(JOIN *join);
 
163
  void store(uint i, Item* item);
 
164
  double val_real();
 
165
  longlong val_int ();
 
166
  String *val_str (String *);
 
167
  my_decimal *val_decimal(my_decimal *);
 
168
  bool val_bool();
 
169
  enum Item_result result_type() const;
 
170
  enum_field_types field_type() const;
 
171
  void fix_length_and_dec();
 
172
 
 
173
  uint cols();
 
174
  Item* element_index(uint i) { return my_reinterpret_cast(Item*)(row[i]); }
 
175
  Item** addr(uint i) { return (Item**)row + i; }
 
176
  bool check_cols(uint c);
 
177
  bool null_inside();
 
178
  void bring_value();
 
179
 
 
180
  /**
 
181
    This method is used to implement a special case of semantic tree
 
182
    rewriting, mandated by a SQL:2003 exception in the specification.
 
183
    The only caller of this method is handle_sql2003_note184_exception(),
 
184
    see the code there for more details.
 
185
    Note that this method breaks the object internal integrity, by
 
186
    removing it's association with the corresponding SELECT_LEX,
 
187
    making this object orphan from the parse tree.
 
188
    No other method, beside the destructor, should be called on this
 
189
    object, as it is now invalid.
 
190
    @return the SELECT_LEX structure that was given in the constructor.
 
191
  */
 
192
  st_select_lex* invalidate_and_restore_select_lex();
 
193
 
 
194
  friend class select_singlerow_subselect;
 
195
};
 
196
 
 
197
/* used in static ALL/ANY optimization */
 
198
class select_max_min_finder_subselect;
 
199
class Item_maxmin_subselect :public Item_singlerow_subselect
 
200
{
 
201
protected:
 
202
  bool max;
 
203
  bool was_values;  // Set if we have found at least one row
 
204
public:
 
205
  Item_maxmin_subselect(THD *thd, Item_subselect *parent,
 
206
                        st_select_lex *select_lex, bool max);
 
207
  virtual void print(String *str, enum_query_type query_type);
 
208
  void cleanup();
 
209
  bool any_value() { return was_values; }
 
210
  void register_value() { was_values= TRUE; }
 
211
  void reset_value_registration() { was_values= FALSE; }
 
212
};
 
213
 
 
214
/* exists subselect */
 
215
 
 
216
class Item_exists_subselect :public Item_subselect
 
217
{
 
218
protected:
 
219
  bool value; /* value of this item (boolean: exists/not-exists) */
 
220
 
 
221
public:
 
222
  Item_exists_subselect(st_select_lex *select_lex);
 
223
  Item_exists_subselect(): Item_subselect() {}
 
224
 
 
225
  subs_type substype() { return EXISTS_SUBS; }
 
226
  void reset() 
 
227
  {
 
228
    value= 0;
 
229
  }
 
230
 
 
231
  enum Item_result result_type() const { return INT_RESULT;}
 
232
  longlong val_int();
 
233
  double val_real();
 
234
  String *val_str(String*);
 
235
  my_decimal *val_decimal(my_decimal *);
 
236
  bool val_bool();
 
237
  void fix_length_and_dec();
 
238
  virtual void print(String *str, enum_query_type query_type);
 
239
 
 
240
  friend class select_exists_subselect;
 
241
  friend class subselect_uniquesubquery_engine;
 
242
  friend class subselect_indexsubquery_engine;
 
243
};
 
244
 
 
245
 
 
246
/*
 
247
  IN subselect: this represents "left_exr IN (SELECT ...)"
 
248
 
 
249
  This class has: 
 
250
   - (as a descendant of Item_subselect) a "subquery execution engine" which 
 
251
      allows it to evaluate subqueries. (and this class participates in
 
252
      execution by having was_null variable where part of execution result
 
253
      is stored.
 
254
   - Transformation methods (todo: more on this).
 
255
 
 
256
  This class is not used directly, it is "wrapped" into Item_in_optimizer
 
257
  which provides some small bits of subquery evaluation.
 
258
*/
 
259
 
 
260
class Item_in_subselect :public Item_exists_subselect
 
261
{
 
262
protected:
 
263
  Item *left_expr;
 
264
  /*
 
265
    expr & optimizer used in subselect rewriting to store Item for
 
266
    all JOIN in UNION
 
267
  */
 
268
  Item *expr;
 
269
  Item_in_optimizer *optimizer;
 
270
  bool was_null;
 
271
  bool abort_on_null;
 
272
  bool transformed;
 
273
public:
 
274
  /* Used to trigger on/off conditions that were pushed down to subselect */
 
275
  bool *pushed_cond_guards;
 
276
 
 
277
  bool *get_cond_guard(int i)
 
278
  {
 
279
    return pushed_cond_guards ? pushed_cond_guards + i : NULL;
 
280
  }
 
281
  void set_cond_guard_var(int i, bool v) 
 
282
  { 
 
283
    if ( pushed_cond_guards)
 
284
      pushed_cond_guards[i]= v;
 
285
  }
 
286
  bool have_guarded_conds() { return test(pushed_cond_guards); }
 
287
 
 
288
  Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery
 
289
 
 
290
  Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
 
291
  Item_in_subselect()
 
292
    :Item_exists_subselect(), optimizer(0), abort_on_null(0), transformed(0),
 
293
     pushed_cond_guards(NULL), upper_item(0)
 
294
  {}
 
295
 
 
296
  subs_type substype() { return IN_SUBS; }
 
297
  void reset() 
 
298
  {
 
299
    value= 0;
 
300
    null_value= 0;
 
301
    was_null= 0;
 
302
  }
 
303
  trans_res select_transformer(JOIN *join);
 
304
  trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
 
305
  trans_res single_value_transformer(JOIN *join, Comp_creator *func);
 
306
  trans_res row_value_transformer(JOIN * join);
 
307
  longlong val_int();
 
308
  double val_real();
 
309
  String *val_str(String*);
 
310
  my_decimal *val_decimal(my_decimal *);
 
311
  void update_null_value () { (void) val_bool(); }
 
312
  bool val_bool();
 
313
  void top_level_item() { abort_on_null=1; }
 
314
  inline bool is_top_level_item() { return abort_on_null; }
 
315
  bool test_limit(st_select_lex_unit *unit);
 
316
  virtual void print(String *str, enum_query_type query_type);
 
317
  bool fix_fields(THD *thd, Item **ref);
 
318
 
 
319
  friend class Item_ref_null_helper;
 
320
  friend class Item_is_not_null_test;
 
321
  friend class subselect_indexsubquery_engine;
 
322
};
 
323
 
 
324
 
 
325
/* ALL/ANY/SOME subselect */
 
326
class Item_allany_subselect :public Item_in_subselect
 
327
{
 
328
public:
 
329
  chooser_compare_func_creator func_creator;
 
330
  Comp_creator *func;
 
331
  bool all;
 
332
 
 
333
  Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
 
334
                        st_select_lex *select_lex, bool all);
 
335
 
 
336
  // only ALL subquery has upper not
 
337
  subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
 
338
  trans_res select_transformer(JOIN *join);
 
339
  virtual void print(String *str, enum_query_type query_type);
 
340
};
 
341
 
 
342
 
 
343
class subselect_engine: public Sql_alloc
 
344
{
 
345
protected:
 
346
  select_subselect *result; /* results storage class */
 
347
  THD *thd; /* pointer to current THD */
 
348
  Item_subselect *item; /* item, that use this engine */
 
349
  enum Item_result res_type; /* type of results */
 
350
  enum_field_types res_field_type; /* column type of the results */
 
351
  bool maybe_null; /* may be null (first item in select) */
 
352
public:
 
353
 
 
354
  subselect_engine(Item_subselect *si, select_subselect *res)
 
355
    :thd(0)
 
356
  {
 
357
    result= res;
 
358
    item= si;
 
359
    res_type= STRING_RESULT;
 
360
    res_field_type= MYSQL_TYPE_VAR_STRING;
 
361
    maybe_null= 0;
 
362
  }
 
363
  virtual ~subselect_engine() {}; // to satisfy compiler
 
364
  virtual void cleanup()= 0;
 
365
 
 
366
  /*
 
367
    Also sets "thd" for subselect_engine::result.
 
368
    Should be called before prepare().
 
369
  */
 
370
  void set_thd(THD *thd_arg);
 
371
  THD * get_thd() { return thd; }
 
372
  virtual int prepare()= 0;
 
373
  virtual void fix_length_and_dec(Item_cache** row)= 0;
 
374
  /*
 
375
    Execute the engine
 
376
 
 
377
    SYNOPSIS
 
378
      exec()
 
379
 
 
380
    DESCRIPTION
 
381
      Execute the engine. The result of execution is subquery value that is
 
382
      either captured by previously set up select_result-based 'sink' or
 
383
      stored somewhere by the exec() method itself.
 
384
 
 
385
      A required side effect: If at least one pushed-down predicate is
 
386
      disabled, subselect_engine->no_rows() must return correct result after 
 
387
      the exec() call.
 
388
 
 
389
    RETURN
 
390
      0 - OK
 
391
      1 - Either an execution error, or the engine was "changed", and the
 
392
          caller should call exec() again for the new engine.
 
393
  */
 
394
  virtual int exec()= 0;
 
395
  virtual uint cols()= 0; /* return number of columns in select */
 
396
  virtual uint8 uncacheable()= 0; /* query is uncacheable */
 
397
  enum Item_result type() { return res_type; }
 
398
  enum_field_types field_type() { return res_field_type; }
 
399
  virtual void exclude()= 0;
 
400
  virtual bool may_be_null() { return maybe_null; };
 
401
  virtual table_map upper_select_const_tables()= 0;
 
402
  static table_map calc_const_tables(TABLE_LIST *);
 
403
  virtual void print(String *str, enum_query_type query_type)= 0;
 
404
  virtual bool change_result(Item_subselect *si, select_subselect *result)= 0;
 
405
  virtual bool no_tables()= 0;
 
406
  virtual bool is_executed() const { return FALSE; }
 
407
  /* Check if subquery produced any rows during last query execution */
 
408
  virtual bool no_rows() = 0;
 
409
 
 
410
protected:
 
411
  void set_row(List<Item> &item_list, Item_cache **row);
 
412
};
 
413
 
 
414
 
 
415
class subselect_single_select_engine: public subselect_engine
 
416
{
 
417
  my_bool prepared; /* simple subselect is prepared */
 
418
  my_bool optimized; /* simple subselect is optimized */
 
419
  my_bool executed; /* simple subselect is executed */
 
420
  st_select_lex *select_lex; /* corresponding select_lex */
 
421
  JOIN * join; /* corresponding JOIN structure */
 
422
public:
 
423
  subselect_single_select_engine(st_select_lex *select,
 
424
                                 select_subselect *result,
 
425
                                 Item_subselect *item);
 
426
  void cleanup();
 
427
  int prepare();
 
428
  void fix_length_and_dec(Item_cache** row);
 
429
  int exec();
 
430
  uint cols();
 
431
  uint8 uncacheable();
 
432
  void exclude();
 
433
  table_map upper_select_const_tables();
 
434
  virtual void print (String *str, enum_query_type query_type);
 
435
  bool change_result(Item_subselect *si, select_subselect *result);
 
436
  bool no_tables();
 
437
  bool may_be_null();
 
438
  bool is_executed() const { return executed; }
 
439
  bool no_rows();
 
440
};
 
441
 
 
442
 
 
443
class subselect_union_engine: public subselect_engine
 
444
{
 
445
  st_select_lex_unit *unit;  /* corresponding unit structure */
 
446
public:
 
447
  subselect_union_engine(st_select_lex_unit *u,
 
448
                         select_subselect *result,
 
449
                         Item_subselect *item);
 
450
  void cleanup();
 
451
  int prepare();
 
452
  void fix_length_and_dec(Item_cache** row);
 
453
  int exec();
 
454
  uint cols();
 
455
  uint8 uncacheable();
 
456
  void exclude();
 
457
  table_map upper_select_const_tables();
 
458
  virtual void print (String *str, enum_query_type query_type);
 
459
  bool change_result(Item_subselect *si, select_subselect *result);
 
460
  bool no_tables();
 
461
  bool is_executed() const;
 
462
  bool no_rows();
 
463
};
 
464
 
 
465
 
 
466
struct st_join_table;
 
467
 
 
468
 
 
469
/*
 
470
  A subquery execution engine that evaluates the subquery by doing one index
 
471
  lookup in a unique index.
 
472
 
 
473
  This engine is used to resolve subqueries in forms
 
474
  
 
475
    outer_expr IN (SELECT tbl.unique_key FROM tbl WHERE subq_where) 
 
476
    
 
477
  or, tuple-based:
 
478
  
 
479
    (oe1, .. oeN) IN (SELECT uniq_key_part1, ... uniq_key_partK
 
480
                      FROM tbl WHERE subqwhere) 
 
481
  
 
482
  i.e. the subquery is a single table SELECT without GROUP BY, aggregate
 
483
  functions, etc.
 
484
*/
 
485
 
 
486
class subselect_uniquesubquery_engine: public subselect_engine
 
487
{
 
488
protected:
 
489
  st_join_table *tab;
 
490
  Item *cond; /* The WHERE condition of subselect */
 
491
  /* 
 
492
    TRUE<=> last execution produced empty set. Valid only when left
 
493
    expression is NULL.
 
494
  */
 
495
  bool empty_result_set;
 
496
  bool null_keypart; /* TRUE <=> constructed search tuple has a NULL */
 
497
public:
 
498
 
 
499
  // constructor can assign THD because it will be called after JOIN::prepare
 
500
  subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
 
501
                                  Item_subselect *subs, Item *where)
 
502
    :subselect_engine(subs, 0), tab(tab_arg), cond(where)
 
503
  {
 
504
    set_thd(thd_arg);
 
505
  }
 
506
  ~subselect_uniquesubquery_engine();
 
507
  void cleanup();
 
508
  int prepare();
 
509
  void fix_length_and_dec(Item_cache** row);
 
510
  int exec();
 
511
  uint cols() { return 1; }
 
512
  uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
 
513
  void exclude();
 
514
  table_map upper_select_const_tables() { return 0; }
 
515
  virtual void print (String *str, enum_query_type query_type);
 
516
  bool change_result(Item_subselect *si, select_subselect *result);
 
517
  bool no_tables();
 
518
  int scan_table();
 
519
  bool copy_ref_key();
 
520
  bool no_rows() { return empty_result_set; }
 
521
};
 
522
 
 
523
 
 
524
class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
 
525
{
 
526
  /* FALSE for 'ref', TRUE for 'ref-or-null'. */
 
527
  bool check_null;
 
528
  /* 
 
529
    The "having" clause. This clause (further reffered to as "artificial
 
530
    having") was inserted by subquery transformation code. It contains 
 
531
    Item(s) that have a side-effect: they record whether the subquery has 
 
532
    produced a row with NULL certain components. We need to use it for cases
 
533
    like
 
534
      (oe1, oe2) IN (SELECT t.key, t.no_key FROM t1)
 
535
    where we do index lookup on t.key=oe1 but need also to check if there
 
536
    was a row such that t.no_key IS NULL.
 
537
    
 
538
    NOTE: This is currently here and not in the uniquesubquery_engine. Ideally
 
539
    it should have been in uniquesubquery_engine in order to allow execution of
 
540
    subqueries like
 
541
    
 
542
      (oe1, oe2) IN (SELECT primary_key, non_key_maybe_null_field FROM tbl)
 
543
 
 
544
    We could use uniquesubquery_engine for the first component and let
 
545
    Item_is_not_null_test( non_key_maybe_null_field) to handle the second.
 
546
 
 
547
    However, subqueries like the above are currently not handled by index
 
548
    lookup-based subquery engines, the engine applicability check misses
 
549
    them: it doesn't switch the engine for case of artificial having and
 
550
    [eq_]ref access (only for artifical having + ref_or_null or no having).
 
551
    The above example subquery is handled as a full-blown SELECT with eq_ref
 
552
    access to one table.
 
553
 
 
554
    Due to this limitation, the "artificial having" currently needs to be 
 
555
    checked by only in indexsubquery_engine.
 
556
  */
 
557
  Item *having;
 
558
public:
 
559
 
 
560
  // constructor can assign THD because it will be called after JOIN::prepare
 
561
  subselect_indexsubquery_engine(THD *thd_arg, st_join_table *tab_arg,
 
562
                                 Item_subselect *subs, Item *where,
 
563
                                 Item *having_arg, bool chk_null)
 
564
    :subselect_uniquesubquery_engine(thd_arg, tab_arg, subs, where),
 
565
     check_null(chk_null),
 
566
     having(having_arg)
 
567
  {}
 
568
  int exec();
 
569
  virtual void print (String *str, enum_query_type query_type);
 
570
};
 
571
 
 
572
 
 
573
inline bool Item_subselect::is_evaluated() const
 
574
{
 
575
  return engine->is_executed();
 
576
}
 
577
 
 
578
inline bool Item_subselect::is_uncacheable() const
 
579
{
 
580
  return engine->uncacheable();
 
581
}
 
582
 
 
583