~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/item_subselect.cc

  • Committer: brian
  • Date: 2008-07-03 13:40:21 UTC
  • Revision ID: brian@localhost.localdomain-20080703134021-7p4ab3xpjpmbcebi
Update for using real bool types.

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
  Item_result_field(), value_assigned(0), thd(0), substitution(0),
41
41
  engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
42
42
  const_item_cache(1), engine_changed(0), changed(0),
43
 
  is_correlated(FALSE)
 
43
  is_correlated(false)
44
44
{
45
45
  with_subselect= 1;
46
46
  reset();
141
141
    delete left_expr_cache;
142
142
    left_expr_cache= NULL;
143
143
  }
144
 
  first_execution= TRUE;
 
144
  first_execution= true;
145
145
  Item_subselect::cleanup();
146
146
  DBUG_VOID_RETURN;
147
147
}
169
169
  engine->set_thd((thd= thd_param));
170
170
 
171
171
  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
172
 
    return TRUE;
 
172
    return true;
173
173
 
174
174
  res= engine->prepare();
175
175
 
209
209
    if (engine->cols() > max_columns)
210
210
    {
211
211
      my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
212
 
      return TRUE;
 
212
      return true;
213
213
    }
214
214
    fix_length_and_dec();
215
215
  }
318
318
  {
319
319
    /* Always compute IN for the first row as the cache is not valid for it. */
320
320
    if (!first_execution)
321
 
      DBUG_RETURN(FALSE);
322
 
    first_execution= FALSE;
 
321
      DBUG_RETURN(false);
 
322
    first_execution= false;
323
323
  }
324
324
 
325
325
  /*
414
414
                                             Item_subselect *parent,
415
415
                                             st_select_lex *select_lex,
416
416
                                             bool max_arg)
417
 
  :Item_singlerow_subselect(), was_values(TRUE)
 
417
  :Item_singlerow_subselect(), was_values(true)
418
418
{
419
419
  DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
420
420
  max= max_arg;
445
445
  Item_singlerow_subselect::cleanup();
446
446
 
447
447
  /*
448
 
    By default it is TRUE to avoid TRUE reporting by
 
448
    By default it is true to avoid true reporting by
449
449
    Item_func_not_all/Item_func_nop_all if this item was never called.
450
450
 
451
 
    Engine exec() set it to FALSE by reset_value_registration() call.
452
 
    select_max_min_finder_subselect::send_data() set it back to TRUE if some
 
451
    Engine exec() set it to false by reset_value_registration() call.
 
452
    select_max_min_finder_subselect::send_data() set it back to true if some
453
453
    value will be found.
454
454
  */
455
 
  was_values= TRUE;
 
455
  was_values= true;
456
456
  DBUG_VOID_RETURN;
457
457
}
458
458
 
714
714
 
715
715
Item_in_subselect::Item_in_subselect(Item * left_exp,
716
716
                                     st_select_lex *select_lex):
717
 
  Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
 
717
  Item_exists_subselect(), left_expr_cache(0), first_execution(true),
718
718
  optimizer(0), pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED),
719
719
  upper_item(0)
720
720
{
894
894
    reset();
895
895
    /* 
896
896
      Must mark the IN predicate as NULL so as to make sure an enclosing NOT
897
 
      predicate will return FALSE. See the comments in 
 
897
      predicate will return false. See the comments in 
898
898
      subselect_uniquesubquery_engine::copy_ref_key for further details.
899
899
    */
900
900
    null_value= 1;
1093
1093
  {
1094
1094
    if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
1095
1095
      DBUG_RETURN(RES_ERROR);
1096
 
    pushed_cond_guards[0]= TRUE;
 
1096
    pushed_cond_guards[0]= true;
1097
1097
  }
1098
1098
 
1099
1099
  /*
1120
1120
                               trigcond(oe $cmp$ ref_or_null_helper<ie>)
1121
1121
                                   
1122
1122
    the addition is wrapped into trigger only when we want to distinguish
1123
 
    between NULL and FALSE results.
 
1123
    between NULL and false results.
1124
1124
 
1125
1125
  - Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
1126
1126
    following:
1127
1127
 
1128
 
    = If we don't need to distinguish between NULL and FALSE subquery:
 
1128
    = If we don't need to distinguish between NULL and false subquery:
1129
1129
        
1130
1130
      SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
1131
1131
 
1235
1235
      }
1236
1236
      /* 
1237
1237
        If we may encounter NULL IN (SELECT ...) and care whether subquery
1238
 
        result is NULL or FALSE, wrap condition in a trig_cond.
 
1238
        result is NULL or false, wrap condition in a trig_cond.
1239
1239
      */
1240
1240
      if (!abort_on_null && left_expr->maybe_null)
1241
1241
      {
1366
1366
                                                        left_expr->cols())))
