~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_subselect.cc

Removed/replaced DBUG

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
 
/**
17
 
  @file
18
 
 
19
 
  @brief
20
 
  subselect Item
21
 
 
22
 
  @todo
23
 
    - add function from mysql_select that use JOIN* as parameter to JOIN
24
 
    methods (sql_select.h/sql_select.cc)
25
 
*/
26
 
 
27
 
#ifdef USE_PRAGMA_IMPLEMENTATION
28
 
#pragma implementation                          // gcc: Class implementation
29
 
#endif
30
 
 
31
 
#include "mysql_priv.h"
32
 
#include "sql_select.h"
33
 
 
34
 
inline Item * and_items(Item* cond, Item *item)
35
 
{
36
 
  return (cond? (new Item_cond_and(cond, item)) : item);
37
 
}
38
 
 
39
 
Item_subselect::Item_subselect():
40
 
  Item_result_field(), value_assigned(0), thd(0), substitution(0),
41
 
  engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
42
 
  const_item_cache(1), engine_changed(0), changed(0),
43
 
  is_correlated(false)
44
 
{
45
 
  with_subselect= 1;
46
 
  reset();
47
 
  /*
48
 
    Item value is NULL if select_result_interceptor didn't change this value
49
 
    (i.e. some rows will be found returned)
50
 
  */
51
 
  null_value= 1;
52
 
}
53
 
 
54
 
 
55
 
void Item_subselect::init(st_select_lex *select_lex,
56
 
                          select_result_interceptor *result)
57
 
{
58
 
  /*
59
 
    Please see Item_singlerow_subselect::invalidate_and_restore_select_lex(),
60
 
    which depends on alterations to the parse tree implemented here.
61
 
  */
62
 
 
63
 
  unit= select_lex->master_unit();
64
 
 
65
 
  if (unit->item)
66
 
  {
67
 
    /*
68
 
      Item can be changed in JOIN::prepare while engine in JOIN::optimize
69
 
      => we do not copy old_engine here
70
 
    */
71
 
    engine= unit->item->engine;
72
 
    parsing_place= unit->item->parsing_place;
73
 
    unit->item->engine= 0;
74
 
    unit->item= this;
75
 
    engine->change_result(this, result);
76
 
  }
77
 
  else
78
 
  {
79
 
    SELECT_LEX *outer_select= unit->outer_select();
80
 
    /*
81
 
      do not take into account expression inside aggregate functions because
82
 
      they can access original table fields
83
 
    */
84
 
    parsing_place= (outer_select->in_sum_expr ?
85
 
                    NO_MATTER :
86
 
                    outer_select->parsing_place);
87
 
    if (unit->is_union())
88
 
      engine= new subselect_union_engine(unit, result, this);
89
 
    else
90
 
      engine= new subselect_single_select_engine(select_lex, result, this);
91
 
  }
92
 
  {
93
 
    SELECT_LEX *upper= unit->outer_select();
94
 
    if (upper->parsing_place == IN_HAVING)
95
 
      upper->subquery_in_having= 1;
96
 
  }
97
 
  return;
98
 
}
99
 
 
100
 
st_select_lex *
101
 
Item_subselect::get_select_lex()
102
 
{
103
 
  return unit->first_select();
104
 
}
105
 
 
106
 
void Item_subselect::cleanup()
107
 
{
108
 
  Item_result_field::cleanup();
109
 
  if (old_engine)
110
 
  {
111
 
    if (engine)
112
 
      engine->cleanup();
113
 
    engine= old_engine;
114
 
    old_engine= 0;
115
 
  }
116
 
  if (engine)
117
 
    engine->cleanup();
118
 
  reset();
119
 
  value_assigned= 0;
120
 
  return;
121
 
}
122
 
 
123
 
void Item_singlerow_subselect::cleanup()
124
 
{
125
 
  value= 0; row= 0;
126
 
  Item_subselect::cleanup();
127
 
  return;
128
 
}
129
 
 
130
 
 
131
 
void Item_in_subselect::cleanup()
132
 
{
133
 
  if (left_expr_cache)
134
 
  {
135
 
    left_expr_cache->delete_elements();
136
 
    delete left_expr_cache;
137
 
    left_expr_cache= NULL;
138
 
  }
139
 
  first_execution= true;
140
 
  Item_subselect::cleanup();
141
 
  return;
142
 
}
143
 
 
144
 
Item_subselect::~Item_subselect()
145
 
{
146
 
  delete engine;
147
 
}
148
 
 
149
 
Item_subselect::trans_res
150
 
Item_subselect::select_transformer(JOIN *join __attribute__((__unused__)))
151
 
{
152
 
  return(RES_OK);
153
 
}
154
 
 
155
 
 
156
 
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
157
 
{
158
 
  char const *save_where= thd_param->where;
159
 
  uint8 uncacheable;
160
 
  bool res;
161
 
 
162
 
  assert(fixed == 0);
163
 
  engine->set_thd((thd= thd_param));
164
 
 
165
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
166
 
    return true;
167
 
 
168
 
  res= engine->prepare();
169
 
 
170
 
  // all transformation is done (used by prepared statements)
171
 
  changed= 1;
172
 
 
173
 
  if (!res)
174
 
  {
175
 
    /*
176
 
      Substitute the current item with an Item_in_optimizer that was
177
 
      created by Item_in_subselect::select_in_like_transformer and
178
 
      call fix_fields for the substituted item which in turn calls
179
 
      engine->prepare for the subquery predicate.
180
 
    */
181
 
    if (substitution)
182
 
    {
183
 
      int ret= 0;
184
 
 
185
 
      // did we changed top item of WHERE condition
186
 
      if (unit->outer_select()->where == (*ref))
187
 
        unit->outer_select()->where= substitution; // correct WHERE for PS
188
 
      else if (unit->outer_select()->having == (*ref))
189
 
        unit->outer_select()->having= substitution; // correct HAVING for PS
190
 
 
191
 
      (*ref)= substitution;
192
 
      substitution->name= name;
193
 
      if (have_to_be_excluded)
194
 
        engine->exclude();
195
 
      substitution= 0;
196
 
      thd->where= "checking transformed subquery";
197
 
      if (!(*ref)->fixed)
198
 
        ret= (*ref)->fix_fields(thd, ref);
199
 
      thd->where= save_where;
200
 
      return ret;
201
 
    }
202
 
    // Is it one field subselect?
203
 
    if (engine->cols() > max_columns)
204
 
    {
205
 
      my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
206
 
      return true;
207
 
    }
208
 
    fix_length_and_dec();
209
 
  }
210
 
  else
211
 
    goto err;
212
 
  
213
 
  if ((uncacheable= engine->uncacheable()))
214
 
  {
215
 
    const_item_cache= 0;
216
 
    if (uncacheable & UNCACHEABLE_RAND)
217
 
      used_tables_cache|= RAND_TABLE_BIT;
218
 
  }
219
 
  fixed= 1;
220
 
 
221
 
err:
222
 
  thd->where= save_where;
223
 
  return res;
224
 
}
225
 
 
226
 
 
227
 
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
228
 
                          uchar *argument)
229
 
{
230
 
 
231
 
  if (walk_subquery)
232
 
  {
233
 
    for (SELECT_LEX *lex= unit->first_select(); lex; lex= lex->next_select())
234
 
    {
235
 
      List_iterator<Item> li(lex->item_list);
236
 
      Item *item;
237
 
      ORDER *order;
238
 
 
239
 
      if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
240
 
        return 1;
241
 
      if (lex->having && (lex->having)->walk(processor, walk_subquery,
242
 
                                             argument))
243
 
        return 1;
244
 
 
245
 
      while ((item=li++))
246
 
      {
247
 
        if (item->walk(processor, walk_subquery, argument))
248
 
          return 1;
249
 
      }
250
 
      for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
251
 
      {
252
 
        if ((*order->item)->walk(processor, walk_subquery, argument))
253
 
          return 1;
254
 
      }
255
 
      for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
256
 
      {
257
 
        if ((*order->item)->walk(processor, walk_subquery, argument))
258
 
          return 1;
259
 
      }
260
 
    }
261
 
  }
262
 
  return (this->*processor)(argument);
263
 
}
264
 
 
265
 
 
266
 
bool Item_subselect::exec()
267
 
{
268
 
  int res;
269
 
 
270
 
  if (thd->is_error())
271
 
  /* Do not execute subselect in case of a fatal error */
272
 
    return 1;
273
 
 
274
 
  res= engine->exec();
275
 
 
276
 
  if (engine_changed)
277
 
  {
278
 
    engine_changed= 0;
279
 
    return exec();
280
 
  }
281
 
  return (res);
282
 
}
283
 
 
284
 
 
285
 
/*
286
 
  Compute the IN predicate if the left operand's cache changed.
287
 
*/
288
 
 
289
 
bool Item_in_subselect::exec()
290
 
{
291
 
  assert(exec_method != MATERIALIZATION ||
292
 
              (exec_method == MATERIALIZATION &&
293
 
               engine->engine_type() == subselect_engine::HASH_SJ_ENGINE));
294
 
  /*
295
 
    Initialize the cache of the left predicate operand. This has to be done as
296
 
    late as now, because Cached_item directly contains a resolved field (not
297
 
    an item, and in some cases (when temp tables are created), these fields
298
 
    end up pointing to the wrong field. One solution is to change Cached_item
299
 
    to not resolve its field upon creation, but to resolve it dynamically
300
 
    from a given Item_ref object.
301
 
    TODO: the cache should be applied conditionally based on:
302
 
    - rules - e.g. only if the left operand is known to be ordered, and/or
303
 
    - on a cost-based basis, that takes into account the cost of a cache
304
 
      lookup, the cache hit rate, and the savings per cache hit.
305
 
  */
306
 
  if (!left_expr_cache && exec_method == MATERIALIZATION)
307
 
    init_left_expr_cache();
308
 
 
309
 
  /* If the new left operand is already in the cache, reuse the old result. */
310
 
  if (left_expr_cache && test_if_item_cache_changed(*left_expr_cache) < 0)
311
 
  {
312
 
    /* Always compute IN for the first row as the cache is not valid for it. */
313
 
    if (!first_execution)
314
 
      return(false);
315
 
    first_execution= false;
316
 
  }
317
 
 
318
 
  /*
319
 
    The exec() method below updates item::value, and item::null_value, thus if
320
 
    we don't call it, the next call to item::val_int() will return whatever
321
 
    result was computed by its previous call.
322
 
  */
323
 
  return(Item_subselect::exec());
324
 
}
325
 
 
326
 
 
327
 
Item::Type Item_subselect::type() const
328
 
{
329
 
  return SUBSELECT_ITEM;
330
 
}
331
 
 
332
 
 
333
 
void Item_subselect::fix_length_and_dec()
334
 
{
335
 
  engine->fix_length_and_dec(0);
336
 
}
337
 
 
338
 
 
339
 
table_map Item_subselect::used_tables() const
340
 
{
341
 
  return (table_map) (engine->uncacheable() ? used_tables_cache : 0L);
342
 
}
343
 
 
344
 
 
345
 
bool Item_subselect::const_item() const
346
 
{
347
 
  return const_item_cache;
348
 
}
349
 
 
350
 
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
351
 
{
352
 
  if (!with_sum_func && !const_item())
353
 
    return new Item_field(result_field);
354
 
  return copy_or_same(thd_arg);
355
 
}
356
 
 
357
 
void Item_subselect::update_used_tables()
358
 
{
359
 
  if (!engine->uncacheable())
360
 
  {
361
 
    // did all used tables become static?
362
 
    if (!(used_tables_cache & ~engine->upper_select_const_tables()))
363
 
      const_item_cache= 1;
364
 
  }
365
 
}
366
 
 
367
 
 
368
 
void Item_subselect::print(String *str, enum_query_type query_type)
369
 
{
370
 
  str->append('(');
371
 
  engine->print(str, query_type);
372
 
  str->append(')');
373
 
}
374
 
 
375
 
 
376
 
Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
377
 
  :Item_subselect(), value(0)
378
 
{
379
 
  init(select_lex, new select_singlerow_subselect(this));
380
 
  maybe_null= 1;
381
 
  max_columns= UINT_MAX;
382
 
  return;
383
 
}
384
 
 
385
 
st_select_lex *
386
 
Item_singlerow_subselect::invalidate_and_restore_select_lex()
387
 
{
388
 
  st_select_lex *result= get_select_lex();
389
 
 
390
 
  assert(result);
391
 
 
392
 
  /*
393
 
    This code restore the parse tree in it's state before the execution of
394
 
    Item_singlerow_subselect::Item_singlerow_subselect(),
395
 
    and in particular decouples this object from the SELECT_LEX,
396
 
    so that the SELECT_LEX can be used with a different flavor
397
 
    or Item_subselect instead, as part of query rewriting.
398
 
  */
399
 
  unit->item= NULL;
400
 
 
401
 
  return(result);
402
 
}
403
 
 
404
 
Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
405
 
                                             Item_subselect *parent,
406
 
                                             st_select_lex *select_lex,
407
 
                                             bool max_arg)
408
 
  :Item_singlerow_subselect(), was_values(true)
409
 
{
410
 
  max= max_arg;
411
 
  init(select_lex, new select_max_min_finder_subselect(this, max_arg));
412
 
  max_columns= 1;
413
 
  maybe_null= 1;
414
 
  max_columns= 1;
415
 
 
416
 
  /*
417
 
    Following information was collected during performing fix_fields()
418
 
    of Items belonged to subquery, which will be not repeated
419
 
  */
420
 
  used_tables_cache= parent->get_used_tables_cache();
421
 
  const_item_cache= parent->get_const_item_cache();
422
 
 
423
 
  /*
424
 
    this subquery always creates during preparation, so we can assign
425
 
    thd here
426
 
  */
427
 
  thd= thd_param;
428
 
 
429
 
  return;
430
 
}
431
 
 
432
 
void Item_maxmin_subselect::cleanup()
433
 
{
434
 
  Item_singlerow_subselect::cleanup();
435
 
 
436
 
  /*
437
 
    By default it is true to avoid true reporting by
438
 
    Item_func_not_all/Item_func_nop_all if this item was never called.
439
 
 
440
 
    Engine exec() set it to false by reset_value_registration() call.
441
 
    select_max_min_finder_subselect::send_data() set it back to true if some
442
 
    value will be found.
443
 
  */
444
 
  was_values= true;
445
 
  return;
446
 
}
447
 
 
448
 
 
449
 
void Item_maxmin_subselect::print(String *str, enum_query_type query_type)
450
 
{
451
 
  str->append(max?"<max>":"<min>", 5);
452
 
  Item_singlerow_subselect::print(str, query_type);
453
 
}
454
 
 
455
 
 
456
 
