~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.h

  • Committer: Brian Aker
  • Date: 2010-02-07 01:33:54 UTC
  • Revision ID: brian@gaz-20100207013354-d2pg1n68u5c09pgo
Remove giant include header to its own file.

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 */
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#ifndef DRIZZLED_ITEM_SUBSELECT_H
 
21
#define DRIZZLED_ITEM_SUBSELECT_H
15
22
 
16
23
/* subselect Item */
17
24
 
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;
 
25
 
 
26
#include "drizzled/comp_creator.h"
 
27
#include "drizzled/item/ref.h"
 
28
#include "drizzled/item/field.h"
 
29
#include "drizzled/item/bin_string.h"
 
30
 
 
31
namespace drizzled
 
32
{
 
33
 
 
34
class Select_Lex;
 
35
class Select_Lex_Unit;
24
36
class JOIN;
25
37
class select_result_interceptor;
26
38
class subselect_engine;
27
39
class subselect_hash_sj_engine;
28
40
class Item_bool_func2;
29
41
class Cached_item;
 
42
class Item_in_optimizer;
 
43
class Item_func_not_all;
 
44
class Tmp_Table_Param;
 
45
 
30
46
 
31
47
/* base class for subselects */
32
48
 
35
51
  bool value_assigned; /* value already assigned to subselect */
36
52
public:
37
53
  /* thread handler, will be assigned in fix_fields only */
38
 
  THD *thd;
 
54
  Session *session;
39
55
  /* substitution instead of subselect in case of optimization */
40
56
  Item *substitution;
41
57
  /* unit of subquery */
42
 
public:
43
 
  st_select_lex_unit *unit;
 
58
  Select_Lex_Unit *unit;
44
59
protected:
45
60
  /* engine that perform execution of subselect (single select or union) */
46
61
  subselect_engine *engine;
49
64
  /* cache of used external tables */
50
65
  table_map used_tables_cache;
51
66
  /* allowed number of columns (1 for single value subqueries) */
52
 
  uint max_columns;
 
67
  uint32_t max_columns;
53
68
  /* where subquery is placed */
54
69
  enum_parsing_place parsing_place;
55
70
  /* work with 'substitution' */
64
79
  bool changed;
65
80
 
66
81
  /* TRUE <=> The underlying SELECT is correlated w.r.t some ancestor select */
67
 
  bool is_correlated; 
 
82
  bool is_correlated;
68
83
 
69
84
  enum trans_res {RES_OK, RES_REDUCE, RES_ERROR};
70
85
  enum subs_type {UNKNOWN_SUBS, SINGLEROW_SUBS,
79
94
    pointer in constructor initialization list, but we need to pass a pointer
80
95
    to subselect Item class to select_result_interceptor's constructor.
81
96
  */
82
 
  virtual void init (st_select_lex *select_lex,
 
97
  virtual void init (Select_Lex *select_lex,
83
98
                     select_result_interceptor *result);
84
99
 
85
100
  ~Item_subselect();
97
112
    update_null_value();
98
113
    return null_value;
99
114
  }
100
 
  bool fix_fields(THD *thd, Item **ref);
 
115
  bool fix_fields(Session *session, Item **ref);
101
116
  virtual bool exec();
102
117
  virtual void fix_length_and_dec();
103
118
  table_map used_tables() const;
105
120
  bool const_item() const;
106
121
  inline table_map get_used_tables_cache() { return used_tables_cache; }
107
122
  inline bool get_const_item_cache() { return const_item_cache; }
108
 
  Item *get_tmp_table_item(THD *thd);
 
123
  Item *get_tmp_table_item(Session *session);
109
124
  void update_used_tables();
110
125
  virtual void print(String *str, enum_query_type query_type);
111
126
  virtual bool have_guarded_conds() { return false; }
129
144
  */
130
145
  virtual void reset_value_registration() {}
131
146
  enum_parsing_place place() { return parsing_place; }
132
 
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
 
147
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
133
148
 
134
149
  /**
135
 
    Get the SELECT_LEX structure associated with this Item.
136
 
    @return the SELECT_LEX structure associated with this Item
 
150
    Get the Select_Lex structure associated with this Item.
 
151
    @return the Select_Lex structure associated with this Item
137
152
  */
138
 
  st_select_lex* get_select_lex();
 
153
  Select_Lex* get_select_lex();
139
154
 
140
155
  friend class select_result_interceptor;
141
156
  friend class Item_in_optimizer;
142
 
  friend bool Item_field::fix_fields(THD *, Item **);
143
 
  friend int  Item_field::fix_outer_field(THD *, Field **, Item **);
144
 
  friend bool Item_ref::fix_fields(THD *, Item **);
145
 
  friend void mark_select_range_as_dependent(THD*,
146
 
                                             st_select_lex*, st_select_lex*,
 
157
  friend bool Item_field::fix_fields(Session *, Item **);
 
158
  friend int  Item_field::fix_outer_field(Session *, Field **, Item **);
 
159
  friend bool Item_ref::fix_fields(Session *, Item **);
 
160
  friend void mark_select_range_as_dependent(Session*,
 
161
                                             Select_Lex*, Select_Lex*,
147
162
                                             Field*, Item*, Item_ident*);
148
163
};
149
164
 
155
170
protected:
156
171
  Item_cache *value, **row;
157
172
public:
158
 
  Item_singlerow_subselect(st_select_lex *select_lex);
 
173
  Item_singlerow_subselect(Select_Lex *select_lex);
159
174
  Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {}
160
175
 
161
176
  void cleanup();
163
178
 
164
179
  void reset();
165
180
  trans_res select_transformer(JOIN *join);
166
 
  void store(uint i, Item* item);
 
181
  void store(uint32_t i, Item* item);
167
182
  double val_real();
168
183
  int64_t val_int ();
169
184
  String *val_str (String *);
173
188
  enum_field_types field_type() const;
174
189
  void fix_length_and_dec();
175
190
 
176
 
  uint cols();
177
 
  Item* element_index(uint i) { return my_reinterpret_cast(Item*)(row[i]); }
178
 
  Item** addr(uint i) { return (Item**)row + i; }
179
 
  bool check_cols(uint c);
 
191
  uint32_t cols();
 
192
  Item* element_index(uint32_t i) { return reinterpret_cast<Item*>(row[i]); }
 
193
  Item** addr(uint32_t i) { return (Item**)row + i; }
 
194
  bool check_cols(uint32_t c);
180
195
  bool null_inside();
181
196
  void bring_value();
182
197
 
186
201
    The only caller of this method is handle_sql2003_note184_exception(),
187
202
    see the code there for more details.
188
203
    Note that this method breaks the object internal integrity, by
189
 
    removing it's association with the corresponding SELECT_LEX,
 
204
    removing it's association with the corresponding Select_Lex,
190
205
    making this object orphan from the parse tree.
191
206
    No other method, beside the destructor, should be called on this
192
207
    object, as it is now invalid.
193
 
    @return the SELECT_LEX structure that was given in the constructor.
 
208
    @return the Select_Lex structure that was given in the constructor.
194
209
  */
195
 
  st_select_lex* invalidate_and_restore_select_lex();
 
210
  Select_Lex* invalidate_and_restore_select_lex();
196
211
 
197
212
  friend class select_singlerow_subselect;
198
213
};
205
220
  bool max;
206
221
  bool was_values;  // Set if we have found at least one row
207
222
public:
208
 
  Item_maxmin_subselect(THD *thd, Item_subselect *parent,
209
 
                        st_select_lex *select_lex, bool max);
 
223
  Item_maxmin_subselect(Session *session, Item_subselect *parent,
 
224
                        Select_Lex *select_lex, bool max);
210
225
  virtual void print(String *str, enum_query_type query_type);
211
226
  void cleanup();
212
227
  bool any_value() { return was_values; }
222
237
  bool value; /* value of this item (boolean: exists/not-exists) */
223
238
 
224
239
public:
225
 
  Item_exists_subselect(st_select_lex *select_lex);
 
240
  Item_exists_subselect(Select_Lex *select_lex);
226
241
  Item_exists_subselect(): Item_subselect() {}
227
242
 
228
243
  subs_type substype() { return EXISTS_SUBS; }
229
 
  void reset() 
 
244
  void reset()
230
245
  {
231
246
    value= 0;
232
247
  }
251
266
  "left_expr IN (SELECT ...)".
252
267
 
253
268
  @detail
254
 
  This class has: 
 
269
  This class has:
255
270
   - A "subquery execution engine" (as a subclass of Item_subselect) that allows
256
271
     it to evaluate subqueries. (and this class participates in execution by
257
272
     having was_null variable where part of execution result is stored.
285
300
public:
286
301
  /* Used to trigger on/off conditions that were pushed down to subselect */
287
302
  bool *pushed_cond_guards;
288
 
  
 
303
 
289
304
  /* Priority of this predicate in the convert-to-semi-join-nest process. */
290
305
  int sj_convert_priority;
291
306
 
292
 
  /* 
 
307
  /*
293
308
    Location of the subquery predicate. It is either
294
309
     - pointer to join nest if the subquery predicate is in the ON expression
295
 
     - (TABLE_LIST*)1 if the predicate is in the WHERE.
 
310
     - (TableList*)1 if the predicate is in the WHERE.
296
311
  */
297
 
  TABLE_LIST *expr_join_nest;
 
312
  TableList *expr_join_nest;
298
313
 
299
314
  /* The method chosen to execute the IN predicate.  */
300
315
  enum enum_exec_method {
309
324
  {
310
325
    return pushed_cond_guards ? pushed_cond_guards + i : NULL;
311
326
  }
312
 
  void set_cond_guard_var(int i, bool v) 
313
 
  { 
 
327
  void set_cond_guard_var(int i, bool v)
 
328
  {
314
329
    if ( pushed_cond_guards)
315
330
      pushed_cond_guards[i]= v;
316
331
  }
318
333
 
319
334
  Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery
320
335
 
321
 
  Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
 
336
  Item_in_subselect(Item * left_expr, Select_Lex *select_lex);
322
337
  Item_in_subselect()
323
 
    :Item_exists_subselect(), left_expr_cache(0), first_execution(true),
324
 
    optimizer(0), abort_on_null(0), pushed_cond_guards(NULL),
325
 
    exec_method(NOT_TRANSFORMED), upper_item(0)
 
338
    :
 
339
      Item_exists_subselect(),
 
340
      left_expr(NULL),
 
341
      left_expr_cache(NULL),
 
342
      first_execution(true),
 
343
      optimizer(NULL),
 
344
      abort_on_null(false),
 
345
      pushed_cond_guards(NULL),
 
346
      sj_convert_priority(0),
 
347
      expr_join_nest(NULL),
 
348
      exec_method(NOT_TRANSFORMED),
 
349
      upper_item(NULL)
326
350
  {}
327
351
  void cleanup();
328
352
  subs_type substype() { return IN_SUBS; }
329
 
  void reset() 
 
353
  void reset()
330
354
  {
331
355
    value= 0;
332
356
    null_value= 0;
333
357
    was_null= 0;
334
358
  }
335
359
  trans_res select_transformer(JOIN *join);
336
 
  trans_res select_in_like_transformer(JOIN *join, Comp_creator *func);
337
 
  trans_res single_value_transformer(JOIN *join, Comp_creator *func);
 
360
  trans_res select_in_like_transformer(JOIN *join, const Comp_creator *func);
 
361
  trans_res single_value_transformer(JOIN *join, const Comp_creator *func);
338
362
  trans_res row_value_transformer(JOIN * join);
339
363
  trans_res single_value_in_to_exists_transformer(JOIN * join,
340
 
                                                  Comp_creator *func);
 
364
                                                  const Comp_creator *func);
341
365
  trans_res row_value_in_to_exists_transformer(JOIN * join);
342
366
  virtual bool exec();
343
367
  int64_t val_int();
348
372
  bool val_bool();
349
373
  void top_level_item() { abort_on_null=1; }
350
374
  inline bool is_top_level_item() { return abort_on_null; }
351
 
  bool test_limit(st_select_lex_unit *unit);
 
375
  bool test_limit(Select_Lex_Unit *unit);
352
376
  virtual void print(String *str, enum_query_type query_type);
353
 
  bool fix_fields(THD *thd, Item **ref);
 
377
  bool fix_fields(Session *session, Item **ref);
354
378
  bool setup_engine();
355
379
  bool init_left_expr_cache();
356
 
  bool is_expensive_processor(uchar *arg);
 
380
  bool is_expensive_processor(unsigned char *arg);
357
381
 
358
382
  friend class Item_ref_null_helper;
359
383
  friend class Item_is_not_null_test;
372
396
  bool all;
373
397
 
374
398
  Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
375
 
                        st_select_lex *select_lex, bool all);
 
399
                        Select_Lex *select_lex, bool all);
376
400
 
377
401
  // only ALL subquery has upper not
378
402
  subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
381
405
};
382
406
 