1367
1367
        DBUG_RETURN(RES_ERROR);
1368
1368
      for (uint i= 0; i < cols_num; i++)
1369
 
        pushed_cond_guards[i]= TRUE;
 
1369
        pushed_cond_guards[i]= true;
1370
1370
    }
1371
1371
  }
1372
1372
 
1759
1759
    execution.
1760
1760
 
1761
1761
  @returns
1762
 
    @retval TRUE  memory allocation error occurred
1763
 
    @retval FALSE an execution method was chosen successfully
 
1762
    @retval true  memory allocation error occurred
 
1763
    @retval false an execution method was chosen successfully
1764
1764
*/
1765
1765
 
1766
1766
bool Item_in_subselect::setup_engine()
1767
1767
{
1768
1768
  subselect_hash_sj_engine *new_engine= NULL;
1769
 
  bool res= FALSE;
 
1769
  bool res= false;
1770
1770
 
1771
1771
  DBUG_ENTER("Item_in_subselect::setup_engine");
1772
1772
 
1833
1833
  but it takes a different kind of collection of items, and the
1834
1834
  list we push to is dynamically allocated.
1835
1835
 
1836
 
  @retval TRUE  if a memory allocation error occurred or the cache is
 
1836
  @retval true  if a memory allocation error occurred or the cache is
1837
1837
                not applicable to the current query
1838
 
  @retval FALSE if success
 
1838
  @retval false if success
1839
1839
*/
1840
1840
 
1841
1841
bool Item_in_subselect::init_left_expr_cache()
1842
1842
{
1843
1843
  JOIN *outer_join;
1844
1844
  Next_select_func end_select;
1845
 
  bool use_result_field= FALSE;
 
1845
  bool use_result_field= false;
1846
1846
 
1847
1847
  outer_join= unit->outer_select()->join;
1848
1848
  if (!outer_join || !outer_join->tables)
1849
 
    return TRUE;
 
1849
    return true;
1850
1850
  /*
1851
1851
    If we use end_[send | write]_group to handle complete rows of the outer
1852
1852
    query, make the cache of the left IN operand use Item_field::result_field
1858
1858
  */
1859
1859
  end_select= outer_join->join_tab[outer_join->tables-1].next_select;
1860
1860
  if (end_select == end_send_group || end_select == end_write_group)
1861
 
    use_result_field= TRUE;
 
1861
    use_result_field= true;
1862
1862
 
1863
1863
  if (!(left_expr_cache= new List<Cached_item>))
1864
 
    return TRUE;
 
1864
    return true;
1865
1865
 
1866
1866
  for (uint i= 0; i < left_expr->cols(); i++)
1867
1867
  {
1869
1869
                                                 left_expr->element_index(i),
1870
1870
                                                 use_result_field);
1871
1871
    if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
1872
 
      return TRUE;
 
1872
      return true;
1873
1873
  }
1874
 
  return FALSE;
 
1874
  return false;
1875
1875
}
1876
1876
 
1877
1877
 
1884
1884
    make_cond_for_table() in such a way that it is unchanged when we use
1885
1885
    the IN=>EXISTS transformation to compute IN.
1886
1886
 
1887
 
  @retval TRUE  if the predicate is expensive
1888
 
  @retval FALSE otherwise
 
1887
  @retval true  if the predicate is expensive
 
1888
  @retval false otherwise
1889
1889
*/
1890
1890
 
1891
1891
bool Item_in_subselect::is_expensive_processor(uchar *arg)
1975
1975
    return value is undefined if last execution ended in an error.
1976
1976
 
1977
1977
  RETURN
1978
 
    TRUE  - Last subselect execution has produced no rows
1979
 
    FALSE - Otherwise
 
1978
    true  - Last subselect execution has produced no rows
 
1979
    false - Otherwise
1980
1980
*/
1981
1981
 
1982
1982
bool subselect_union_engine::no_rows()
2067
2067
int subselect_uniquesubquery_engine::prepare()
2068
2068
{
2069
2069
  /* Should never be called. */
2070
 
  DBUG_ASSERT(FALSE);
 
2070
  DBUG_ASSERT(false);
2071
2071
  return 1;
2072
2072
}
2073
2073
 