void Item_singlerow_subselect::reset()
457
 
{
458
 
  null_value= 1;
459
 
  if (value)
460
 
    value->null_value= 1;
461
 
}
462
 
 
463
 
 
464
 
/**
465
 
  @todo
466
 
  - We cant change name of Item_field or Item_ref, because it will
467
 
  prevent it's correct resolving, but we should save name of
468
 
  removed item => we do not make optimization if top item of
469
 
  list is field or reference.
470
 
  - switch off this optimization for prepare statement,
471
 
  because we do not rollback this changes.
472
 
  Make rollback for it, or special name resolving mode in 5.0.
473
 
*/
474
 
Item_subselect::trans_res
475
 
Item_singlerow_subselect::select_transformer(JOIN *join)
476
 
{
477
 
  if (changed)
478
 
    return(RES_OK);
479
 
 
480
 
  SELECT_LEX *select_lex= join->select_lex;
481
 
 
482
 
  if (!select_lex->master_unit()->is_union() &&
483
 
      !select_lex->table_list.elements &&
484
 
      select_lex->item_list.elements == 1 &&
485
 
      !select_lex->item_list.head()->with_sum_func &&
486
 
      /*
487
 
        We cant change name of Item_field or Item_ref, because it will
488
 
        prevent it's correct resolving, but we should save name of
489
 
        removed item => we do not make optimization if top item of
490
 
        list is field or reference.
491
 
        TODO: solve above problem
492
 
      */
493
 
      !(select_lex->item_list.head()->type() == FIELD_ITEM ||
494
 
        select_lex->item_list.head()->type() == REF_ITEM) &&
495
 
      !join->conds && !join->having
496
 
      )
497
 
  {
498
 
 
499
 
    have_to_be_excluded= 1;
500
 
    if (thd->lex->describe)
501
 
    {
502
 
      char warn_buff[MYSQL_ERRMSG_SIZE];
503
 
      sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
504
 
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
505
 
                   ER_SELECT_REDUCED, warn_buff);
506
 
    }
507
 
    substitution= select_lex->item_list.head();
508
 
    /*
509
 
      as far as we moved content to upper level, field which depend of
510
 
      'upper' select is not really dependent => we remove this dependence
511
 
    */
512
 
    substitution->walk(&Item::remove_dependence_processor, 0,
513
 
                       (uchar *) select_lex->outer_select());
514
 
    return(RES_REDUCE);
515
 
  }
516
 
  return(RES_OK);
517
 
}
518
 
 
519
 
 
520
 
void Item_singlerow_subselect::store(uint i, Item *item)
521
 
{
522
 
  row[i]->store(item);
523
 
}
524
 
 
525
 
enum Item_result Item_singlerow_subselect::result_type() const
526
 
{
527
 
  return engine->type();
528
 
}
529
 
 
530
 
/* 
531
 
 Don't rely on the result type to calculate field type. 
532
 
 Ask the engine instead.
533
 
*/
534
 
enum_field_types Item_singlerow_subselect::field_type() const
535
 
{
536
 
  return engine->field_type();
537
 
}
538
 
 
539
 
void Item_singlerow_subselect::fix_length_and_dec()
540
 
{
541
 
  if ((max_columns= engine->cols()) == 1)
542
 
  {
543
 
    engine->fix_length_and_dec(row= &value);
544
 
  }
545
 
  else
546
 
  {
547
 
    if (!(row= (Item_cache**) sql_alloc(sizeof(Item_cache*)*max_columns)))
548
 
      return;
549
 
    engine->fix_length_and_dec(row);
550
 
    value= *row;
551
 
  }
552
 
  unsigned_flag= value->unsigned_flag;
553
 
  /*
554
 
    If there are not tables in subquery then ability to have NULL value
555
 
    depends on SELECT list (if single row subquery have tables then it
556
 
    always can be NULL if there are not records fetched).
557
 
  */
558
 
  if (engine->no_tables())
559
 
    maybe_null= engine->may_be_null();
560
 
}
561
 
 
562
 
uint Item_singlerow_subselect::cols()
563
 
{
564
 
  return engine->cols();
565
 
}
566
 
 
567
 
bool Item_singlerow_subselect::check_cols(uint c)
568
 
{
569
 
  if (c != engine->cols())
570
 
  {
571
 
    my_error(ER_OPERAND_COLUMNS, MYF(0), c);
572
 
    return 1;
573
 
  }
574
 
  return 0;
575
 
}
576
 
 
577
 
bool Item_singlerow_subselect::null_inside()
578
 
{
579
 
  for (uint i= 0; i < max_columns ; i++)
580
 
  {
581
 
    if (row[i]->null_value)
582
 
      return 1;
583
 
  }
584
 
  return 0;
585
 
}
586
 
 
587
 
void Item_singlerow_subselect::bring_value()
588
 
{
589
 
  exec();
590
 
}
591
 
 
592
 
double Item_singlerow_subselect::val_real()
593
 
{
594
 
  assert(fixed == 1);
595
 
  if (!exec() && !value->null_value)
596
 
  {
597
 
    null_value= 0;
598
 
    return value->val_real();
599
 
  }
600
 
  else
601
 
  {
602
 
    reset();
603
 
    return 0;
604
 
  }
605
 
}
606
 
 
607
 
int64_t Item_singlerow_subselect::val_int()
608
 
{
609
 
  assert(fixed == 1);
610
 
  if (!exec() && !value->null_value)
611
 
  {
612
 
    null_value= 0;
613
 
    return value->val_int();
614
 
  }
615
 
  else
616
 
  {
617
 
    reset();
618
 
    return 0;
619
 
  }
620
 
}
621
 
 
622
 
String *Item_singlerow_subselect::val_str(String *str)
623
 
{
624
 
  if (!exec() && !value->null_value)
625
 
  {
626
 
    null_value= 0;
627
 
    return value->val_str(str);
628
 
  }
629
 
  else
630
 
  {
631
 
    reset();
632
 
    return 0;
633
 
  }
634
 
}
635
 
 
636
 
 
637
 
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
638
 
{
639
 
  if (!exec() && !value->null_value)
640
 
  {
641
 
    null_value= 0;
642
 
    return value->val_decimal(decimal_value);
643
 
  }
644
 
  else
645
 
  {
646
 
    reset();
647
 
    return 0;
648
 
  }
649
 
}
650
 
 
651
 
 
652
 
bool Item_singlerow_subselect::val_bool()
653
 
{
654
 
  if (!exec() && !value->null_value)
655
 
  {
656
 
    null_value= 0;
657
 
    return value->val_bool();
658
 
  }
659
 
  else
660
 
  {
661
 
    reset();
662
 
    return 0;
663
 
  }
664
 
}
665
 
 
666
 
 
667
 
Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
668
 
  Item_subselect()
669
 
{
670
 
  bool val_bool();
671
 
  init(select_lex, new select_exists_subselect(this));
672
 
  max_columns= UINT_MAX;
673
 
  null_value= 0; //can't be NULL
674
 
  maybe_null= 0; //can't be NULL
675
 
  value= 0;
676
 
  return;
677
 
}
678
 
 
679
 
 
680
 
void Item_exists_subselect::print(String *str, enum_query_type query_type)
681
 
{
682
 
  str->append(STRING_WITH_LEN("exists"));
683
 
  Item_subselect::print(str, query_type);
684
 
}
685
 
 
686
 
 
687
 
bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
688
 
{
689
 
  if (unit_arg->fake_select_lex &&
690
 
      unit_arg->fake_select_lex->test_limit())
691
 
    return(1);
692
 
 
693
 
  SELECT_LEX *sl= unit_arg->first_select();
694
 
  for (; sl; sl= sl->next_select())
695
 
  {
696
 
    if (sl->test_limit())
697
 
      return(1);
698
 
  }
699
 
  return(0);
700
 
}
701
 
 
702
 
Item_in_subselect::Item_in_subselect(Item * left_exp,
703
 
                                     st_select_lex *select_lex):
704
 
  Item_exists_subselect(), left_expr_cache(0), first_execution(true),
705
 
  optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
706
 
  upper_item(0)
707
 
{
708
 
  left_expr= left_exp;
709
 
  init(select_lex, new select_exists_subselect(this));
710
 
  max_columns= UINT_MAX;
711
 
  maybe_null= 1;
712
 
  abort_on_null= 0;
713
 
  reset();
714
 
  //if test_limit will fail then error will be reported to client
715
 
  test_limit(select_lex->master_unit());
716
 
  return;
717
 
}
718
 
 
719
 
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
720
 
                                             chooser_compare_func_creator fc,
721
 
                                             st_select_lex *select_lex,
722
 
                                             bool all_arg)
723
 
  :Item_in_subselect(), func_creator(fc), all(all_arg)
724
 
{
725
 
  left_expr= left_exp;
726
 
  func= func_creator(all_arg);
727
 
  init(select_lex, new select_exists_subselect(this));
728
 
  max_columns= 1;
729
 
  abort_on_null= 0;
730
 
  reset();
731
 
  //if test_limit will fail then error will be reported to client
732
 
  test_limit(select_lex->master_unit());
733
 
  return;
734
 
}
735
 
 
736
 
 
737
 
void Item_exists_subselect::fix_length_and_dec()
738
 
{
739
 
   decimals= 0;
740
 
   max_length= 1;
741
 
   max_columns= engine->cols();
742
 
  /* We need only 1 row to determine existence */
743
 
  unit->global_parameters->select_limit= new Item_int((int32) 1);
744
 
}
745
 
 
746
 
double Item_exists_subselect::val_real()
747
 
{
748
 
  assert(fixed == 1);
749
 
  if (exec())
750
 
  {
751
 
    reset();
752
 
    return 0;
753
 
  }
754
 
  return (double) value;
755
 
}
756
 
 
757
 
int64_t Item_exists_subselect::val_int()
758
 
{
759
 
  assert(fixed == 1);
760
 
  if (exec())
761
 
  {
762
 
    reset();
763
 
    return 0;
764
 
  }
765
 
  return value;
766
 
}
767
 
 
768
 
String *Item_exists_subselect::val_str(String *str)
769
 
{
770
 
  assert(fixed == 1);
771
 
  if (exec())
772
 
  {
773
 
    reset();
774
 
    return 0;
775
 
  }
776
 
  str->set((uint64_t)value,&my_charset_bin);
777
 
  return str;
778
 
}
779
 
 
780
 
 
781
 
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
782
 
{
783
 
  assert(fixed == 1);
784
 
  if (exec())
785
 
  {
786
 
    reset();
787
 
    return 0;
788
 
  }
789
 
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
790
 
  return decimal_value;
791
 
}
792
 
 
793
 
 
794
 
bool Item_exists_subselect::val_bool()
795
 
{
796
 
  assert(fixed == 1);
797
 
  if (exec())
798
 
  {
799
 
    reset();
800
 
    return 0;
801
 
  }
802
 
  return value != 0;
803
 
}
804
 
 
805
 
 
806
 
double Item_in_subselect::val_real()
807
 
{
808
 
  /*
809
 
    As far as Item_in_subselect called only from Item_in_optimizer this
810
 
    method should not be used
811
 
  */
812
 
  assert(0);
813
 
  assert(fixed == 1);
814
 
  null_value= 0;
815
 
  if (exec())
816
 
  {
817
 
    reset();
818
 
    null_value= 1;
819
 
    return 0;
820
 
  }
821
 
  if (was_null && !value)
822
 
    null_value= 1;
823
 
  return (double) value;
824
 
}
825
 
 
826
 
 
827
 
int64_t Item_in_subselect::val_int()
828
 
{
829
 
  /*
830
 
    As far as Item_in_subselect called only from Item_in_optimizer this
831
 
    method should not be used
832
 
  */
833
 
  assert(fixed == 1);
834
 
  null_value= 0;
835
 
  if (exec())
836
 
  {
837
 
    reset();
838
 
    null_value= 1;
839
 
    return 0;
840
 
  }
841
 
  if (was_null && !value)
842
 
    null_value= 1;
843
 
  return value;
844
 
}
845
 
 
846
 
 
847
 
String *Item_in_subselect::val_str(String *str)
848
 
{
849
 
  /*
850
 
    As far as Item_in_subselect called only from Item_in_optimizer this
851
 
    method should not be used
852
 
  */
853
 
  assert(0);
854
 
  assert(fixed == 1);
855
 
  null_value= 0;
856
 
  if (exec())
857
 
  {
858
 
    reset();
859
 
    null_value= 1;
860
 
    return 0;
861
 
  }
862
 
  if (was_null && !value)
863
 
  {
864
 
    null_value= 1;
865
 
    return 0;
866
 
  }
867
 
  str->set((uint64_t)value, &my_charset_bin);
868
 
  return str;
869
 
}
870
 
 
871
 
 
872
 
bool Item_in_subselect::val_bool()
873
 
{
874
 
  assert(fixed == 1);
875
 
  null_value= 0;
876
 
  if (exec())
877
 
  {
878
 
    reset();
879
 
    /* 
880
 
      Must mark the IN predicate as NULL so as to make sure an enclosing NOT
881
 
      predicate will return false. See the comments in 
882
 
      subselect_uniquesubquery_engine::copy_ref_key for further details.
883
 
    */
884
 
    null_value= 1;
885
 
    return 0;
886
 
  }
887
 
  if (was_null && !value)
888
 
    null_value= 1;
889
 
  return value;
890
 
}
891
 
 
892
 
my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
893
 
{
894
 
  /*
895
 
    As far as Item_in_subselect called only from Item_in_optimizer this
896
 
    method should not be used
897
 
  */
898
 
  assert(0);
899
 
  null_value= 0;
900
 
  assert(fixed == 1);
901
 
  if (exec())
902
 
  {
903
 
    reset();
904
 
    null_value= 1;
905
 
    return 0;
906
 
  }
907
 
  if (was_null && !value)
908
 
    null_value= 1;
909
 
  int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
910
 
  return decimal_value;
911
 
}
912
 
 
913
 
 
914
 