383
407
 
384
 
class subselect_engine: public Sql_alloc
 
408
class subselect_engine: public memory::SqlAlloc
385
409
{
386
410
protected:
387
411
  select_result_interceptor *result; /* results storage class */
388
 
  THD *thd; /* pointer to current THD */
 
412
  Session *session; /* pointer to current Session */
389
413
  Item_subselect *item; /* item, that use this engine */
390
414
  enum Item_result res_type; /* type of results */
391
415
  enum_field_types res_field_type; /* column type of the results */
397
421
                         INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE};
398
422
 
399
423
  subselect_engine(Item_subselect *si, select_result_interceptor *res)
400
 
    :thd(0)
 
424
    :session(NULL)
401
425
  {
402
426
    result= res;
403
427
    item= si;
409
433
  virtual void cleanup()= 0;
410
434
 
411
435
  /*
412
 
    Also sets "thd" for subselect_engine::result.
 
436
    Also sets "session" for subselect_engine::result.
413
437
    Should be called before prepare().
414
438
  */
415
 
  void set_thd(THD *thd_arg);
416
 
  THD * get_thd() { return thd; }
 
439
  void set_session(Session *session_arg);
 
440
  Session * get_session() { return session; }
417
441
  virtual int prepare()= 0;
418
442
  virtual void fix_length_and_dec(Item_cache** row)= 0;
419
443
  /*
428
452
      stored somewhere by the exec() method itself.
429
453
 
430
454
      A required side effect: If at least one pushed-down predicate is
431
 
      disabled, subselect_engine->no_rows() must return correct result after 
 
455
      disabled, subselect_engine->no_rows() must return correct result after
432
456
      the exec() call.
433
457
 
434
458
    RETURN
437
461
          caller should call exec() again for the new engine.
438
462
  */
439
463
  virtual int exec()= 0;
440
 
  virtual uint cols()= 0; /* return number of columns in select */
 
464
  virtual uint32_t cols()= 0; /* return number of columns in select */
441
465
  virtual uint8_t uncacheable()= 0; /* query is uncacheable */
442
466
  enum Item_result type() { return res_type; }
443
467
  enum_field_types field_type() { return res_field_type; }
444
468
  virtual void exclude()= 0;
445
469
  virtual bool may_be_null() { return maybe_null; };
446
470
  virtual table_map upper_select_const_tables()= 0;
447
 
  static table_map calc_const_tables(TABLE_LIST *);
 
471
  static table_map calc_const_tables(TableList *);
448
472
  virtual void print(String *str, enum_query_type query_type)= 0;
449
473
  virtual bool change_result(Item_subselect *si,
450
474
                             select_result_interceptor *result)= 0;
464
488
  bool prepared; /* simple subselect is prepared */
465
489
  bool optimized; /* simple subselect is optimized */
466
490
  bool executed; /* simple subselect is executed */
467
 
  st_select_lex *select_lex; /* corresponding select_lex */
 
491
  Select_Lex *select_lex; /* corresponding select_lex */
468
492
  JOIN * join; /* corresponding JOIN structure */
469
493
public:
470
 
  subselect_single_select_engine(st_select_lex *select,
 
494
  subselect_single_select_engine(Select_Lex *select,
471
495
                                 select_result_interceptor *result,
472
496
                                 Item_subselect *item);
473
497
  void cleanup();
474
498
  int prepare();
475
499
  void fix_length_and_dec(Item_cache** row);
476
500
  int exec();
477
 
  uint cols();
 
501
  uint32_t cols();
478
502
  uint8_t uncacheable();
479
503
  void exclude();
480
504
  table_map upper_select_const_tables();
493
517
 
494
518
class subselect_union_engine: public subselect_engine
495
519
{
496
 
  st_select_lex_unit *unit;  /* corresponding unit structure */
 
520
  Select_Lex_Unit *unit;  /* corresponding unit structure */
497
521
public:
498
 
  subselect_union_engine(st_select_lex_unit *u,
 
522
  subselect_union_engine(Select_Lex_Unit *u,
499
523
                         select_result_interceptor *result,
500
524
                         Item_subselect *item);
501
525
  void cleanup();
502
526
  int prepare();
503
527
  void fix_length_and_dec(Item_cache** row);
504
528
  int exec();
505
 
  uint cols();
 
529
  uint32_t cols();
506
530
  uint8_t uncacheable();
507
531
  void exclude();
508
532
  table_map upper_select_const_tables();
515
539
};
516
540
 
517
541
 
518
 
struct st_join_table;
 
542
class JoinTable;
519
543
 
520
544
 
521
545
/*
523
547
  lookup in a unique index.
524
548
 
525
549
  This engine is used to resolve subqueries in forms
526
 
  
527
 
    outer_expr IN (SELECT tbl.unique_key FROM tbl WHERE subq_where) 
528
 
    
 
550
 
 
551
    outer_expr IN (SELECT tbl.unique_key FROM tbl WHERE subq_where)
 
552
 
529
553
  or, tuple-based:
530
 
  
 
554
 
531
555
    (oe1, .. oeN) IN (SELECT uniq_key_part1, ... uniq_key_partK
532
 
                      FROM tbl WHERE subqwhere) 
533
 
  
 
556
                      FROM tbl WHERE subqwhere)
 
557
 
534
558
  i.e. the subquery is a single table SELECT without GROUP BY, aggregate
535
559
  functions, etc.
536
560
*/
538
562
class subselect_uniquesubquery_engine: public subselect_engine
539
563
{
540
564
protected:
541
 
  st_join_table *tab;
 
565
  JoinTable *tab;
542
566
  Item *cond; /* The WHERE condition of subselect */
543
 
  /* 
 
567
  /*
544
568
    TRUE<=> last execution produced empty set. Valid only when left
545
569
    expression is NULL.
546
570
  */
548
572
  bool null_keypart; /* TRUE <=> constructed search tuple has a NULL */
549
573
public:
550
574
 
551
 
  // constructor can assign THD because it will be called after JOIN::prepare
552
 
  subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg,
 
575
  // constructor can assign Session because it will be called after JOIN::prepare
 
576
  subselect_uniquesubquery_engine(Session *session_arg, JoinTable *tab_arg,
553
577
                                  Item_subselect *subs, Item *where)
554
578
    :subselect_engine(subs, 0), tab(tab_arg), cond(where)
555
579
  {
556
 
    set_thd(thd_arg);
 
580
    set_session(session_arg);
557
581
  }
558
582
  void cleanup();
559
583
  int prepare();
560
584
  void fix_length_and_dec(Item_cache** row);
561
585
  int exec();
562
 
  uint cols() { return 1; }
 
586
  uint32_t cols() { return 1; }
563
587
  uint8_t uncacheable() { return UNCACHEABLE_DEPENDENT; }
564
588
  void exclude();
565
589
  table_map upper_select_const_tables() { return 0; }
577
601
{
578
602
  /* FALSE for 'ref', TRUE for 'ref-or-null'. */
579
603
  bool check_null;
580
 
  /* 
 
604
  /*
581
605
    The "having" clause. This clause (further reffered to as "artificial
582
 
    having") was inserted by subquery transformation code. It contains 
583
 
    Item(s) that have a side-effect: they record whether the subquery has 
 
606
    having") was inserted by subquery transformation code. It contains
 
607
    Item(s) that have a side-effect: they record whether the subquery has
584
608
    produced a row with NULL certain components. We need to use it for cases
585
609
    like
586
610
      (oe1, oe2) IN (SELECT t.key, t.no_key FROM t1)
587
611
    where we do index lookup on t.key=oe1 but need also to check if there
588
612
    was a row such that t.no_key IS NULL.
589
 
    
 
613
 
590
614
    NOTE: This is currently here and not in the uniquesubquery_engine. Ideally
591
615
    it should have been in uniquesubquery_engine in order to allow execution of
592
616
    subqueries like
593
 
    
 
617
 
594
618
      (oe1, oe2) IN (SELECT primary_key, non_key_maybe_null_field FROM tbl)
595
619
 
596
620
    We could use uniquesubquery_engine for the first component and let
603
627
    The above example subquery is handled as a full-blown SELECT with eq_ref
604
628
    access to one table.
605
629
 
606
 
    Due to this limitation, the "artificial having" currently needs to be 
 
630
    Due to this limitation, the "artificial having" currently needs to be
607
631
    checked by only in indexsubquery_engine.
608
632
  */
609
633
  Item *having;
610
634
public:
611
635
 
612
 
  // constructor can assign THD because it will be called after JOIN::prepare
613
 
  subselect_indexsubquery_engine(THD *thd_arg, st_join_table *tab_arg,
 
636
  // constructor can assign Session because it will be called after JOIN::prepare
 
637
  subselect_indexsubquery_engine(Session *session_arg, JoinTable *tab_arg,
614
638
                                 Item_subselect *subs, Item *where,
615
639
                                 Item *having_arg, bool chk_null)
616
 
    :subselect_uniquesubquery_engine(thd_arg, tab_arg, subs, where),
 
640
    :subselect_uniquesubquery_engine(session_arg, tab_arg, subs, where),
617
641
     check_null(chk_null),
618
642
     having(having_arg)
619
643
  {}
659
683
  */
660
684
  JOIN *materialize_join;
661
685
  /* Temp table context of the outer select's JOIN. */
662
 
  TMP_TABLE_PARAM *tmp_param;
 
686
  Tmp_Table_Param *tmp_param;
663
687
 
664
688
public:
665
 
  subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
 
689
  subselect_hash_sj_engine(Session *session_in, Item_subselect *in_predicate,
666
690
                               subselect_single_select_engine *old_engine)
667
 
    :subselect_uniquesubquery_engine(thd, NULL, in_predicate, NULL),
 
691
    :subselect_uniquesubquery_engine(session_in, NULL, in_predicate, NULL),
668
692
    is_materialized(false), materialize_engine(old_engine),
669
693
    materialize_join(NULL), tmp_param(NULL)
670
694
  {}
676
700
  int prepare() { return 0; }
677
701
  int exec();
678
702
  virtual void print (String *str, enum_query_type query_type);
679
 
  uint cols()
 
703
  uint32_t cols()
680
704
  {
681
705
    return materialize_engine->cols();
682
706
  }
683
707
  virtual enum_engine_type engine_type() { return HASH_SJ_ENGINE; }
684
708
};
 
709
 
 
710
} /* namespace drizzled */
 
711
 
 
712
#endif /* DRIZZLED_ITEM_SUBSELECT_H */