2083
2083
    return value is undefined if last execution ended in an error.
2084
2084
 
2085
2085
  RETURN
2086
 
    TRUE  - Last subselect execution has produced no rows
2087
 
    FALSE - Otherwise
 
2086
    true  - Last subselect execution has produced no rows
 
2087
    false - Otherwise
2088
2088
*/
2089
2089
 
2090
2090
bool subselect_single_select_engine::no_rows()
2168
2168
    unit->set_limit(unit->global_parameters);
2169
2169
    if (join->flatten_subqueries())
2170
2170
    {
2171
 
      thd->is_fatal_error= TRUE;
 
2171
      thd->is_fatal_error= true;
2172
2172
      DBUG_RETURN(1);
2173
2173
    }
2174
2174
    if (join->optimize())
2289
2289
    Scan the table using sequential access until we find at least one row
2290
2290
    satisfying select condition.
2291
2291
    
2292
 
    The caller must set this->empty_result_set=FALSE before calling this
2293
 
    function. This function will set it to TRUE if it finds a matching row.
 
2292
    The caller must set this->empty_result_set=false before calling this
 
2293
    function. This function will set it to true if it finds a matching row.
2294
2294
 
2295
2295
  RETURN
2296
 
    FALSE - OK
2297
 
    TRUE  - Error
 
2296
    false - OK
 
2297
    true  - Error
2298
2298
*/
2299
2299
 
2300
2300
int subselect_uniquesubquery_engine::scan_table()
2324
2324
 
2325
2325
    if (!cond || cond->val_int())
2326
2326
    {
2327
 
      empty_result_set= FALSE;
 
2327
      empty_result_set= false;
2328
2328
      break;
2329
2329
    }
2330
2330
  }
2344
2344
    Copy ref key and check for null parts in it.
2345
2345
    Depending on the nullability and conversion problems this function
2346
2346
    recognizes and processes the following states :
2347
 
      1. Partial match on top level. This means IN has a value of FALSE
 
2347
      1. Partial match on top level. This means IN has a value of false
2348
2348
         regardless of the data in the subquery table.
2349
2349
         Detected by finding a NULL in the left IN operand of a top level
2350
2350
         expression.
2351
 
         We may actually skip reading the subquery, so return TRUE to skip
 
2351
         We may actually skip reading the subquery, so return true to skip
2352
2352
         the table scan in subselect_uniquesubquery_engine::exec and make
2353
 
         the value of the IN predicate a NULL (that is equal to FALSE on
 
2353
         the value of the IN predicate a NULL (that is equal to false on
2354
2354
         top level).
2355
2355
      2. No exact match when IN is nested inside another predicate.
2356
2356
         Detected by finding a NULL in the left IN operand when IN is not
2357
2357
         a top level predicate.
2358
2358
         We cannot have an exact match. But we must proceed further with a
2359
2359
         table scan to find out if it's a partial match (and IN has a value
2360
 
         of NULL) or no match (and IN has a value of FALSE).
2361
 
         So we return FALSE to continue with the scan and see if there are
 
2360
         of NULL) or no match (and IN has a value of false).
 
2361
         So we return false to continue with the scan and see if there are
2362
2362
         any record that would constitute a partial match (as we cannot
2363
2363
         determine that from the index).
2364
2364
      3. Error converting the left IN operand to the column type of the
2365
2365
         right IN operand. This counts as no match (and IN has the value of
2366
 
         FALSE). We mark the subquery table cursor as having no more rows
 
2366
         false). We mark the subquery table cursor as having no more rows
2367
2367
         (to ensure that the processing that follows will not find a match)
2368
 
         and return FALSE, so IN is not treated as returning NULL.
 
2368
         and return false, so IN is not treated as returning NULL.
2369
2369
 
2370
2370
 
2371
2371
  RETURN
2372
 
    FALSE - The value of the IN predicate is not known. Proceed to find the
 
2372
    false - The value of the IN predicate is not known. Proceed to find the
2373
2373
            value of the IN predicate using the determined values of
2374
2374
            null_keypart and table->status.
2375
 
    TRUE  - IN predicate has a value of NULL. Stop the processing right there
 
2375
    true  - IN predicate has a value of NULL. Stop the processing right there
2376
2376
            and return NULL to the outer predicates.
2377
2377
*/
2378
2378
 