/* 
915
 
  Rewrite a single-column IN/ALL/ANY subselect
916
 
 
917
 
  SYNOPSIS
918
 
    Item_in_subselect::single_value_transformer()
919
 
      join  Join object of the subquery (i.e. 'child' join).
920
 
      func  Subquery comparison creator
921
 
 
922
 
  DESCRIPTION
923
 
    Rewrite a single-column subquery using rule-based approach. The subquery
924
 
    
925
 
       oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
926
 
    
927
 
    First, try to convert the subquery to scalar-result subquery in one of
928
 
    the forms:
929
 
    
930
 
       - oe $cmp$ (SELECT MAX(...) )  // handled by Item_singlerow_subselect
931
 
       - oe $cmp$ <max>(SELECT ...)   // handled by Item_maxmin_subselect
932
 
   
933
 
    If that fails, the subquery will be handled with class Item_in_optimizer.
934
 
    There are two possibilites:
935
 
    - If the subquery execution method is materialization, then the subquery is
936
 
      not transformed any further.
937
 
    - Otherwise the IN predicates is transformed into EXISTS by injecting
938
 
      equi-join predicates and possibly other helper predicates. For details
939
 
      see method single_value_in_like_transformer().
940
 
 
941
 
  RETURN
942
 
    RES_OK     Either subquery was transformed, or appopriate
943
 
                       predicates where injected into it.
944
 
    RES_REDUCE The subquery was reduced to non-subquery
945
 
    RES_ERROR  Error
946
 
*/
947
 
 
948
 
Item_subselect::trans_res
949
 
Item_in_subselect::single_value_transformer(JOIN *join,
950
 
                                            Comp_creator *func)
951
 
{
952
 
  SELECT_LEX *select_lex= join->select_lex;
953
 
 
954
 
  /*
955
 
    Check that the right part of the subselect contains no more than one
956
 
    column. E.g. in SELECT 1 IN (SELECT * ..) the right part is (SELECT * ...)
957
 
  */
958
 
  if (select_lex->item_list.elements > 1)
959
 
  {
960
 
    my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
961
 
    return(RES_ERROR);
962
 
  }
963
 
 
964
 
  /*
965
 
    If this is an ALL/ANY single-value subselect, try to rewrite it with
966
 
    a MIN/MAX subselect. We can do that if a possible NULL result of the
967
 
    subselect can be ignored.
968
 
    E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten
969
 
    with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2).
970
 
    We can't check that this optimization is safe if it's not a top-level
971
 
    item of the WHERE clause (e.g. because the WHERE clause can contain IS
972
 
    NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
973
 
    later in this method.
974
 
  */
975
 
  if ((abort_on_null || (upper_item && upper_item->top_level())) &&
976
 
      !select_lex->master_unit()->uncacheable && !func->eqne_op())
977
 
  {
978
 
    if (substitution)
979
 
    {
980
 
      // It is second (third, ...) SELECT of UNION => All is done
981
 
      return(RES_OK);
982
 
    }
983
 
 
984
 
    Item *subs;
985
 
    if (!select_lex->group_list.elements &&
986
 
        !select_lex->having &&
987
 
        !select_lex->with_sum_func &&
988
 
        !(select_lex->next_select()) &&
989
 
        select_lex->table_list.elements)
990
 
    {
991
 
      Item_sum_hybrid *item;
992
 
      nesting_map save_allow_sum_func;
993
 
      if (func->l_op())
994
 
      {
995
 
        /*
996
 
          (ALL && (> || =>)) || (ANY && (< || =<))
997
 
          for ALL condition is inverted
998
 
        */
999
 
        item= new Item_sum_max(*select_lex->ref_pointer_array);
1000
 
      }
1001
 
      else
1002
 
      {
1003
 
        /*
1004
 
          (ALL && (< || =<)) || (ANY && (> || =>))
1005
 
          for ALL condition is inverted
1006
 
        */
1007
 
        item= new Item_sum_min(*select_lex->ref_pointer_array);
1008
 
      }
1009
 
      if (upper_item)
1010
 
        upper_item->set_sum_test(item);
1011
 
      *select_lex->ref_pointer_array= item;
1012
 
      {
1013
 
        List_iterator<Item> it(select_lex->item_list);
1014
 
        it++;
1015
 
        it.replace(item);
1016
 
      }
1017
 
 
1018
 
      save_allow_sum_func= thd->lex->allow_sum_func;
1019
 
      thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
1020
 
      /*
1021
 
        Item_sum_(max|min) can't substitute other item => we can use 0 as
1022
 
        reference, also Item_sum_(max|min) can't be fixed after creation, so
1023
 
        we do not check item->fixed
1024
 
      */
1025
 
      if (item->fix_fields(thd, 0))
1026
 
        return(RES_ERROR);
1027
 
      thd->lex->allow_sum_func= save_allow_sum_func; 
1028
 
      /* we added aggregate function => we have to change statistic */
1029
 
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields, 
1030
 
                        0);
1031
 
 
1032
 
      subs= new Item_singlerow_subselect(select_lex);
1033
 
    }
1034
 
    else
1035
 
    {
1036
 
      Item_maxmin_subselect *item;
1037
 
      subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
1038
 
      if (upper_item)
1039
 
        upper_item->set_sub_test(item);
1040
 
    }
1041
 
    /* fix fields is already called for  left expression */
1042
 
    substitution= func->create(left_expr, subs);
1043
 
    return(RES_OK);
1044
 
  }
1045
 
 
1046
 
  if (!substitution)
1047
 
  {
1048
 
    /* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
1049
 
    SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1050
 
    substitution= optimizer;
1051
 
 
1052
 
    SELECT_LEX *current= thd->lex->current_select, *up;
1053
 
 
1054
 
    thd->lex->current_select= up= current->return_after_parsing();
1055
 
    //optimizer never use Item **ref => we can pass 0 as parameter
1056
 
    if (!optimizer || optimizer->fix_left(thd, 0))
1057
 
    {
1058
 
      thd->lex->current_select= current;
1059
 
      return(RES_ERROR);
1060
 
    }
1061
 
    thd->lex->current_select= current;
1062
 
 
1063
 
    /*
1064
 
      As far as  Item_ref_in_optimizer do not substitute itself on fix_fields
1065
 
      we can use same item for all selects.
1066
 
    */
1067
 
    expr= new Item_direct_ref(&select_lex->context,
1068
 
                              (Item**)optimizer->get_cache(),
1069
 
                              (char *)"<no matter>",
1070
 
                              (char *)in_left_expr_name);
1071
 
 
1072
 
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1073
 
  }
1074
 
 
1075
 
  if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1076
 
  {
1077
 
    if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
1078
 
      return(RES_ERROR);
1079
 
    pushed_cond_guards[0]= true;
1080
 
  }
1081
 
 
1082
 
  /*
1083
 
    If this IN predicate can be computed via materialization, do not
1084
 
    perform the IN -> EXISTS transformation.
1085
 
  */
1086
 
  if (exec_method == MATERIALIZATION)
1087
 
    return(RES_OK);
1088
 
 
1089
 
  /* Perform the IN=>EXISTS transformation. */
1090
 
  return(single_value_in_to_exists_transformer(join, func));
1091
 
}
1092
 
 
1093
 
 
1094
 
/**
1095
 
  Transofrm an IN predicate into EXISTS via predicate injection.
1096
 
 
1097
 
  @details The transformation injects additional predicates into the subquery
1098
 
  (and makes the subquery correlated) as follows.
1099
 
 
1100
 
  - If the subquery has aggregates, GROUP BY, or HAVING, convert to
1101
 
 
1102
 
    SELECT ie FROM ...  HAVING subq_having AND 
1103
 
                               trigcond(oe $cmp$ ref_or_null_helper<ie>)
1104
 
                                   
1105
 
    the addition is wrapped into trigger only when we want to distinguish
1106
 
    between NULL and false results.
1107
 
 
1108
 
  - Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
1109
 
    following:
1110
 
 
1111
 
    = If we don't need to distinguish between NULL and false subquery:
1112
 
        
1113
 
      SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
1114
 
 
1115
 
    = If we need to distinguish between those:
1116
 
 
1117
 
      SELECT 1 FROM ...
1118
 
        WHERE  subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
1119
 
        HAVING trigcond(<is_not_null_test>(ie))
1120
 
 
1121
 
    @param join  Join object of the subquery (i.e. 'child' join).
1122
 
    @param func  Subquery comparison creator
1123
 
 
1124
 
    @retval RES_OK     Either subquery was transformed, or appopriate
1125
 
                       predicates where injected into it.
1126
 
    @retval RES_REDUCE The subquery was reduced to non-subquery
1127
 
    @retval RES_ERROR  Error
1128
 
*/
1129
 
 
1130
 
Item_subselect::trans_res
1131
 
Item_in_subselect::single_value_in_to_exists_transformer(JOIN * join, Comp_creator *func)
1132
 
{
1133
 
  SELECT_LEX *select_lex= join->select_lex;
1134
 
 
1135
 
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1136
 
  if (join->having || select_lex->with_sum_func ||
1137
 
      select_lex->group_list.elements)
1138
 
  {
1139
 
    bool tmp;
1140
 
    Item *item= func->create(expr,
1141
 
                             new Item_ref_null_helper(&select_lex->context,
1142
 
                                                      this,
1143
 
                                                      select_lex->
1144
 
                                                      ref_pointer_array,
1145
 
                                                      (char *)"<ref>",
1146
 
                                                      this->full_name()));
1147
 
    if (!abort_on_null && left_expr->maybe_null)
1148
 
    {
1149
 
      /* 
1150
 
        We can encounter "NULL IN (SELECT ...)". Wrap the added condition
1151
 
        within a trig_cond.
1152
 
      */
1153
 
      item= new Item_func_trig_cond(item, get_cond_guard(0));
1154
 
    }
1155
 
    
1156
 
    /*
1157
 
      AND and comparison functions can't be changed during fix_fields()
1158
 
      we can assign select_lex->having here, and pass 0 as last
1159
 
      argument (reference) to fix_fields()
1160
 
    */
1161
 
    select_lex->having= join->having= and_items(join->having, item);
1162
 
    if (join->having == item)
1163
 
      item->name= (char*)in_having_cond;
1164
 
    select_lex->having_fix_field= 1;
1165
 
    /*
1166
 
      we do not check join->having->fixed, because Item_and (from and_items)
1167
 
      or comparison function (from func->create) can't be fixed after creation
1168
 
    */
1169
 
    tmp= join->having->fix_fields(thd, 0);
1170
 
    select_lex->having_fix_field= 0;
1171
 
    if (tmp)
1172
 
      return(RES_ERROR);
1173
 
  }
1174
 
  else
1175
 
  {
1176
 
    Item *item= (Item*) select_lex->item_list.head();
1177
 
 
1178
 
    if (select_lex->table_list.elements)
1179
 
    {
1180
 
      bool tmp;
1181
 
      Item *having= item, *orig_item= item;
1182
 
      select_lex->item_list.empty();
1183
 
      select_lex->item_list.push_back(new Item_int("Not_used",
1184
 
                                                   (int64_t) 1,
1185
 
                                                   MY_INT64_NUM_DECIMAL_DIGITS));
1186
 
      select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1187
 
       
1188
 
      item= func->create(expr, item);
1189
 
      if (!abort_on_null && orig_item->maybe_null)
1190
 
      {
1191
 
        having= new Item_is_not_null_test(this, having);
1192
 
        if (left_expr->maybe_null)
1193
 
        {
1194
 
          if (!(having= new Item_func_trig_cond(having,
1195
 
                                                get_cond_guard(0))))
1196
 
            return(RES_ERROR);
1197
 
        }
1198
 
        /*
1199
 
          Item_is_not_null_test can't be changed during fix_fields()
1200
 
          we can assign select_lex->having here, and pass 0 as last
1201
 
          argument (reference) to fix_fields()
1202
 
        */
1203
 
        having->name= (char*)in_having_cond;
1204
 
        select_lex->having= join->having= having;
1205
 
        select_lex->having_fix_field= 1;
1206
 
        /*
1207
 
          we do not check join->having->fixed, because Item_and (from
1208
 
          and_items) or comparison function (from func->create) can't be
1209
 
          fixed after creation
1210
 
        */
1211
 
        tmp= join->having->fix_fields(thd, 0);
1212
 
        select_lex->having_fix_field= 0;
1213
 
        if (tmp)
1214
 
          return(RES_ERROR);
1215
 
        item= new Item_cond_or(item,
1216
 
                               new Item_func_isnull(orig_item));
1217
 
      }
1218
 
      /* 
1219
 
        If we may encounter NULL IN (SELECT ...) and care whether subquery
1220
 
        result is NULL or false, wrap condition in a trig_cond.
1221
 
      */
1222
 
      if (!abort_on_null && left_expr->maybe_null)
1223
 
      {
1224
 
        if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
1225
 
          return(RES_ERROR);
1226
 
      }
1227
 
      /*
1228
 
        TODO: figure out why the following is done here in 
1229
 
        single_value_transformer but there is no corresponding action in
1230
 
        row_value_transformer?
1231
 
      */
1232
 
      item->name= (char *)in_additional_cond;
1233
 
 
1234
 
      /*
1235
 
        AND can't be changed during fix_fields()
1236
 
        we can assign select_lex->having here, and pass 0 as last
1237
 
        argument (reference) to fix_fields()
1238
 
      */
1239
 
      select_lex->where= join->conds= and_items(join->conds, item);
1240
 
      select_lex->where->top_level_item();
1241
 
      /*
1242
 
        we do not check join->conds->fixed, because Item_and can't be fixed
1243
 
        after creation
1244
 
      */
1245
 
      if (join->conds->fix_fields(thd, 0))
1246
 
        return(RES_ERROR);
1247
 
    }
1248
 
    else
1249
 
    {
1250
 
      bool tmp;
1251
 
      if (select_lex->master_unit()->is_union())
1252
 
      {
1253
 
        /*
1254
 
          comparison functions can't be changed during fix_fields()
1255
 
          we can assign select_lex->having here, and pass 0 as last
1256
 
          argument (reference) to fix_fields()
1257
 
        */
1258
 
        Item *new_having=
1259
 
          func->create(expr,
1260
 
                       new Item_ref_null_helper(&select_lex->context, this,
1261
 
                                            select_lex->ref_pointer_array,
1262
 
                                            (char *)"<no matter>",
1263
 
                                            (char *)"<result>"));
1264
 
        if (!abort_on_null && left_expr->maybe_null)
1265
 
        {
1266
 
          if (!(new_having= new Item_func_trig_cond(new_having,
1267
 
                                                    get_cond_guard(0))))
1268
 
            return(RES_ERROR);
1269
 
        }
1270
 
        new_having->name= (char*)in_having_cond;
1271
 
        select_lex->having= join->having= new_having;
1272
 
        select_lex->having_fix_field= 1;
1273
 
        
1274
 
        /*
1275
 
          we do not check join->having->fixed, because comparison function
1276
 
          (from func->create) can't be fixed after creation
1277
 
        */
1278
 
        tmp= join->having->fix_fields(thd, 0);
1279
 
        select_lex->having_fix_field= 0;
1280
 
        if (tmp)
1281
 
          return(RES_ERROR);
1282
 
      }
1283
 
      else
1284
 
      {
1285
 
        // it is single select without tables => possible optimization
1286
 
        item= func->create(left_expr, item);
1287
 
        // fix_field of item will be done in time of substituting
1288
 
        substitution= item;
1289
 
        have_to_be_excluded= 1;
1290
 
        if (thd->lex->describe)
1291
 
        {
1292
 
          char warn_buff[MYSQL_ERRMSG_SIZE];
1293
 
          sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1294
 
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1295
 
                       ER_SELECT_REDUCED, warn_buff);
1296
 
        }
1297
 
        return(RES_REDUCE);
1298
 
      }
1299
 
    }
1300
 
  }
1301
 
 
1302
 
  return(RES_OK);
1303
 
}
1304
 
 
1305
 
 
1306
 
Item_subselect::trans_res
1307
 
Item_in_subselect::row_value_transformer(JOIN *join)
1308
 
{
1309
 
  SELECT_LEX *select_lex= join->select_lex;
1310
 
  uint cols_num= left_expr->cols();
1311
 
 
1312
 
  if (select_lex->item_list.elements != left_expr->cols())
1313
 
  {
1314
 
    my_error(ER_OPERAND_COLUMNS, MYF(0), left_expr->cols());
1315
 
    return(RES_ERROR);
1316
 
  }
1317
 
 
1318
 
  /*
1319
 
    Wrap the current IN predicate in an Item_in_optimizer. The actual
1320
 
    substitution in the Item tree takes place in Item_subselect::fix_fields.
1321
 
  */
1322
 
  if (!substitution)
1323
 
  {
1324
 
    //first call for this unit
1325
 
    SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
1326
 
    substitution= optimizer;
1327
 
 
1328
 
    SELECT_LEX *current= thd->lex->current_select, *up;
1329
 
    thd->lex->current_select= up= current->return_after_parsing();
1330
 
    //optimizer never use Item **ref => we can pass 0 as parameter
1331
 
    if (!optimizer || optimizer->fix_left(thd, 0))
1332
 
    {
1333
 
      thd->lex->current_select= current;
1334
 
      return(RES_ERROR);
1335
 
    }
1336
 
 
1337
 
    // we will refer to upper level cache array => we have to save it in PS
1338
 
    optimizer->keep_top_level_cache();
1339
 
 
1340
 
    thd->lex->current_select= current;
1341
 
    master_unit->uncacheable|= UNCACHEABLE_DEPENDENT;
1342
 
 
1343
 
    if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
1344
 
    {
1345
 
      if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
1346
 
                                                        left_expr->cols())))
1347
 
        return(RES_ERROR);
1348
 
      for (uint i= 0; i < cols_num; i++)
1349
 
        pushed_cond_guards[i]= true;
1350
 
    }
1351
 
  }
1352
 
 
1353
 
  /*
1354
 
    If this IN predicate can be computed via materialization, do not
1355
 
    perform the IN -> EXISTS transformation.
1356
 
  */
1357
 
  if (exec_method == MATERIALIZATION)
1358
 
    return(RES_OK);
1359
 
 
1360
 
  /* Perform the IN=>EXISTS transformation. */
1361
 
  return(row_value_in_to_exists_transformer(join));
1362
 
}
1363
 
 
1364
 
 
1365
 
/**
1366
 
  Tranform a (possibly non-correlated) IN subquery into a correlated EXISTS.
1367
 
 
1368
 
  @todo
1369
 
  The IF-ELSE below can be refactored so that there is no duplication of the
1370
 
  statements that create the new conditions. For this we have to invert the IF
1371
 
  and the FOR statements as this:
1372
 
  for (each left operand)
1373
 
    create the equi-join condition
1374
 
    if (is_having_used || !abort_on_null)
1375
 
      create the "is null" and is_not_null_test items
1376
 
    if (is_having_used)
1377
 
      add the equi-join and the null tests to HAVING
1378
 
    else
1379
 
      add the equi-join and the "is null" to WHERE
1380
 
      add the is_not_null_test to HAVING
1381
 
*/
1382
 
 
1383
 
Item_subselect::trans_res
1384
 
Item_in_subselect::row_value_in_to_exists_transformer(JOIN * join)
1385
 