2413
2413
    /*
2414
2414
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed 
2415
2415
      using the store_key::store_key_result enum because ref.key_err is a 
2416
 
      boolean and we want to detect both TRUE and STORE_KEY_FATAL from the 
2417
 
      space of the union of the values of [TRUE, FALSE] and 
 
2416
      boolean and we want to detect both true and STORE_KEY_FATAL from the 
 
2417
      space of the union of the values of [true, false] and 
2418
2418
      store_key::store_key_result.  
2419
2419
      TODO: fix the variable an return types.
2420
2420
    */
2445
2445
    This is a special case, we don't need to search for NULL in the table,
2446
2446
    instead, the result value is 
2447
2447
      - NULL  if select produces empty row set
2448
 
      - FALSE otherwise.
 
2448
      - false otherwise.
2449
2449
 
2450
 
    In some cases (IN subselect is a top level item, i.e. abort_on_null==TRUE)
2451
 
    the caller doesn't distinguish between NULL and FALSE result and we just
2452
 
    return FALSE. 
 
2450
    In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
 
2451
    the caller doesn't distinguish between NULL and false result and we just
 
2452
    return false. 
2453
2453
    Otherwise we make a full table scan to see if there is at least one 
2454
2454
    matching row.
2455
2455
    
2458
2458
  NOTE
2459
2459
    
2460
2460
  RETURN
2461
 
    FALSE - ok
2462
 
    TRUE  - an error occured while scanning
 
2461
    false - ok
 
2462
    true  - an error occured while scanning
2463
2463
*/
2464
2464
 
2465
2465
int subselect_uniquesubquery_engine::exec()
2467
2467
  DBUG_ENTER("subselect_uniquesubquery_engine::exec");
2468
2468
  int error;
2469
2469
  TABLE *table= tab->table;
2470
 
  empty_result_set= TRUE;
 
2470
  empty_result_set= true;
2471
2471
  table->status= 0;
2472
2472
 
2473
2473
  /* TODO: change to use of 'full_scan' here? */
2503
2503
    if (!table->status && (!cond || cond->val_int()))
2504
2504
    {
2505
2505
      ((Item_in_subselect *) item)->value= 1;
2506
 
      empty_result_set= FALSE;
 
2506
      empty_result_set= false;
2507
2507
    }
2508
2508
    else
2509
2509
      ((Item_in_subselect *) item)->value= 0;
2528
2528
    The value of the predicate is calculated as follows: 
2529
2529
    1. If oe IS NULL, this is a special case, do a full table scan on
2530
2530
       table tbl and search for row that satisfies subq_where. If such 
2531
 
       row is found, return NULL, otherwise return FALSE.
 
2531
       row is found, return NULL, otherwise return false.
2532
2532
    2. Make an index lookup via key=oe, search for a row that satisfies
2533
 
       subq_where. If found, return TRUE.
2534
 
    3. If check_null==TRUE, make another lookup via key=NULL, search for a 
 
2533
       subq_where. If found, return true.
 
2534
    3. If check_null==true, make another lookup via key=NULL, search for a 
2535
2535
       row that satisfies subq_where. If found, return NULL, otherwise
2536
 
       return FALSE.
 
2536
       return false.
2537
2537
 
2538
2538
  TODO
2539
2539
    The step #1 can be optimized further when the index has several key
2553
2553
 
2554
2554
    If this query produces a row, the result is NULL (as we're evaluating 
2555
2555
    "(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2556
 
    i.e. NULL).  If the query produces no rows, the result is FALSE.
 
2556
    i.e. NULL).  If the query produces no rows, the result is false.
2557
2557
 
2558
2558
    We currently evaluate (1) by doing a full table scan. (2) can be
2559
2559
    evaluated by doing a "ref" scan on "keypart1=const1", which can be much
2573
2573
  TABLE *table= tab->table;
2574
2574
 
2575
2575
  ((Item_in_subselect *) item)->value= 0;
2576
 
  empty_result_set= TRUE;
 
2576
  empty_result_set= true;
2577
2577
  null_keypart= 0;
2578
2578
  table->status= 0;
2579
2579
 