{
1386
 
  SELECT_LEX *select_lex= join->select_lex;
1387
 
  Item *having_item= 0;
1388
 
  uint cols_num= left_expr->cols();
1389
 
  bool is_having_used= (join->having || select_lex->with_sum_func ||
1390
 
                        select_lex->group_list.first ||
1391
 
                        !select_lex->table_list.elements);
1392
 
 
1393
 
  select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
1394
 
  if (is_having_used)
1395
 
  {
1396
 
    /*
1397
 
      (l1, l2, l3) IN (SELECT v1, v2, v3 ... HAVING having) =>
1398
 
      EXISTS (SELECT ... HAVING having and
1399
 
                                (l1 = v1 or is null v1) and
1400
 
                                (l2 = v2 or is null v2) and
1401
 
                                (l3 = v3 or is null v3) and
1402
 
                                is_not_null_test(v1) and
1403
 
                                is_not_null_test(v2) and
1404
 
                                is_not_null_test(v3))
1405
 
      where is_not_null_test used to register nulls in case if we have
1406
 
      not found matching to return correct NULL value
1407
 
      TODO: say here explicitly if the order of AND parts matters or not.
1408
 
    */
1409
 
    Item *item_having_part2= 0;
1410
 
    for (uint i= 0; i < cols_num; i++)
1411
 
    {
1412
 
      assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1413
 
                  (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1414
 
                   ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1415
 
                    Item_ref::OUTER_REF));
1416
 
      if (select_lex->ref_pointer_array[i]->
1417
 
          check_cols(left_expr->element_index(i)->cols()))
1418
 
        return(RES_ERROR);
1419
 
      Item *item_eq=
1420
 
        new Item_func_eq(new
1421
 
                         Item_ref(&select_lex->context,
1422
 
                                  (*optimizer->get_cache())->
1423
 
                                  addr(i),
1424
 
                                  (char *)"<no matter>",
1425
 
                                  (char *)in_left_expr_name),
1426
 
                         new
1427
 
                         Item_ref(&select_lex->context,
1428
 
                                  select_lex->ref_pointer_array + i,
1429
 
                                  (char *)"<no matter>",
1430
 
                                  (char *)"<list ref>")
1431
 
                        );
1432
 
      Item *item_isnull=
1433
 
        new Item_func_isnull(new
1434
 
                             Item_ref(&select_lex->context,
1435
 
                                      select_lex->ref_pointer_array+i,
1436
 
                                      (char *)"<no matter>",
1437
 
                                      (char *)"<list ref>")
1438
 
                            );
1439
 
      Item *col_item= new Item_cond_or(item_eq, item_isnull);
1440
 
      if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1441
 
      {
1442
 
        if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
1443
 
          return(RES_ERROR);
1444
 
      }
1445
 
      having_item= and_items(having_item, col_item);
1446
 
      
1447
 
      Item *item_nnull_test= 
1448
 
         new Item_is_not_null_test(this,
1449
 
                                   new Item_ref(&select_lex->context,
1450
 
                                                select_lex->
1451
 
                                                ref_pointer_array + i,
1452
 
                                                (char *)"<no matter>",
1453
 
                                                (char *)"<list ref>"));
1454
 
      if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1455
 
      {
1456
 
        if (!(item_nnull_test= 
1457
 
              new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
1458
 
          return(RES_ERROR);
1459
 
      }
1460
 
      item_having_part2= and_items(item_having_part2, item_nnull_test);
1461
 
      item_having_part2->top_level_item();
1462
 
    }
1463
 
    having_item= and_items(having_item, item_having_part2);
1464
 
    having_item->top_level_item();
1465
 
  }
1466
 
  else
1467
 
  {
1468
 
    /*
1469
 
      (l1, l2, l3) IN (SELECT v1, v2, v3 ... WHERE where) =>
1470
 
      EXISTS (SELECT ... WHERE where and
1471
 
                               (l1 = v1 or is null v1) and
1472
 
                               (l2 = v2 or is null v2) and
1473
 
                               (l3 = v3 or is null v3)
1474
 
                         HAVING is_not_null_test(v1) and
1475
 
                                is_not_null_test(v2) and
1476
 
                                is_not_null_test(v3))
1477
 
      where is_not_null_test register NULLs values but reject rows
1478
 
 
1479
 
      in case when we do not need correct NULL, we have simplier construction:
1480
 
      EXISTS (SELECT ... WHERE where and
1481
 
                               (l1 = v1) and
1482
 
                               (l2 = v2) and
1483
 
                               (l3 = v3)
1484
 
    */
1485
 
    Item *where_item= 0;
1486
 
    for (uint i= 0; i < cols_num; i++)
1487
 
    {
1488
 
      Item *item, *item_isnull;
1489
 
      assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1490
 
                  (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1491
 
                   ((Item_ref*)(select_lex->ref_pointer_array[i]))->ref_type() ==
1492
 
                    Item_ref::OUTER_REF));
1493
 
      if (select_lex->ref_pointer_array[i]->
1494
 
          check_cols(left_expr->element_index(i)->cols()))
1495
 
        return(RES_ERROR);
1496
 
      item=
1497
 
        new Item_func_eq(new
1498
 
                         Item_direct_ref(&select_lex->context,
1499
 
                                         (*optimizer->get_cache())->
1500
 
                                         addr(i),
1501
 
                                         (char *)"<no matter>",
1502
 
                                         (char *)in_left_expr_name),
1503
 
                         new
1504
 
                         Item_direct_ref(&select_lex->context,
1505
 
                                         select_lex->
1506
 
                                         ref_pointer_array+i,
1507
 
                                         (char *)"<no matter>",
1508
 
                                         (char *)"<list ref>")
1509
 
                        );
1510
 
      if (!abort_on_null)
1511
 
      {
1512
 
        Item *having_col_item=
1513
 
          new Item_is_not_null_test(this,
1514
 
                                    new
1515
 
                                    Item_ref(&select_lex->context, 
1516
 
                                             select_lex->ref_pointer_array + i,
1517
 
                                             (char *)"<no matter>",
1518
 
                                             (char *)"<list ref>"));
1519
 
        
1520
 
        
1521
 
        item_isnull= new
1522
 
          Item_func_isnull(new
1523
 
                           Item_direct_ref(&select_lex->context,
1524
 
                                           select_lex->
1525
 
                                           ref_pointer_array+i,
1526
 
                                           (char *)"<no matter>",
1527
 
                                           (char *)"<list ref>")
1528
 
                          );
1529
 
        item= new Item_cond_or(item, item_isnull);
1530
 
        /* 
1531
 
          TODO: why we create the above for cases where the right part
1532
 
                cant be NULL?
1533
 
        */
1534
 
        if (left_expr->element_index(i)->maybe_null)
1535
 
        {
1536
 
          if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
1537
 
            return(RES_ERROR);
1538
 
          if (!(having_col_item= 
1539
 
                  new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
1540
 
            return(RES_ERROR);
1541
 
        }
1542
 
        having_item= and_items(having_item, having_col_item);
1543
 
      }
1544
 
      where_item= and_items(where_item, item);
1545
 
    }
1546
 
    /*
1547
 
      AND can't be changed during fix_fields()
1548
 
      we can assign select_lex->where here, and pass 0 as last
1549
 
      argument (reference) to fix_fields()
1550
 
    */
1551
 
    select_lex->where= join->conds= and_items(join->conds, where_item);
1552
 
    select_lex->where->top_level_item();
1553
 
    if (join->conds->fix_fields(thd, 0))
1554
 
      return(RES_ERROR);
1555
 
  }
1556
 
  if (having_item)
1557
 
  {
1558
 
    bool res;
1559
 
    select_lex->having= join->having= and_items(join->having, having_item);
1560
 
    if (having_item == select_lex->having)
1561
 
      having_item->name= (char*)in_having_cond;
1562
 
    select_lex->having->top_level_item();
1563
 
    /*
1564
 
      AND can't be changed during fix_fields()
1565
 
      we can assign select_lex->having here, and pass 0 as last
1566
 
      argument (reference) to fix_fields()
1567
 
    */
1568
 
    select_lex->having_fix_field= 1;
1569
 
    res= join->having->fix_fields(thd, 0);
1570
 
    select_lex->having_fix_field= 0;
1571
 
    if (res)
1572
 
    {
1573
 
      return(RES_ERROR);
1574
 
    }
1575
 
  }
1576
 
 
1577
 
  return(RES_OK);
1578
 
}
1579
 
 
1580
 
 
1581
 
Item_subselect::trans_res
1582
 
Item_in_subselect::select_transformer(JOIN *join)
1583
 
{
1584
 
  return select_in_like_transformer(join, &eq_creator);
1585
 
}
1586
 
 
1587
 
 
1588
 
/**
1589
 
  Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
1590
 
  transformation function.
1591
 
 
1592
 
    To decide which transformation procedure (scalar or row) applicable here
1593
 
    we have to call fix_fields() for left expression to be able to call
1594
 
    cols() method on it. Also this method make arena management for
1595
 
    underlying transformation methods.
1596
 
 
1597
 
  @param join    JOIN object of transforming subquery
1598
 
  @param func    creator of condition function of subquery
1599
 
 
1600
 
  @retval
1601
 
    RES_OK      OK
1602
 
  @retval
1603
 
    RES_REDUCE  OK, and current subquery was reduced during
1604
 
    transformation
1605
 
  @retval
1606
 
    RES_ERROR   Error
1607
 
*/
1608
 
 
1609
 
Item_subselect::trans_res
1610
 
Item_in_subselect::select_in_like_transformer(JOIN *join, Comp_creator *func)
1611
 
{
1612
 
  SELECT_LEX *current= thd->lex->current_select, *up;
1613
 
  const char *save_where= thd->where;
1614
 
  Item_subselect::trans_res res= RES_ERROR;
1615
 
  bool result;
1616
 
 
1617
 
  {
1618
 
    /*
1619
 
      IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1620
 
      ORDER BY clause becomes meaningless thus we drop it here.
1621
 
    */
1622
 
    SELECT_LEX *sl= current->master_unit()->first_select();
1623
 
    for (; sl; sl= sl->next_select())
1624
 
    {
1625
 
      if (sl->join)
1626
 
        sl->join->order= 0;
1627
 
    }
1628
 
  }
1629
 
 
1630
 
  if (changed)
1631
 
    return(RES_OK);
1632
 
 
1633
 
  thd->where= "IN/ALL/ANY subquery";
1634
 
 
1635
 
  /*
1636
 
    In some optimisation cases we will not need this Item_in_optimizer
1637
 
    object, but we can't know it here, but here we need address correct
1638
 
    reference on left expresion.
1639
 
  */
1640
 
  if (!optimizer)
1641
 
  {
1642
 
    result= (!(optimizer= new Item_in_optimizer(left_expr, this)));
1643
 
    if (result)
1644
 
      goto err;
1645
 
  }
1646
 
 
1647
 
  thd->lex->current_select= up= current->return_after_parsing();
1648
 
  result= (!left_expr->fixed &&
1649
 
           left_expr->fix_fields(thd, optimizer->arguments()));
1650
 
  /* fix_fields can change reference to left_expr, we need reassign it */
1651
 
  left_expr= optimizer->arguments()[0];
1652
 
 
1653
 
  thd->lex->current_select= current;
1654
 
  if (result)
1655
 
    goto err;
1656
 
 
1657
 
  /*
1658
 
    If we didn't choose an execution method up to this point, we choose
1659
 
    the IN=>EXISTS transformation.
1660
 
  */
1661
 
  if (exec_method == NOT_TRANSFORMED)
1662
 
    exec_method= IN_TO_EXISTS;
1663
 
 
1664
 
  /*
1665
 
    Both transformers call fix_fields() only for Items created inside them,
1666
 
    and all those items do not make permanent changes in the current item arena
1667
 
    which allows us to call them with changed arena (if we do not know the
1668
 
    nature of Item, we have to call fix_fields() for it only with the original
1669
 
    arena to avoid memory leak).
1670
 
  */
1671
 
  if (left_expr->cols() == 1)
1672
 
    res= single_value_transformer(join, func);
1673
 
  else
1674
 
  {
1675
 
    /* we do not support row operation for ALL/ANY/SOME */
1676
 
    if (func != &eq_creator)
1677
 
    {
1678
 
      my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
1679
 
      return(RES_ERROR);
1680
 
    }
1681
 
    res= row_value_transformer(join);
1682
 
  }
1683
 
err:
1684
 
  thd->where= save_where;
1685
 
  return(res);
1686
 
}
1687
 
 
1688
 
 
1689
 
void Item_in_subselect::print(String *str, enum_query_type query_type)
1690
 
{
1691
 
  if (exec_method == IN_TO_EXISTS)
1692
 
    str->append(STRING_WITH_LEN("<exists>"));
1693
 
  else
1694
 
  {
1695
 
    left_expr->print(str, query_type);
1696
 
    str->append(STRING_WITH_LEN(" in "));
1697
 
  }
1698
 
  Item_subselect::print(str, query_type);
1699
 
}
1700
 
 
1701
 
 
1702
 
bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
1703
 
{
1704
 
  bool result = 0;
1705
 
 
1706
 
  if (exec_method == SEMI_JOIN)
1707
 
    return !( (*ref)= new Item_int(1));
1708
 
 
1709
 
  return result || Item_subselect::fix_fields(thd_arg, ref);
1710
 
}
1711
 
 
1712
 
 
1713
 
/**
1714
 
  Try to create an engine to compute the subselect via materialization,
1715
 
  and if this fails, revert to execution via the IN=>EXISTS transformation.
1716
 
 
1717
 
  @details
1718
 
    The purpose of this method is to hide the implementation details
1719
 
    of this Item's execution. The method creates a new engine for
1720
 
    materialized execution, and initializes the engine.
1721
 
 
1722
 
    If this initialization fails
1723
 
    - either because it wasn't possible to create the needed temporary table
1724
 
      and its index,
1725
 
    - or because of a memory allocation error,
1726
 
    then we revert back to execution via the IN=>EXISTS tranformation.
1727
 
 
1728
 
    The initialization of the new engine is divided in two parts - a permanent
1729
 
    one that lives across prepared statements, and one that is repeated for each
1730
 
    execution.
1731
 
 
1732
 
  @returns
1733
 
    @retval true  memory allocation error occurred
1734
 
    @retval false an execution method was chosen successfully
1735
 
*/
1736
 
 
1737
 
bool Item_in_subselect::setup_engine()
1738
 
{
1739
 
  subselect_hash_sj_engine *new_engine= NULL;
1740
 
  bool res= false;
1741
 
 
1742
 
  if (engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE)
1743
 
  {
1744
 
    /* Create/initialize objects in permanent memory. */
1745
 
    subselect_single_select_engine *old_engine;
1746
 
 
1747
 
    old_engine= (subselect_single_select_engine*) engine;
1748
 
 
1749
 
    if (!(new_engine= new subselect_hash_sj_engine(thd, this,
1750
 
                                                   old_engine)) ||
1751
 
        new_engine->init_permanent(unit->get_unit_column_types()))
1752
 
    {
1753
 
      Item_subselect::trans_res trans_res;
1754
 
      /*
1755
 
        If for some reason we cannot use materialization for this IN predicate,
1756
 
        delete all materialization-related objects, and apply the IN=>EXISTS
1757
 
        transformation.
1758
 
      */
1759
 
      delete new_engine;
1760
 
      new_engine= NULL;
1761
 
      exec_method= NOT_TRANSFORMED;
1762
 
      if (left_expr->cols() == 1)
1763
 
        trans_res= single_value_in_to_exists_transformer(old_engine->join,
1764
 
                                                         &eq_creator);
1765
 
      else
1766
 
        trans_res= row_value_in_to_exists_transformer(old_engine->join);
1767
 
      res= (trans_res != Item_subselect::RES_OK);
1768
 
    }
1769
 
    if (new_engine)
1770
 
      engine= new_engine;
1771
 
  }
1772
 
  else
1773
 
  {
1774
 
    assert(engine->engine_type() == subselect_engine::HASH_SJ_ENGINE);
1775
 
    new_engine= (subselect_hash_sj_engine*) engine;
1776
 
  }
1777
 
 
1778
 
  /* Initilizations done in runtime memory, repeated for each execution. */
1779
 
  if (new_engine)
1780
 
  {
1781
 
    /*
1782
 
      Reset the LIMIT 1 set in Item_exists_subselect::fix_length_and_dec.
1783
 
      TODO:
1784
 
      Currently we set the subquery LIMIT to infinity, and this is correct
1785
 
      because we forbid at parse time LIMIT inside IN subqueries (see
1786
 
      Item_in_subselect::test_limit). However, once we allow this, here
1787
 
      we should set the correct limit if given in the query.
1788
 
    */
1789
 
    unit->global_parameters->select_limit= NULL;
1790
 
    if ((res= new_engine->init_runtime()))
1791
 
      return(res);
1792
 
  }
1793
 
 
1794
 
  return(res);
1795
 
}
1796
 
 
1797
 
 
1798
 
/**
1799
 
  Initialize the cache of the left operand of the IN predicate.
1800
 
 
1801
 
  @note This method has the same purpose as alloc_group_fields(),
1802
 
  but it takes a different kind of collection of items, and the
1803
 
  list we push to is dynamically allocated.
1804
 
 
1805
 
  @retval true  if a memory allocation error occurred or the cache is
1806
 
                not applicable to the current query
1807
 
  @retval false if success
1808
 
*/
1809
 
 
1810
 
bool Item_in_subselect::init_left_expr_cache()
1811
 
{
1812
 
  JOIN *outer_join;
1813
 
  Next_select_func end_select;
1814
 
  bool use_result_field= false;
1815
 
 
1816
 
  outer_join= unit->outer_select()->join;
1817
 
  if (!outer_join || !outer_join->tables)
1818
 
    return true;
1819
 
  /*
1820
 
    If we use end_[send | write]_group to handle complete rows of the outer
1821
 
    query, make the cache of the left IN operand use Item_field::result_field
1822
 
    instead of Item_field::field.  We need this because normally
1823
 
    Cached_item_field uses Item::field to fetch field data, while
1824
 
    copy_ref_key() that copies the left IN operand into a lookup key uses
1825
 
    Item::result_field. In the case end_[send | write]_group result_field is
1826
 
    one row behind field.
1827
 
  */
1828
 
  end_select= outer_join->join_tab[outer_join->tables-1].next_select;
1829
 
  if (end_select == end_send_group || end_select == end_write_group)
1830
 
    use_result_field= true;
1831
 
 
1832
 
  if (!(left_expr_cache= new List<Cached_item>))
1833
 
    return true;
1834
 
 
1835
 
  for (uint i= 0; i < left_expr->cols(); i++)
1836
 
  {
1837
 
    Cached_item *cur_item_cache= new_Cached_item(thd,
1838
 
                                                 left_expr->element_index(i),
1839
 
                                                 use_result_field);
1840
 
    if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1841
 
      return true;
1842
 
  }
1843
 
  return false;
1844
 
}
1845
 
 
1846
 
 
1847
 
/*
1848
 
  Callback to test if an IN predicate is expensive.
1849
 
 
1850
 
  @details
1851
 
    IN predicates are considered expensive only if they will be executed via
1852
 
    materialization. The return value affects the behavior of
1853
 
    make_cond_for_table() in such a way that it is unchanged when we use
1854
 
    the IN=>EXISTS transformation to compute IN.
1855
 
 
1856
 
  @retval true  if the predicate is expensive
1857
 
  @retval false otherwise
1858
 
*/
1859
 
 
1860
 
bool Item_in_subselect::is_expensive_processor(uchar *arg __attribute__((__unused__)))
1861
 
{
1862
 
  return exec_method == MATERIALIZATION;
1863
 
}
1864
 
 
1865
 
 
1866
 
Item_subselect::trans_res
1867
 
Item_allany_subselect::select_transformer(JOIN *join)
1868
 
{
1869
 
  exec_method= IN_TO_EXISTS;
1870
 
  if (upper_item)
1871
 
    upper_item->show= 1;
1872
 
  return(select_in_like_transformer(join, func));
1873
 
}
1874
 
 
1875
 
 
1876
 
void Item_allany_subselect::print(String *str, enum_query_type query_type)
1877
 
{
1878
 
  if (exec_method == IN_TO_EXISTS)
1879
 
    str->append(STRING_WITH_LEN("<exists>"));
1880
 
  else
1881
 
  {
1882
 
    left_expr->print(str, query_type);
1883
 
    str->append(' ');
1884
 
    str->append(func->symbol(all));
1885
 
    str->append(all ? " all " : " any ", 5);
1886
 
  }
1887
 
  Item_subselect::print(str, query_type);
1888
 
}
1889
 
 
1890
 
 
1891
 
void subselect_engine::set_thd(THD *thd_arg)
1892
 
{
1893
 
  thd= thd_arg;
1894
 
  if (result)
1895
 
    result->set_thd(thd_arg);
1896
 
}
1897
 
 
1898
 
 
1899
 
subselect_single_select_engine::
1900
 
subselect_single_select_engine(st_select_lex *select,
1901
 
                               select_result_interceptor *result_arg,
1902
 
                               Item_subselect *item_arg)
1903
 
  :subselect_engine(item_arg, result_arg),
1904
 
   prepared(0), executed(0), select_lex(select), join(0)
1905
 
{
1906
 
  select_lex->master_unit()->item= item_arg;
1907
 
}
1908
 
 
1909
 
 
1910
 
void subselect_single_select_engine::cleanup()
1911
 
{
1912
 
  prepared= executed= 0;
1913
 
  join= 0;
1914
 
  result->cleanup();
1915
 
  return;
1916
 
}
1917
 
 
1918
 
 
1919
 
void subselect_union_engine::cleanup()
1920
 
{
1921
 
  unit->reinit_exec_mechanism();
1922
 
  result->cleanup();
1923
 
  return;
1924
 
}
1925
 
 
1926
 
 
1927
 
bool subselect_union_engine::is_executed() const
1928
 
{
1929
 
  return unit->executed;
1930
 
}
1931
 
 
1932
 
 
1933
 
/*
1934
 
  Check if last execution of the subquery engine produced any rows
1935
 
 
1936
 
  SYNOPSIS
1937
 
    subselect_union_engine::no_rows()
1938
 
 
1939
 
  DESCRIPTION
1940
 
    Check if last execution of the subquery engine produced any rows. The
1941
 
    return value is undefined if last execution ended in an error.
1942
 
 
1943
 
  RETURN
1944
 
    true  - Last subselect execution has produced no rows
1945
 
    false - Otherwise
1946
 
*/
1947
 
 
1948
 
bool subselect_union_engine::no_rows()
1949
 
{
1950
 
  /* Check if we got any rows when reading UNION result from temp. table: */
1951
 
  return test(!unit->fake_select_lex->join->send_records);
1952
 
}
1953
 
 
1954
 
 
1955
 
void subselect_uniquesubquery_engine::cleanup()
1956
 
{
1957
 
  /* Tell handler we don't need the index anymore */
1958
 
  if (tab->table->file->inited)
1959
 
    tab->table->file->ha_index_end();
1960
 
  return;
1961
 
}
1962
 
 
1963
 
 
1964
 
subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
1965
 
                                               select_result_interceptor *result_arg,
1966
 
                                               Item_subselect *item_arg)
1967
 
  :subselect_engine(item_arg, result_arg)
1968
 
{
1969
 
  unit= u;
1970
 
  unit->item= item_arg;
1971
 
}
1972
 
 
1973
 
 
1974
 
/**
1975
 
  Create and prepare the JOIN object that represents the query execution
1976
 
  plan for the subquery.
1977
 
 
1978
 
  @detail
1979
 
  This method is called from Item_subselect::fix_fields. For prepared
1980
 
  statements it is called both during the PREPARE and EXECUTE phases in the
1981
 
  following ways:
1982
 
  - During PREPARE the optimizer needs some properties
1983
 
    (join->fields_list.elements) of the JOIN to proceed with preparation of
1984
 
    the remaining query (namely to complete ::fix_fields for the subselect
1985
 
    related classes. In the end of PREPARE the JOIN is deleted.
1986
 
  - When we EXECUTE the query, Item_subselect::fix_fields is called again, and
1987
 
    the JOIN object is re-created again, prepared and executed. In the end of
1988
 
    execution it is deleted.
1989
 
  In all cases the JOIN is created in runtime memory (not in the permanent
1990
 
  memory root).
1991
 
 
1992
 
  @todo
1993
 
  Re-check what properties of 'join' are needed during prepare, and see if
1994
 
  we can avoid creating a JOIN during JOIN::prepare of the outer join.
1995
 
 
1996
 
  @retval 0  if success
1997
 
  @retval 1  if error
1998
 
*/
1999
 
 
2000
 
int subselect_single_select_engine::prepare()
2001
 
{
2002
 
  if (prepared)
2003
 
    return 0;
2004
 
  join= new JOIN(thd, select_lex->item_list,
2005
 
                 select_lex->options | SELECT_NO_UNLOCK, result);
2006
 
  if (!join || !result)
2007
 
    return 1; /* Fatal error is set already. */
2008
 
  prepared= 1;
2009
 
  SELECT_LEX *save_select= thd->lex->current_select;
2010
 
  thd->lex->current_select= select_lex;
2011
 
  if (join->prepare(&select_lex->ref_pointer_array,
2012
 
                    (TABLE_LIST*) select_lex->table_list.first,
2013
 
                    select_lex->with_wild,
2014
 
                    select_lex->where,
2015
 
                    select_lex->order_list.elements +
2016
 
                    select_lex->group_list.elements,
2017
 
                    (ORDER*) select_lex->order_list.first,
2018
 
                    (ORDER*) select_lex->group_list.first,
2019
 
                    select_lex->having,
2020
 
                    (ORDER*) 0, select_lex,
2021
 
                    select_lex->master_unit()))
2022
 
    return 1;
2023
 
  thd->lex->current_select= save_select;
2024
 
  return 0;
2025
 
}
2026
 
 
2027
 
int subselect_union_engine::prepare()
2028
 
{
2029
 
  return unit->prepare(thd, result, SELECT_NO_UNLOCK);
2030
 
}
2031
 
 
2032
 
int subselect_uniquesubquery_engine::prepare()
2033
 
{
2034
 
  /* Should never be called. */
2035
 
  assert(false);
2036
 
  return 1;
2037
 
}
2038
 
 
2039
 
 
2040
 
/*
2041
 
  Check if last execution of the subquery engine produced any rows
2042
 
 
2043
 
  SYNOPSIS
2044
 
    subselect_single_select_engine::no_rows()
2045
 
 
2046
 
  DESCRIPTION
2047
 
    Check if last execution of the subquery engine produced any rows. The
2048
 
    return value is undefined if last execution ended in an error.
2049
 
 
2050
 
  RETURN
2051
 
    true  - Last subselect execution has produced no rows
2052
 
    false - Otherwise
2053
 
*/
2054
 
 
2055
 
bool subselect_single_select_engine::no_rows()
2056
 
2057
 
  return !item->assigned();
2058
 
}
2059
 
 
2060
 
 
2061
 