2620
2620
      {
2621
2621
        if ((!cond || cond->val_int()) && (!having || having->val_int()))
2622
2622
        {
2623
 
          empty_result_set= FALSE;
 
2623
          empty_result_set= false;
2624
2624
          if (null_finding)
2625
2625
            ((Item_in_subselect *) item)->was_null= 1;
2626
2626
          else
2817
2817
  @param res            new select_result object
2818
2818
 
2819
2819
  @retval
2820
 
    FALSE OK
 
2820
    false OK
2821
2821
  @retval
2822
 
    TRUE  error
 
2822
    true  error
2823
2823
*/
2824
2824
 
2825
2825
bool subselect_single_select_engine::change_result(Item_subselect *si,
2838
2838
  @param res            new select_result object
2839
2839
 
2840
2840
  @retval
2841
 
    FALSE OK
 
2841
    false OK
2842
2842
  @retval
2843
 
    TRUE  error
 
2843
    true  error
2844
2844
*/
2845
2845
 
2846
2846
bool subselect_union_engine::change_result(Item_subselect *si,
2860
2860
  @param res            new select_result object
2861
2861
 
2862
2862
  @retval
2863
 
    FALSE OK
 
2863
    false OK
2864
2864
  @retval
2865
 
    TRUE  error
 
2865
    true  error
2866
2866
*/
2867
2867
 
2868
2868
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
2869
2869
                                                    select_result_interceptor *res)
2870
2870
{
2871
2871
  DBUG_ASSERT(0);
2872
 
  return TRUE;
 
2872
  return true;
2873
2873
}
2874
2874
 
2875
2875
 
2877
2877
  Report about presence of tables in subquery.
2878
2878
 
2879
2879
  @retval
2880
 
    TRUE  there are not tables used in subquery
 
2880
    true  there are not tables used in subquery
2881
2881
  @retval
2882
 
    FALSE there are some tables in subquery
 
2882
    false there are some tables in subquery
2883
2883
*/
2884
2884
bool subselect_single_select_engine::no_tables()
2885
2885
{
2894
2894
    subselect_single_select_engine::may_be_null()
2895
2895
 
2896
2896
  RETURN
2897
 
    FALSE  can guarantee that the subquery never return NULL
2898
 
    TRUE   otherwise
 
2897
    false  can guarantee that the subquery never return NULL
 
2898
    true   otherwise
2899
2899
*/
2900
2900
bool subselect_single_select_engine::may_be_null()
2901
2901
{
2907
2907
  Report about presence of tables in subquery.
2908
2908
 
2909
2909
  @retval
2910
 
    TRUE  there are not tables used in subquery
 
2910
    true  there are not tables used in subquery
2911
2911
  @retval
2912
 
    FALSE there are some tables in subquery
 
2912
    false there are some tables in subquery
2913
2913
*/
2914
2914
bool subselect_union_engine::no_tables()
2915
2915
{
2916
2916
  for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
2917
2917
  {
2918
2918
    if (sl->table_list.elements)
2919
 
      return FALSE;
 
2919
      return false;
2920
2920
  }
2921
 
  return TRUE;
 
2921
  return true;
2922
2922
}
2923
2923
 
2924
2924
 
2926
2926
  Report about presence of tables in subquery.
2927
2927
 
2928
2928
  @retval
2929
 
    TRUE  there are not tables used in subquery
 
2929
    true  there are not tables used in subquery
2930
2930
  @retval
2931
 
    FALSE there are some tables in subquery
 
2931
    false there are some tables in subquery
2932
2932
*/
2933
2933
 
2934
2934
bool subselect_uniquesubquery_engine::no_tables()
2959
2959
    Currently Item_subselect::init() already chooses and creates at parse
2960
2960
    time an engine with a corresponding JOIN to execute the subquery.
2961
2961
 
2962
 
  @retval TRUE  if error
2963
 
  @retval FALSE otherwise
 
2962
  @retval true  if error
 
2963
  @retval false otherwise
2964
2964
*/
2965
2965
 
2966
2966
bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns)
2983
2983
    managed (created/filled/etc) internally by the interceptor.
2984
2984
  */
2985
2985
  if (!(tmp_result_sink= new select_union))
2986
 
    DBUG_RETURN(TRUE);
 
2986
    DBUG_RETURN(true);
2987
2987
  if (tmp_result_sink->create_result_table(
2988
 
                         thd, tmp_columns, TRUE,
 
2988
                         thd, tmp_columns, true,
2989
2989
                         thd->options | TMP_TABLE_ALL_COLUMNS,
2990
 
                         "materialized subselect", TRUE))
2991
 
    DBUG_RETURN(TRUE);
 
2990
                         "materialized subselect", true))
 
2991
    DBUG_RETURN(true);
2992
2992
 
2993
2993
  tmp_table= tmp_result_sink->table;
2994
2994
  tmp_key= tmp_table->key_info;
3011
3011
    free_tmp_table(thd, tmp_table);
3012
3012
    delete result;
3013
3013
    result= NULL;
3014
 
    DBUG_RETURN(TRUE);
 
3014
    DBUG_RETURN(true);
3015
3015
  }
3016
3016
  result= tmp_result_sink;
3017
3017
 
3032
3032
      subselect_uniquesubquery_engine, so these objects are incomplete.
3033
3033
  */ 
3034
3034
  if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
3035
 
    DBUG_RETURN(TRUE);
 
3035
    DBUG_RETURN(true);
3036
3036
  tab->table= tmp_table;
3037
3037
  tab->ref.key= 0; /* The only temp table index. */
3038
3038
  tab->ref.key_length= tmp_key->key_length;
3043
3043
                                  (tmp_key_parts + 1)))) ||