/* 
2062
 
 makes storage for the output values for the subquery and calcuates 
2063
 
 their data and column types and their nullability.
2064
 
*/ 
2065
 
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2066
 
{
2067
 
  Item *sel_item;
2068
 
  List_iterator_fast<Item> li(item_list);
2069
 
  res_type= STRING_RESULT;
2070
 
  res_field_type= MYSQL_TYPE_STRING;
2071
 
  for (uint i= 0; (sel_item= li++); i++)
2072
 
  {
2073
 
    item->max_length= sel_item->max_length;
2074
 
    res_type= sel_item->result_type();
2075
 
    res_field_type= sel_item->field_type();
2076
 
    item->decimals= sel_item->decimals;
2077
 
    item->unsigned_flag= sel_item->unsigned_flag;
2078
 
    maybe_null= sel_item->maybe_null;
2079
 
    if (!(row[i]= Item_cache::get_cache(sel_item)))
2080
 
      return;
2081
 
    row[i]->setup(sel_item);
2082
 
  }
2083
 
  if (item_list.elements > 1)
2084
 
    res_type= ROW_RESULT;
2085
 
}
2086
 
 
2087
 
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
2088
 
{
2089
 
  assert(row || select_lex->item_list.elements==1);
2090
 
  set_row(select_lex->item_list, row);
2091
 
  item->collation.set(row[0]->collation);
2092
 
  if (cols() != 1)
2093
 
    maybe_null= 0;
2094
 
}
2095
 
 
2096
 
void subselect_union_engine::fix_length_and_dec(Item_cache **row)
2097
 
{
2098
 
  assert(row || unit->first_select()->item_list.elements==1);
2099
 
 
2100
 
  if (unit->first_select()->item_list.elements == 1)
2101
 
  {
2102
 
    set_row(unit->types, row);
2103
 
    item->collation.set(row[0]->collation);
2104
 
  }
2105
 
  else
2106
 
  {
2107
 
    bool maybe_null_saved= maybe_null;
2108
 
    set_row(unit->types, row);
2109
 
    maybe_null= maybe_null_saved;
2110
 
  }
2111
 
}
2112
 
 
2113
 
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row __attribute__((__unused__)))
2114
 
{
2115
 
  //this never should be called
2116
 
  assert(0);
2117
 
}
2118
 
 
2119
 
int  init_read_record_seq(JOIN_TAB *tab);
2120
 
int join_read_always_key_or_null(JOIN_TAB *tab);
2121
 
int join_read_next_same_or_null(READ_RECORD *info);
2122
 
 
2123
 
int subselect_single_select_engine::exec()
2124
 
{
2125
 
  char const *save_where= thd->where;
2126
 
  SELECT_LEX *save_select= thd->lex->current_select;
2127
 
  thd->lex->current_select= select_lex;
2128
 
  if (!join->optimized)
2129
 
  {
2130
 
    SELECT_LEX_UNIT *unit= select_lex->master_unit();
2131
 
 
2132
 
    unit->set_limit(unit->global_parameters);
2133
 
    if (join->flatten_subqueries())
2134
 
    {
2135
 
      thd->is_fatal_error= true;
2136
 
      return(1);
2137
 
    }
2138
 
    if (join->optimize())
2139
 
    {
2140
 
      thd->where= save_where;
2141
 
      executed= 1;
2142
 
      thd->lex->current_select= save_select;
2143
 
      return(join->error ? join->error : 1);
2144
 
    }
2145
 
    if (!select_lex->uncacheable && thd->lex->describe && 
2146
 
        !(join->select_options & SELECT_DESCRIBE) && 
2147
 
        join->need_tmp && item->const_item())
2148
 
    {
2149
 
      /*
2150
 
        Force join->join_tmp creation, because this subquery will be replaced
2151
 
        by a simple select from the materialization temp table by optimize()
2152
 
        called by EXPLAIN and we need to preserve the initial query structure
2153
 
        so we can display it.
2154
 
       */
2155
 
      select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
2156
 
      select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
2157
 
      if (join->init_save_join_tab())
2158
 
        return(1);                        /* purecov: inspected */
2159
 
    }
2160
 
    if (item->engine_changed)
2161
 
    {
2162
 
      return(1);
2163
 
    }
2164
 
  }
2165
 
  if (select_lex->uncacheable &&
2166
 
      select_lex->uncacheable != UNCACHEABLE_EXPLAIN
2167
 
      && executed)
2168
 
  {
2169
 
    if (join->reinit())
2170
 
    {
2171
 
      thd->where= save_where;
2172
 
      thd->lex->current_select= save_select;
2173
 
      return(1);
2174
 
    }
2175
 
    item->reset();
2176
 
    item->assigned((executed= 0));
2177
 
  }
2178
 
  if (!executed)
2179
 
  {
2180
 
    item->reset_value_registration();
2181
 
    JOIN_TAB *changed_tabs[MAX_TABLES];
2182
 
    JOIN_TAB **last_changed_tab= changed_tabs;
2183
 
    if (item->have_guarded_conds())
2184
 
    {
2185
 
      /*
2186
 
        For at least one of the pushed predicates the following is true:
2187
 
        We should not apply optimizations based on the condition that was
2188
 
        pushed down into the subquery. Those optimizations are ref[_or_null]
2189
 
        acceses. Change them to be full table scans.
2190
 
      */
2191
 
      for (uint i=join->const_tables ; i < join->tables ; i++)
2192
 
      {
2193
 
        JOIN_TAB *tab=join->join_tab+i;
2194
 
        if (tab && tab->keyuse)
2195
 
        {
2196
 
          for (uint i= 0; i < tab->ref.key_parts; i++)
2197
 
          {
2198
 
            bool *cond_guard= tab->ref.cond_guards[i];
2199
 
            if (cond_guard && !*cond_guard)
2200
 
            {
2201
 
              /* Change the access method to full table scan */
2202
 
              tab->save_read_first_record= tab->read_first_record;
2203
 
              tab->save_read_record= tab->read_record.read_record;
2204
 
              tab->read_first_record= init_read_record_seq;
2205
 
              tab->read_record.record= tab->table->record[0];
2206
 
              tab->read_record.thd= join->thd;
2207
 
              tab->read_record.ref_length= tab->table->file->ref_length;
2208
 
              *(last_changed_tab++)= tab;
2209
 
              break;
2210
 
            }
2211
 
          }
2212
 
        }
2213
 
      }
2214
 
    }
2215
 
    
2216
 
    join->exec();
2217
 
 
2218
 
    /* Enable the optimizations back */
2219
 
    for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
2220
 
    {
2221
 
      JOIN_TAB *tab= *ptab;
2222
 
      tab->read_record.record= 0;
2223
 
      tab->read_record.ref_length= 0;
2224
 
      tab->read_first_record= tab->save_read_first_record; 
2225
 
      tab->read_record.read_record= tab->save_read_record;
2226
 
    }
2227
 
    executed= 1;
2228
 
    thd->where= save_where;
2229
 
    thd->lex->current_select= save_select;
2230
 
    return(join->error||thd->is_fatal_error);
2231
 
  }
2232
 
  thd->where= save_where;
2233
 
  thd->lex->current_select= save_select;
2234
 
  return(0);
2235
 
}
2236
 
 
2237
 
int subselect_union_engine::exec()
2238
 
{
2239
 
  char const *save_where= thd->where;
2240
 
  int res= unit->exec();
2241
 
  thd->where= save_where;
2242
 
  return res;
2243
 
}
2244
 
 
2245
 
 
2246
 
/*
2247
 
  Search for at least one row satisfying select condition
2248
 
 
2249
 
  SYNOPSIS
2250
 
    subselect_uniquesubquery_engine::scan_table()
2251
 
 
2252
 
  DESCRIPTION
2253
 
    Scan the table using sequential access until we find at least one row
2254
 
    satisfying select condition.
2255
 
    
2256
 
    The caller must set this->empty_result_set=false before calling this
2257
 
    function. This function will set it to true if it finds a matching row.
2258
 
 
2259
 
  RETURN
2260
 
    false - OK
2261
 
    true  - Error
2262
 
*/
2263
 
 
2264
 
int subselect_uniquesubquery_engine::scan_table()
2265
 
{
2266
 
  int error;
2267
 
  TABLE *table= tab->table;
2268
 
 
2269
 
  if (table->file->inited)
2270
 
    table->file->ha_index_end();
2271
 
 
2272
 
  table->file->ha_rnd_init(1);
2273
 
  table->file->extra_opt(HA_EXTRA_CACHE,
2274
 
                         current_thd->variables.read_buff_size);
2275
 
  table->null_row= 0;
2276
 
  for (;;)
2277
 
  {
2278
 
    error=table->file->rnd_next(table->record[0]);
2279
 
    if (error && error != HA_ERR_END_OF_FILE)
2280
 
    {
2281
 
      error= report_error(table, error);
2282
 
      break;
2283
 
    }
2284
 
    /* No more rows */
2285
 
    if (table->status)
2286
 
      break;
2287
 
 
2288
 
    if (!cond || cond->val_int())
2289
 
    {
2290
 
      empty_result_set= false;
2291
 
      break;
2292
 
    }
2293
 
  }
2294
 
 
2295
 
  table->file->ha_rnd_end();
2296
 
  return(error != 0);
2297
 
}
2298
 
 
2299
 
 
2300
 
/*
2301
 
  Copy ref key and check for null parts in it
2302
 
 
2303
 
  SYNOPSIS
2304
 
    subselect_uniquesubquery_engine::copy_ref_key()
2305
 
 
2306
 
  DESCRIPTION
2307
 
    Copy ref key and check for null parts in it.
2308
 
    Depending on the nullability and conversion problems this function
2309
 
    recognizes and processes the following states :
2310
 
      1. Partial match on top level. This means IN has a value of false
2311
 
         regardless of the data in the subquery table.
2312
 
         Detected by finding a NULL in the left IN operand of a top level
2313
 
         expression.
2314
 
         We may actually skip reading the subquery, so return true to skip
2315
 
         the table scan in subselect_uniquesubquery_engine::exec and make
2316
 
         the value of the IN predicate a NULL (that is equal to false on
2317
 
         top level).
2318
 
      2. No exact match when IN is nested inside another predicate.
2319
 
         Detected by finding a NULL in the left IN operand when IN is not
2320
 
         a top level predicate.
2321
 
         We cannot have an exact match. But we must proceed further with a
2322
 
         table scan to find out if it's a partial match (and IN has a value
2323
 
         of NULL) or no match (and IN has a value of false).
2324
 
         So we return false to continue with the scan and see if there are
2325
 
         any record that would constitute a partial match (as we cannot
2326
 
         determine that from the index).
2327
 
      3. Error converting the left IN operand to the column type of the
2328
 
         right IN operand. This counts as no match (and IN has the value of
2329
 
         false). We mark the subquery table cursor as having no more rows
2330
 
         (to ensure that the processing that follows will not find a match)
2331
 
         and return false, so IN is not treated as returning NULL.
2332
 
 
2333
 
 
2334
 
  RETURN
2335
 
    false - The value of the IN predicate is not known. Proceed to find the
2336
 
            value of the IN predicate using the determined values of
2337
 
            null_keypart and table->status.
2338
 
    true  - IN predicate has a value of NULL. Stop the processing right there
2339
 
            and return NULL to the outer predicates.
2340
 
*/
2341
 
 
2342
 
bool subselect_uniquesubquery_engine::copy_ref_key()
2343
 
{
2344
 
  for (store_key **copy= tab->ref.key_copy ; *copy ; copy++)
2345
 
  {
2346
 
    enum store_key::store_key_result store_res;
2347
 
    store_res= (*copy)->copy();
2348
 
    tab->ref.key_err= store_res;
2349
 
 
2350
 
    /*
2351
 
      When there is a NULL part in the key we don't need to make index
2352
 
      lookup for such key thus we don't need to copy whole key.
2353
 
      If we later should do a sequential scan return OK. Fail otherwise.
2354
 
 
2355
 
      See also the comment for the subselect_uniquesubquery_engine::exec()
2356
 
      function.
2357
 
    */
2358
 
    null_keypart= (*copy)->null_key;
2359
 
    if (null_keypart)
2360
 
    {
2361
 
      bool top_level= ((Item_in_subselect *) item)->is_top_level_item();
2362
 
      if (top_level)
2363
 
      {
2364
 
        /* Partial match on top level */
2365
 
        return(1);
2366
 
      }
2367
 
      else
2368
 
      {
2369
 
        /* No exact match when IN is nested inside another predicate */
2370
 
        break;
2371
 
      }
2372
 
    }
2373
 
 
2374
 
    /*
2375
 
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed 
2376
 
      using the store_key::store_key_result enum because ref.key_err is a 
2377
 
      boolean and we want to detect both true and STORE_KEY_FATAL from the 
2378
 
      space of the union of the values of [true, false] and 
2379
 
      store_key::store_key_result.  
2380
 
      TODO: fix the variable an return types.
2381
 
    */
2382
 
    if (store_res == store_key::STORE_KEY_FATAL)
2383
 
    {
2384
 
      /*
2385
 
       Error converting the left IN operand to the column type of the right
2386
 
       IN operand. 
2387
 
      */
2388
 
      tab->table->status= STATUS_NOT_FOUND;
2389
 
      break;
2390
 
    }
2391
 
  }
2392
 
  return(0);
2393
 
}
2394
 
 
2395
 
 
2396
 
/*
2397
 
  Execute subselect
2398
 
 
2399
 
  SYNOPSIS
2400
 
    subselect_uniquesubquery_engine::exec()
2401
 
 
2402
 
  DESCRIPTION
2403
 
    Find rows corresponding to the ref key using index access.
2404
 
    If some part of the lookup key is NULL, then we're evaluating
2405
 
      NULL IN (SELECT ... )
2406
 
    This is a special case, we don't need to search for NULL in the table,
2407
 
    instead, the result value is 
2408
 
      - NULL  if select produces empty row set
2409
 
      - false otherwise.
2410
 
 
2411
 
    In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2412
 
    the caller doesn't distinguish between NULL and false result and we just
2413
 
    return false. 
2414
 
    Otherwise we make a full table scan to see if there is at least one 
2415
 
    matching row.
2416
 
    
2417
 
    The result of this function (info about whether a row was found) is
2418
 
    stored in this->empty_result_set.
2419
 
  NOTE
2420
 
    
2421
 
  RETURN
2422
 
    false - ok
2423
 
    true  - an error occured while scanning
2424
 
*/
2425
 
 
2426
 
int subselect_uniquesubquery_engine::exec()
2427
 
{
2428
 
  int error;
2429
 
  TABLE *table= tab->table;
2430
 
  empty_result_set= true;
2431
 
  table->status= 0;
2432
 
 
2433
 
  /* TODO: change to use of 'full_scan' here? */
2434
 
  if (copy_ref_key())
2435
 
    return(1);
2436
 
  if (table->status)
2437
 
  {
2438
 
    /* 
2439
 
      We know that there will be no rows even if we scan. 
2440
 
      Can be set in copy_ref_key.
2441
 
    */
2442
 
    ((Item_in_subselect *) item)->value= 0;
2443
 
    return(0);
2444
 
  }
2445
 
 
2446
 
  if (null_keypart)
2447
 
    return(scan_table());
2448
 
 
2449
 
  if (!table->file->inited)
2450
 
    table->file->ha_index_init(tab->ref.key, 0);
2451
 
  error= table->file->index_read_map(table->record[0],
2452
 
                                     tab->ref.key_buff,
2453
 
                                     make_prev_keypart_map(tab->ref.key_parts),
2454
 
                                     HA_READ_KEY_EXACT);
2455
 
  if (error &&
2456
 
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2457
 
    error= report_error(table, error);
2458
 
  else
2459
 
  {
2460
 
    error= 0;
2461
 
    table->null_row= 0;
2462
 
    if (!table->status && (!cond || cond->val_int()))
2463
 
    {
2464
 
      ((Item_in_subselect *) item)->value= 1;
2465
 
      empty_result_set= false;
2466
 
    }
2467
 
    else
2468
 
      ((Item_in_subselect *) item)->value= 0;
2469
 
  }
2470
 
 
2471
 
  return(error != 0);
2472
 
}
2473
 
 
2474
 
 
2475
 
/*
2476
 
  Index-lookup subselect 'engine' - run the subquery
2477
 
 
2478
 
  SYNOPSIS
2479
 
    subselect_indexsubquery_engine:exec()
2480
 
      full_scan 
2481
 
 
2482
 
  DESCRIPTION
2483
 
    The engine is used to resolve subqueries in form
2484
 
 
2485
 
      oe IN (SELECT key FROM tbl WHERE subq_where) 
2486
 
 
2487
 
    The value of the predicate is calculated as follows: 
2488
 
    1. If oe IS NULL, this is a special case, do a full table scan on
2489
 
       table tbl and search for row that satisfies subq_where. If such 
2490
 
       row is found, return NULL, otherwise return false.
2491
 
    2. Make an index lookup via key=oe, search for a row that satisfies
2492
 
       subq_where. If found, return true.
2493
 
    3. If check_null==true, make another lookup via key=NULL, search for a 
2494
 
       row that satisfies subq_where. If found, return NULL, otherwise
2495
 
       return false.
2496
 
 
2497
 
  TODO
2498
 
    The step #1 can be optimized further when the index has several key
2499
 
    parts. Consider a subquery:
2500
 
    
2501
 
      (oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2502
 
 
2503
 
    and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2504
 
    Current code will do a full table scan and obtain correct result. There
2505
 
    is a better option: instead of evaluating
2506
 
 
2507
 
      SELECT keypart1, keypart2 FROM tbl WHERE subq_where            (1)
2508
 
 
2509
 
    and checking if it has produced any matching rows, evaluate
2510
 
    
2511
 
      SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1  (2)
2512
 
 
2513
 
    If this query produces a row, the result is NULL (as we're evaluating 
2514
 
    "(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2515
 
    i.e. NULL).  If the query produces no rows, the result is false.
2516
 
 
2517
 
    We currently evaluate (1) by doing a full table scan. (2) can be
2518
 
    evaluated by doing a "ref" scan on "keypart1=const1", which can be much
2519
 
    cheaper. We can use index statistics to quickly check whether "ref" scan
2520
 
    will be cheaper than full table scan.
2521
 
 
2522
 
  RETURN
2523
 
    0
2524
 
    1
2525
 
*/
2526
 
 
2527
 
int subselect_indexsubquery_engine::exec()
2528
 
{
2529
 
  int error;
2530
 
  bool null_finding= 0;
2531
 
  TABLE *table= tab->table;
2532
 
 
2533
 
  ((Item_in_subselect *) item)->value= 0;
2534
 
  empty_result_set= true;
2535
 
  null_keypart= 0;
2536
 
  table->status= 0;
2537
 
 
2538
 
  if (check_null)
2539
 
  {
2540
 
    /* We need to check for NULL if there wasn't a matching value */
2541
 
    *tab->ref.null_ref_key= 0;                  // Search first for not null
2542
 
    ((Item_in_subselect *) item)->was_null= 0;
2543
 
  }
2544
 
 
2545
 
  /* Copy the ref key and check for nulls... */
2546
 
  if (copy_ref_key())
2547
 
    return(1);
2548
 
 
2549
 
  if (table->status)
2550
 
  {
2551
 
    /* 
2552
 
      We know that there will be no rows even if we scan. 
2553
 
      Can be set in copy_ref_key.
2554
 
    */
2555
 
    ((Item_in_subselect *) item)->value= 0;
2556
 
    return(0);
2557
 
  }
2558
 
 
2559
 
  if (null_keypart)
2560
 
    return(scan_table());
2561
 
 
2562
 
  if (!table->file->inited)
2563
 
    table->file->ha_index_init(tab->ref.key, 1);
2564
 
  error= table->file->index_read_map(table->record[0],
2565
 
                                     tab->ref.key_buff,
2566
 
                                     make_prev_keypart_map(tab->ref.key_parts),
2567
 
                                     HA_READ_KEY_EXACT);
2568
 
  if (error &&
2569
 
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2570
 
    error= report_error(table, error);
2571
 
  else
2572
 
  {
2573
 
    for (;;)
2574
 
    {
2575
 
      error= 0;
2576
 
      table->null_row= 0;
2577
 
      if (!table->status)
2578
 
      {
2579
 
        if ((!cond || cond->val_int()) && (!having || having->val_int()))
2580
 
        {
2581
 
          empty_result_set= false;
2582
 
          if (null_finding)
2583
 
            ((Item_in_subselect *) item)->was_null= 1;
2584
 
          else
2585
 
            ((Item_in_subselect *) item)->value= 1;
2586
 
          break;
2587
 
        }
2588
 
        error= table->file->index_next_same(table->record[0],
2589
 
                                            tab->ref.key_buff,
2590
 
                                            tab->ref.key_length);
2591
 
        if (error && error != HA_ERR_END_OF_FILE)
2592
 
        {
2593
 
          error= report_error(table, error);
2594
 
          break;
2595
 
        }
2596
 
      }
2597
 
      else
2598
 
      {
2599
 
        if (!check_null || null_finding)
2600
 
          break;                        /* We don't need to check nulls */
2601
 
        *tab->ref.null_ref_key= 1;
2602
 
        null_finding= 1;
2603
 
        /* Check if there exists a row with a null value in the index */
2604
 
        if ((error= (safe_index_read(tab) == 1)))
2605
 
          break;
2606
 
      }
2607
 
    }
2608
 
  }
2609
 
  return(error != 0);
2610
 
}
2611
 
 
2612
 
 
2613
 
uint subselect_single_select_engine::cols()
2614
 
{
2615
 
  return select_lex->item_list.elements;
2616
 
}
2617
 
 
2618
 
 
2619
 
uint subselect_union_engine::cols()
2620
 
{
2621
 
  return unit->types.elements;
2622
 
}
2623
 
 
2624
 
 
2625
 
uint8 subselect_single_select_engine::uncacheable()
2626
 
{
2627
 
  return select_lex->uncacheable;
2628
 
}
2629
 
 
2630
 
 
2631
 
uint8 subselect_union_engine::uncacheable()
2632
 
{
2633
 
  return unit->uncacheable;
2634
 
}
2635
 
 
2636
 
 
2637
 
void subselect_single_select_engine::exclude()
2638
 
{
2639
 
  select_lex->master_unit()->exclude_level();
2640
 
}
2641
 
 
2642
 
void subselect_union_engine::exclude()
2643
 
{
2644
 
  unit->exclude_level();
2645
 
}
2646
 
 
2647
 
 
2648
 
void subselect_uniquesubquery_engine::exclude()
2649
 
{
2650
 
  //this never should be called
2651
 
  assert(0);
2652
 
}
2653
 
 
2654
 
 
2655
 
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
2656
 
{
2657
 
  table_map map= 0;
2658
 
  for (; table; table= table->next_leaf)
2659
 
  {
2660
 
    TABLE *tbl= table->table;
2661
 
    if (tbl && tbl->const_table)
2662
 
      map|= tbl->map;
2663
 
  }
2664
 
  return map;
2665
 
}
2666
 
 
2667
 
 
2668
 
table_map subselect_single_select_engine::upper_select_const_tables()
2669
 
{
2670
 
  return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
2671
 
                           leaf_tables);
2672
 
}
2673
 
 
2674
 
 
2675
 
table_map subselect_union_engine::upper_select_const_tables()
2676
 
{
2677
 
  return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
2678
 
}
2679
 
 
2680
 
 
2681
 
void subselect_single_select_engine::print(String *str,
2682
 
                                           enum_query_type query_type)
2683
 
{
2684
 
  select_lex->print(thd, str, query_type);
2685
 
}
2686
 
 
2687
 
 
2688
 
void subselect_union_engine::print(String *str, enum_query_type query_type)
2689
 
{
2690
 
  unit->print(str, query_type);
2691
 
}
2692
 
 
2693
 
 
2694
 
void subselect_uniquesubquery_engine::print(String *str,
2695
 
                                            enum_query_type query_type)
2696
 
{
2697
 
  char *table_name= tab->table->s->table_name.str;
2698
 
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2699
 
  tab->ref.items[0]->print(str, query_type);
2700
 
  str->append(STRING_WITH_LEN(" in "));
2701
 
  if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY)
2702
 
  {
2703
 
    /*
2704
 
      Temporary tables' names change across runs, so they can't be used for
2705
 
      EXPLAIN EXTENDED.
2706
 
    */
2707
 
    str->append(STRING_WITH_LEN("<temporary table>"));
2708
 
  }
2709
 
  else
2710
 
    str->append(table_name, tab->table->s->table_name.length);
2711
 
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2712
 
  str->append(STRING_WITH_LEN(" on "));
2713
 
  str->append(key_info->name);
2714
 
  if (cond)
2715
 
  {
2716
 
    str->append(STRING_WITH_LEN(" where "));
2717
 
    cond->print(str, query_type);
2718
 
  }
2719
 
  str->append(')');
2720
 
}
2721
 
 
2722
 
/*
2723
 
TODO:
2724
 
The above ::print method should be changed as below. Do it after
2725
 
all other tests pass.
2726
 
 
2727
 
void subselect_uniquesubquery_engine::print(String *str)
2728
 
{
2729
 
  KEY *key_info= tab->table->key_info + tab->ref.key;
2730
 
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2731
 
  for (uint i= 0; i < key_info->key_parts; i++)
2732
 
    tab->ref.items[i]->print(str);
2733
 
  str->append(STRING_WITH_LEN(" in "));
2734
 
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2735
 
  str->append(STRING_WITH_LEN(" on "));
2736
 
  str->append(key_info->name);
2737
 
  if (cond)
2738
 
  {
2739
 
    str->append(STRING_WITH_LEN(" where "));
2740
 
    cond->print(str);
2741
 
  }
2742
 
  str->append(')');
2743
 
}
2744
 
*/
2745
 
 
2746
 
void subselect_indexsubquery_engine::print(String *str,
2747
 
                                           enum_query_type query_type)
2748
 
{
2749
 
  str->append(STRING_WITH_LEN("<index_lookup>("));
2750
 
  tab->ref.items[0]->print(str, query_type);
2751
 
  str->append(STRING_WITH_LEN(" in "));
2752
 
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2753
 
  KEY *key_info= tab->table->key_info+ tab->ref.key;
2754
 
  str->append(STRING_WITH_LEN(" on "));
2755
 
  str->append(key_info->name);
2756
 
  if (check_null)
2757
 
    str->append(STRING_WITH_LEN(" checking NULL"));
2758
 
  if (cond)
2759
 
  {
2760
 
    str->append(STRING_WITH_LEN(" where "));
2761
 
    cond->print(str, query_type);
2762
 
  }
2763
 
  if (having)
2764
 
  {
2765
 
    str->append(STRING_WITH_LEN(" having "));
2766
 
    having->print(str, query_type);
2767
 
  }
2768
 
  str->append(')');
2769
 
}
2770
 
 
2771
 
/**
2772
 
  change select_result object of engine.
2773
 
 
2774
 
  @param si             new subselect Item
2775
 
  @param res            new select_result object
2776
 
 
2777
 
  @retval
2778
 
    false OK
2779
 
  @retval
2780
 
    true  error
2781
 
*/
2782
 
 
2783
 