3044
3044
      !(tab->ref.items=
3045
3045
        (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
3046
 
    DBUG_RETURN(TRUE);
 
3046
    DBUG_RETURN(true);
3047
3047
 
3048
3048
  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3049
3049
  store_key **ref_key= tab->ref.key_copy;
3069
3069
  tab->ref.key_err= 1;
3070
3070
  tab->ref.key_parts= tmp_key_parts;
3071
3071
 
3072
 
  DBUG_RETURN(FALSE);
 
3072
  DBUG_RETURN(false);
3073
3073
}
3074
3074
 
3075
3075
 
3077
3077
  Initialize members of the engine that need to be re-initilized at each
3078
3078
  execution.
3079
3079
 
3080
 
  @retval TRUE  if a memory allocation error occurred
3081
 
  @retval FALSE if success
 
3080
  @retval true  if a memory allocation error occurred
 
3081
  @retval false if success
3082
3082
*/
3083
3083
 
3084
3084
bool subselect_hash_sj_engine::init_runtime()
3091
3091
  /* Let our engine reuse this query plan for materialization. */
3092
3092
  materialize_join= materialize_engine->join;
3093
3093
  materialize_join->change_result(result);
3094
 
  return FALSE;
 
3094
  return false;
3095
3095
}
3096
3096
 
3097
3097
 
3112
3112
 
3113
3113
void subselect_hash_sj_engine::cleanup()
3114
3114
{
3115
 
  is_materialized= FALSE;
 
3115
  is_materialized= false;
3116
3116
  result->cleanup(); /* Resets the temp table as well. */
3117
3117
  materialize_engine->cleanup();
3118
3118
  subselect_uniquesubquery_engine::cleanup();
3126
3126
  If needed materialize the subquery into a temporary table, then
3127
3127
  copmpute the predicate via a lookup into this table.
3128
3128
 
3129
 
  @retval TRUE  if error
3130
 
  @retval FALSE otherwise
 
3129
  @retval true  if error
 
3130
  @retval false otherwise
3131
3131
*/
3132
3132
 
3133
3133
int subselect_hash_sj_engine::exec()
3160
3160
        immediately after materialization (yet it's done together with
3161
3161
        unlocking).
3162
3162
     */
3163
 
    is_materialized= TRUE;
 
3163
    is_materialized= true;
3164
3164
    /*
3165
3165
      If the subquery returned no rows, the temporary table is empty, so we know
3166
 
      directly that the result of IN is FALSE. We first update the table
 
3166
      directly that the result of IN is false. We first update the table
3167
3167
      statistics, then we test if the temporary table for the query result is
3168
3168
      empty.
3169
3169
    */
3170
3170
    tab->table->file->info(HA_STATUS_VARIABLE);
3171
3171
    if (!tab->table->file->stats.records)
3172
3172
    {
3173
 
      empty_result_set= TRUE;
3174
 
      item_in->value= FALSE;
3175
 
      /* TODO: check we need this: item_in->null_value= FALSE; */
3176
 
      DBUG_RETURN(FALSE);
 
3173
      empty_result_set= true;
 
3174
      item_in->value= false;
 
3175
      /* TODO: check we need this: item_in->null_value= false; */
 
3176
      DBUG_RETURN(false);
3177
3177
    }
3178
3178
    /* Set tmp_param only if its usable, i.e. tmp_param->copy_field != NULL. */
3179
3179
    tmp_param= &(item_in->unit->outer_select()->join->tmp_table_param);