bool subselect_single_select_engine::change_result(Item_subselect *si,
2784
 
                                                 select_result_interceptor *res)
2785
 
{
2786
 
  item= si;
2787
 
  result= res;
2788
 
  return select_lex->join->change_result(result);
2789
 
}
2790
 
 
2791
 
 
2792
 
/**
2793
 
  change select_result object of engine.
2794
 
 
2795
 
  @param si             new subselect Item
2796
 
  @param res            new select_result object
2797
 
 
2798
 
  @retval
2799
 
    false OK
2800
 
  @retval
2801
 
    true  error
2802
 
*/
2803
 
 
2804
 
bool subselect_union_engine::change_result(Item_subselect *si,
2805
 
                                           select_result_interceptor *res)
2806
 
{
2807
 
  item= si;
2808
 
  int rc= unit->change_result(res, result);
2809
 
  result= res;
2810
 
  return rc;
2811
 
}
2812
 
 
2813
 
 
2814
 
/**
2815
 
  change select_result emulation, never should be called.
2816
 
 
2817
 
  @param si             new subselect Item
2818
 
  @param res            new select_result object
2819
 
 
2820
 
  @retval
2821
 
    false OK
2822
 
  @retval
2823
 
    true  error
2824
 
*/
2825
 
 
2826
 
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((__unused__)),
2827
 
                                                    select_result_interceptor *res __attribute__((__unused__)))
2828
 
{
2829
 
  assert(0);
2830
 
  return true;
2831
 
}
2832
 
 
2833
 
 
2834
 
/**
2835
 
  Report about presence of tables in subquery.
2836
 
 
2837
 
  @retval
2838
 
    true  there are not tables used in subquery
2839
 
  @retval
2840
 
    false there are some tables in subquery
2841
 
*/
2842
 
bool subselect_single_select_engine::no_tables()
2843
 
{
2844
 
  return(select_lex->table_list.elements == 0);
2845
 
}
2846
 
 
2847
 
 
2848
 
/*
2849
 
  Check statically whether the subquery can return NULL
2850
 
 
2851
 
  SINOPSYS
2852
 
    subselect_single_select_engine::may_be_null()
2853
 
 
2854
 
  RETURN
2855
 
    false  can guarantee that the subquery never return NULL
2856
 
    true   otherwise
2857
 
*/
2858
 
bool subselect_single_select_engine::may_be_null()
2859
 
{
2860
 
  return ((no_tables() && !join->conds && !join->having) ? maybe_null : 1);
2861
 
}
2862
 
 
2863
 
 
2864
 
/**
2865
 
  Report about presence of tables in subquery.
2866
 
 
2867
 
  @retval
2868
 
    true  there are not tables used in subquery
2869
 
  @retval
2870
 
    false there are some tables in subquery
2871
 
*/
2872
 
bool subselect_union_engine::no_tables()
2873
 
{
2874
 
  for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
2875
 
  {
2876
 
    if (sl->table_list.elements)
2877
 
      return false;
2878
 
  }
2879
 
  return true;
2880
 
}
2881
 
 
2882
 
 
2883
 
/**
2884
 
  Report about presence of tables in subquery.
2885
 
 
2886
 
  @retval
2887
 
    true  there are not tables used in subquery
2888
 
  @retval
2889
 
    false there are some tables in subquery
2890
 
*/
2891
 
 
2892
 
bool subselect_uniquesubquery_engine::no_tables()
2893
 
{
2894
 
  /* returning value is correct, but this method should never be called */
2895
 
  return 0;
2896
 
}
2897
 
 
2898
 
 
2899
 
/******************************************************************************
2900
 
  WL#1110 - Implementation of class subselect_hash_sj_engine
2901
 
******************************************************************************/
2902
 
 
2903
 
 
2904
 
/**
2905
 
  Create all structures needed for IN execution that can live between PS
2906
 
  reexecution.
2907
 
 
2908
 
  @detail
2909
 
  - Create a temporary table to store the result of the IN subquery. The
2910
 
    temporary table has one hash index on all its columns.
2911
 
  - Create a new result sink that sends the result stream of the subquery to
2912
 
    the temporary table,
2913
 
  - Create and initialize a new JOIN_TAB, and TABLE_REF objects to perform
2914
 
    lookups into the indexed temporary table.
2915
 
 
2916
 
  @notice:
2917
 
    Currently Item_subselect::init() already chooses and creates at parse
2918
 
    time an engine with a corresponding JOIN to execute the subquery.
2919
 
 
2920
 
  @retval true  if error
2921
 
  @retval false otherwise
2922
 
*/
2923
 
 
2924
 
bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns)
2925
 
{
2926
 
  /* The result sink where we will materialize the subquery result. */
2927
 
  select_union  *tmp_result_sink;
2928
 
  /* The table into which the subquery is materialized. */
2929
 
  TABLE         *tmp_table;
2930
 
  KEY           *tmp_key; /* The only index on the temporary table. */
2931
 
  uint          tmp_key_parts; /* Number of keyparts in tmp_key. */
2932
 
  Item_in_subselect *item_in= (Item_in_subselect *) item;
2933
 
 
2934
 
  /* 1. Create/initialize materialization related objects. */
2935
 
 
2936
 
  /*
2937
 
    Create and initialize a select result interceptor that stores the
2938
 
    result stream in a temporary table. The temporary table itself is
2939
 
    managed (created/filled/etc) internally by the interceptor.
2940
 
  */
2941
 
  if (!(tmp_result_sink= new select_union))
2942
 
    return(true);
2943
 
  if (tmp_result_sink->create_result_table(
2944
 
                         thd, tmp_columns, true,
2945
 
                         thd->options | TMP_TABLE_ALL_COLUMNS,
2946
 
                         "materialized subselect", true))
2947
 
    return(true);
2948
 
 
2949
 
  tmp_table= tmp_result_sink->table;
2950
 
  tmp_key= tmp_table->key_info;
2951
 
  tmp_key_parts= tmp_key->key_parts;
2952
 
 
2953
 
  /*
2954
 
     If the subquery has blobs, or the total key lenght is bigger than some
2955
 
     length, then the created index cannot be used for lookups and we
2956
 
     can't use hash semi join. If this is the case, delete the temporary
2957
 
     table since it will not be used, and tell the caller we failed to
2958
 
     initialize the engine.
2959
 
  */
2960
 
  if (tmp_table->s->keys == 0)
2961
 
  {
2962
 
    assert(tmp_table->s->db_type() == myisam_hton);
2963
 
    assert(
2964
 
      tmp_table->s->uniques ||
2965
 
      tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2966
 
      tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2967
 
    free_tmp_table(thd, tmp_table);
2968
 
    delete result;
2969
 
    result= NULL;
2970
 
    return(true);
2971
 
  }
2972
 
  result= tmp_result_sink;
2973
 
 
2974
 
  /*
2975
 
    Make sure there is only one index on the temp table, and it doesn't have
2976
 
    the extra key part created when s->uniques > 0.
2977
 
  */
2978
 
  assert(tmp_table->s->keys == 1 && tmp_columns->elements == tmp_key_parts);
2979
 
 
2980
 
 
2981
 
  /* 2. Create/initialize execution related objects. */
2982
 
 
2983
 
  /*
2984
 
    Create and initialize the JOIN_TAB that represents an index lookup
2985
 
    plan operator into the materialized subquery result. Notice that:
2986
 
    - this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
2987
 
    - here we initialize only those members that are used by
2988
 
      subselect_uniquesubquery_engine, so these objects are incomplete.
2989
 
  */ 
2990
 
  if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
2991
 
    return(true);
2992
 
  tab->table= tmp_table;
2993
 
  tab->ref.key= 0; /* The only temp table index. */
2994
 
  tab->ref.key_length= tmp_key->key_length;
2995
 
  if (!(tab->ref.key_buff=
2996
 
        (uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
2997
 
      !(tab->ref.key_copy=
2998
 
        (store_key**) thd->alloc((sizeof(store_key*) *
2999
 
                                  (tmp_key_parts + 1)))) ||
3000
 
      !(tab->ref.items=
3001
 
        (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
3002
 
    return(true);
3003
 
 
3004
 
  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3005
 
  store_key **ref_key= tab->ref.key_copy;
3006
 
  uchar *cur_ref_buff= tab->ref.key_buff;
3007
 
  
3008
 
  for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3009
 
  {
3010
 
    tab->ref.items[i]= item_in->left_expr->element_index(i);
3011
 
    int null_count= test(cur_key_part->field->real_maybe_null());
3012
 
    *ref_key= new store_key_item(thd, cur_key_part->field,
3013
 
                                 /* TODO:
3014
 
                                    the NULL byte is taken into account in
3015
 
                                    cur_key_part->store_length, so instead of
3016
 
                                    cur_ref_buff + test(maybe_null), we could
3017
 
                                    use that information instead.
3018
 
                                 */
3019
 
                                 cur_ref_buff + null_count,
3020
 
                                 null_count ? tab->ref.key_buff : 0,
3021
 
                                 cur_key_part->length, tab->ref.items[i]);
3022
 
    cur_ref_buff+= cur_key_part->store_length;
3023
 
  }
3024
 
  *ref_key= NULL; /* End marker. */
3025
 
  tab->ref.key_err= 1;
3026
 
  tab->ref.key_parts= tmp_key_parts;
3027
 
 
3028
 
  return(false);
3029
 
}
3030
 
 
3031
 
 
3032
 
/**
3033
 
  Initialize members of the engine that need to be re-initilized at each
3034
 
  execution.
3035
 
 
3036
 
  @retval true  if a memory allocation error occurred
3037
 
  @retval false if success
3038
 
*/
3039
 
 
3040
 
bool subselect_hash_sj_engine::init_runtime()
3041
 
{
3042
 
  /*
3043
 
    Create and optimize the JOIN that will be used to materialize
3044
 
    the subquery if not yet created.
3045
 
  */
3046
 
  materialize_engine->prepare();
3047
 
  /* Let our engine reuse this query plan for materialization. */
3048
 
  materialize_join= materialize_engine->join;
3049
 
  materialize_join->change_result(result);
3050
 
  return false;
3051
 
}
3052
 
 
3053
 
 
3054
 
subselect_hash_sj_engine::~subselect_hash_sj_engine()
3055
 
{
3056
 
  delete result;
3057
 
  if (tab)
3058
 
    free_tmp_table(thd, tab->table);
3059
 
}
3060
 
 
3061
 
 
3062
 
/**
3063
 
  Cleanup performed after each PS execution.
3064
 
 
3065
 
  @detail
3066
 
  Called in the end of JOIN::prepare for PS from Item_subselect::cleanup.
3067
 
*/
3068
 
 
3069
 
void subselect_hash_sj_engine::cleanup()
3070
 
{
3071
 
  is_materialized= false;
3072
 
  result->cleanup(); /* Resets the temp table as well. */
3073
 
  materialize_engine->cleanup();
3074
 
  subselect_uniquesubquery_engine::cleanup();
3075
 
}
3076
 
 
3077
 
 
3078
 
/**
3079
 
  Execute a subquery IN predicate via materialization.
3080
 
 
3081
 
  @detail
3082
 
  If needed materialize the subquery into a temporary table, then
3083
 
  copmpute the predicate via a lookup into this table.
3084
 
 
3085
 
  @retval true  if error
3086
 
  @retval false otherwise
3087
 
*/
3088
 
 
3089
 
int subselect_hash_sj_engine::exec()
3090
 
{
3091
 
  Item_in_subselect *item_in= (Item_in_subselect *) item;
3092
 
 
3093
 
  /*
3094
 
    Optimize and materialize the subquery during the first execution of
3095
 
    the subquery predicate.
3096
 
  */
3097
 
  if (!is_materialized)
3098
 
  {
3099
 
    int res= 0;
3100
 
    SELECT_LEX *save_select= thd->lex->current_select;
3101
 
    thd->lex->current_select= materialize_engine->select_lex;
3102
 
    if ((res= materialize_join->optimize()))
3103
 
      goto err;
3104
 
    materialize_join->exec();
3105
 
    if ((res= test(materialize_join->error || thd->is_fatal_error)))
3106
 
      goto err;
3107
 
 
3108
 
    /*
3109
 
      TODO:
3110
 
      - Unlock all subquery tables as we don't need them. To implement this
3111
 
        we need to add new functionality to JOIN::join_free that can unlock
3112
 
        all tables in a subquery (and all its subqueries).
3113
 
      - The temp table used for grouping in the subquery can be freed
3114
 
        immediately after materialization (yet it's done together with
3115
 
        unlocking).
3116
 
     */
3117
 
    is_materialized= true;
3118
 
    /*
3119
 
      If the subquery returned no rows, the temporary table is empty, so we know
3120
 
      directly that the result of IN is false. We first update the table
3121
 
      statistics, then we test if the temporary table for the query result is
3122
 
      empty.
3123
 
    */
3124
 
    tab->table->file->info(HA_STATUS_VARIABLE);
3125
 
    if (!tab->table->file->stats.records)
3126
 
    {
3127
 
      empty_result_set= true;
3128
 
      item_in->value= false;
3129
 
      /* TODO: check we need this: item_in->null_value= false; */
3130
 
      return(false);
3131
 
    }
3132
 
    /* Set tmp_param only if its usable, i.e. tmp_param->copy_field != NULL. */
3133
 
    tmp_param= &(item_in->unit->outer_select()->join->tmp_table_param);
3134
 
    if (tmp_param && !tmp_param->copy_field)
3135
 
      tmp_param= NULL;
3136
 
 
3137
 
err:
3138
 
    thd->lex->current_select= save_select;
3139
 
    if (res)
3140
 
      return(res);
3141
 
  }
3142
 
 
3143
 
  /*
3144
 
    Lookup the left IN operand in the hash index of the materialized subquery.
3145
 
  */
3146
 
  return(subselect_uniquesubquery_engine::exec());
3147
 
}
3148
 
 
3149
 
 
3150
 
/**
3151
 
  Print the state of this engine into a string for debugging and views.
3152
 
*/
3153
 
 
3154
 
void subselect_hash_sj_engine::print(String *str, enum_query_type query_type)
3155
 
{
3156
 
  str->append(STRING_WITH_LEN(" <materialize> ("));
3157
 
  materialize_engine->print(str, query_type);
3158
 
  str->append(STRING_WITH_LEN(" ), "));
3159
 
  if (tab)
3160
 
    subselect_uniquesubquery_engine::print(str, query_type);
3161
 
  else
3162
 
    str->append(STRING_WITH_LEN(
3163
 
           "<the access method for lookups is not yet created>"
3164
 
         ));
3165
 
}