~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/subselect.cc

  • Committer: Brian Aker
  • Date: 2008-12-06 23:57:32 UTC
  • mfrom: (656.1.10 devel)
  • Revision ID: brian@tangent.org-20081206235732-jx228bczpvmxu8ww
Merge from Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
208
208
  }
209
209
  else
210
210
    goto err;
211
 
  
 
211
 
212
212
  if ((uncacheable= engine->uncacheable()))
213
213
  {
214
214
    const_item_cache= 0;
477
477
    return(RES_OK);
478
478
 
479
479
  SELECT_LEX *select_lex= join->select_lex;
480
 
 
 
480
 
481
481
  if (!select_lex->master_unit()->is_union() &&
482
482
      !select_lex->table_list.elements &&
483
483
      select_lex->item_list.elements == 1 &&
526
526
  return engine->type();
527
527
}
528
528
 
529
 
/* 
530
 
 Don't rely on the result type to calculate field type. 
 
529
/*
 
530
 Don't rely on the result type to calculate field type.
531
531
 Ask the engine instead.
532
532
*/
533
533
enum_field_types Item_singlerow_subselect::field_type() const
875
875
  if (exec())
876
876
  {
877
877
    reset();
878
 
    /* 
 
878
    /*
879
879
      Must mark the IN predicate as NULL so as to make sure an enclosing NOT
880
 
      predicate will return false. See the comments in 
 
880
      predicate will return false. See the comments in
881
881
      subselect_uniquesubquery_engine::copy_ref_key for further details.
882
882
    */
883
883
    null_value= 1;
910
910
}
911
911
 
912
912
 
913
 
/* 
 
913
/*
914
914
  Rewrite a single-column IN/ALL/ANY subselect
915
915
 
916
916
  SYNOPSIS
920
920
 
921
921
  DESCRIPTION
922
922
    Rewrite a single-column subquery using rule-based approach. The subquery
923
 
    
 
923
 
924
924
       oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
925
 
    
 
925
 
926
926
    First, try to convert the subquery to scalar-result subquery in one of
927
927
    the forms:
928
 
    
 
928
 
929
929
       - oe $cmp$ (SELECT MAX(...) )  // handled by Item_singlerow_subselect
930
930
       - oe $cmp$ <max>(SELECT ...)   // handled by Item_maxmin_subselect
931
 
   
 
931
 
932
932
    If that fails, the subquery will be handled with class Item_in_optimizer.
933
933
    There are two possibilites:
934
934
    - If the subquery execution method is materialization, then the subquery is
1023
1023
      */
1024
1024
      if (item->fix_fields(session, 0))
1025
1025
        return(RES_ERROR);
1026
 
      session->lex->allow_sum_func= save_allow_sum_func; 
 
1026
      session->lex->allow_sum_func= save_allow_sum_func;
1027
1027
      /* we added aggregate function => we have to change statistic */
1028
 
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields, 
 
1028
      count_field_types(select_lex, &join->tmp_table_param, join->all_fields,
1029
1029
                        0);
1030
1030
 
1031
1031
      subs= new Item_singlerow_subselect(select_lex);
1098
1098
 
1099
1099
  - If the subquery has aggregates, GROUP BY, or HAVING, convert to
1100
1100
 
1101
 
    SELECT ie FROM ...  HAVING subq_having AND 
 
1101
    SELECT ie FROM ...  HAVING subq_having AND
1102
1102
                               trigcond(oe $cmp$ ref_or_null_helper<ie>)
1103
 
                                   
 
1103
 
1104
1104
    the addition is wrapped into trigger only when we want to distinguish
1105
1105
    between NULL and false results.
1106
1106
 
1108
1108
    following:
1109
1109
 
1110
1110
    = If we don't need to distinguish between NULL and false subquery:
1111
 
        
 
1111
 
1112
1112
      SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where
1113
1113
 
1114
1114
    = If we need to distinguish between those:
1145
1145
                                                      this->full_name()));
1146
1146
    if (!abort_on_null && left_expr->maybe_null)
1147
1147
    {
1148
 
      /* 
 
1148
      /*
1149
1149
        We can encounter "NULL IN (SELECT ...)". Wrap the added condition
1150
1150
        within a trig_cond.
1151
1151
      */
1152
1152
      item= new Item_func_trig_cond(item, get_cond_guard(0));
1153
1153
    }
1154
 
    
 
1154
 
1155
1155
    /*
1156
1156
      AND and comparison functions can't be changed during fix_fields()
1157
1157
      we can assign select_lex->having here, and pass 0 as last
1183
1183
                                                   (int64_t) 1,
1184
1184
                                                   MY_INT64_NUM_DECIMAL_DIGITS));
1185
1185
      select_lex->ref_pointer_array[0]= select_lex->item_list.head();
1186
 
       
 
1186
 
1187
1187
      item= func->create(expr, item);
1188
1188
      if (!abort_on_null && orig_item->maybe_null)
1189
1189
      {
1214
1214
        item= new Item_cond_or(item,
1215
1215
                               new Item_func_isnull(orig_item));
1216
1216
      }
1217
 
      /* 
 
1217
      /*
1218
1218
        If we may encounter NULL IN (SELECT ...) and care whether subquery
1219
1219
        result is NULL or false, wrap condition in a trig_cond.
1220
1220
      */
1224
1224
          return(RES_ERROR);
1225
1225
      }
1226
1226
      /*
1227
 
        TODO: figure out why the following is done here in 
 
1227
        TODO: figure out why the following is done here in
1228
1228
        single_value_transformer but there is no corresponding action in
1229
1229
        row_value_transformer?
1230
1230
      */
1269
1269
        new_having->name= (char*)in_having_cond;
1270
1270
        select_lex->having= join->having= new_having;
1271
1271
        select_lex->having_fix_field= 1;
1272
 
        
 
1272
 
1273
1273
        /*
1274
1274
          we do not check join->having->fixed, because comparison function
1275
1275
          (from func->create) can't be fixed after creation
1442
1442
          return(RES_ERROR);
1443
1443
      }
1444
1444
      having_item= and_items(having_item, col_item);
1445
 
      
1446
 
      Item *item_nnull_test= 
 
1445
 
 
1446
      Item *item_nnull_test=
1447
1447
         new Item_is_not_null_test(this,
1448
1448
                                   new Item_ref(&select_lex->context,
1449
1449
                                                select_lex->
1452
1452
                                                (char *)"<list ref>"));
1453
1453
      if (!abort_on_null && left_expr->element_index(i)->maybe_null)
1454
1454
      {
1455
 
        if (!(item_nnull_test= 
 
1455
        if (!(item_nnull_test=
1456
1456
              new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
1457
1457
          return(RES_ERROR);
1458
1458
      }
1511
1511
        Item *having_col_item=
1512
1512
          new Item_is_not_null_test(this,
1513
1513
                                    new
1514
 
                                    Item_ref(&select_lex->context, 
 
1514
                                    Item_ref(&select_lex->context,
1515
1515
                                             select_lex->ref_pointer_array + i,
1516
1516
                                             (char *)"<no matter>",
1517
1517
                                             (char *)"<list ref>"));
1518
 
        
1519
 
        
 
1518
 
 
1519
 
1520
1520
        item_isnull= new
1521
1521
          Item_func_isnull(new
1522
1522
                           Item_direct_ref(&select_lex->context,
1526
1526
                                           (char *)"<list ref>")
1527
1527
                          );
1528
1528
        item= new Item_cond_or(item, item_isnull);
1529
 
        /* 
 
1529
        /*
1530
1530
          TODO: why we create the above for cases where the right part
1531
1531
                cant be NULL?
1532
1532
        */
1534
1534
        {
1535
1535
          if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
1536
1536
            return(RES_ERROR);
1537
 
          if (!(having_col_item= 
 
1537
          if (!(having_col_item=
1538
1538
                  new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
1539
1539
            return(RES_ERROR);
1540
1540
        }
2052
2052
*/
2053
2053
 
2054
2054
bool subselect_single_select_engine::no_rows()
2055
 
 
2055
{
2056
2056
  return !item->assigned();
2057
2057
}
2058
2058
 
2059
2059
 
2060
 
/* 
2061
 
 makes storage for the output values for the subquery and calcuates 
 
2060
/*
 
2061
 makes storage for the output values for the subquery and calcuates
2062
2062
 their data and column types and their nullability.
2063
 
*/ 
 
2063
*/
2064
2064
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
2065
2065
{
2066
2066
  Item *sel_item;
2141
2141
      session->lex->current_select= save_select;
2142
2142
      return(join->error ? join->error : 1);
2143
2143
    }
2144
 
    if (!select_lex->uncacheable && session->lex->describe && 
2145
 
        !(join->select_options & SELECT_DESCRIBE) && 
 
2144
    if (!select_lex->uncacheable && session->lex->describe &&
 
2145
        !(join->select_options & SELECT_DESCRIBE) &&
2146
2146
        join->need_tmp && item->const_item())
2147
2147
    {
2148
2148
      /*
2211
2211
        }
2212
2212
      }
2213
2213
    }
2214
 
    
 
2214
 
2215
2215
    join->exec();
2216
2216
 
2217
2217
    /* Enable the optimizations back */
2220
2220
      JOIN_TAB *tab= *ptab;
2221
2221
      tab->read_record.record= 0;
2222
2222
      tab->read_record.ref_length= 0;
2223
 
      tab->read_first_record= tab->save_read_first_record; 
 
2223
      tab->read_first_record= tab->save_read_first_record;
2224
2224
      tab->read_record.read_record= tab->save_read_record;
2225
2225
    }
2226
2226
    executed= 1;
2244
2244
 
2245
2245
/*
2246
2246
  Search for at least one row satisfying select condition
2247
 
 
 
2247
 
2248
2248
  SYNOPSIS
2249
2249
    subselect_uniquesubquery_engine::scan_table()
2250
2250
 
2251
2251
  DESCRIPTION
2252
2252
    Scan the table using sequential access until we find at least one row
2253
2253
    satisfying select condition.
2254
 
    
 
2254
 
2255
2255
    The caller must set this->empty_result_set=false before calling this
2256
2256
    function. This function will set it to true if it finds a matching row.
2257
2257
 
2267
2267
 
2268
2268
  if (table->file->inited)
2269
2269
    table->file->ha_index_end();
2270
 
 
 
2270
 
2271
2271
  table->file->ha_rnd_init(1);
2272
2272
  table->file->extra_opt(HA_EXTRA_CACHE,
2273
2273
                         current_session->variables.read_buff_size);
2371
2371
    }
2372
2372
 
2373
2373
    /*
2374
 
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed 
2375
 
      using the store_key::store_key_result enum because ref.key_err is a 
2376
 
      boolean and we want to detect both true and STORE_KEY_FATAL from the 
2377
 
      space of the union of the values of [true, false] and 
2378
 
      store_key::store_key_result.  
 
2374
      Check if the error is equal to STORE_KEY_FATAL. This is not expressed
 
2375
      using the store_key::store_key_result enum because ref.key_err is a
 
2376
      boolean and we want to detect both true and STORE_KEY_FATAL from the
 
2377
      space of the union of the values of [true, false] and
 
2378
      store_key::store_key_result.
2379
2379
      TODO: fix the variable an return types.
2380
2380
    */
2381
2381
    if (store_res == store_key::STORE_KEY_FATAL)
2382
2382
    {
2383
2383
      /*
2384
2384
       Error converting the left IN operand to the column type of the right
2385
 
       IN operand. 
 
2385
       IN operand.
2386
2386
      */
2387
2387
      tab->table->status= STATUS_NOT_FOUND;
2388
2388
      break;
2403
2403
    If some part of the lookup key is NULL, then we're evaluating
2404
2404
      NULL IN (SELECT ... )
2405
2405
    This is a special case, we don't need to search for NULL in the table,
2406
 
    instead, the result value is 
 
2406
    instead, the result value is
2407
2407
      - NULL  if select produces empty row set
2408
2408
      - false otherwise.
2409
2409
 
2410
2410
    In some cases (IN subselect is a top level item, i.e. abort_on_null==true)
2411
2411
    the caller doesn't distinguish between NULL and false result and we just
2412
 
    return false. 
2413
 
    Otherwise we make a full table scan to see if there is at least one 
 
2412
    return false.
 
2413
    Otherwise we make a full table scan to see if there is at least one
2414
2414
    matching row.
2415
 
    
 
2415
 
2416
2416
    The result of this function (info about whether a row was found) is
2417
2417
    stored in this->empty_result_set.
2418
2418
  NOTE
2419
 
    
 
2419
 
2420
2420
  RETURN
2421
2421
    false - ok
2422
2422
    true  - an error occured while scanning
2428
2428
  Table *table= tab->table;
2429
2429
  empty_result_set= true;
2430
2430
  table->status= 0;
2431
 
 
 
2431
 
2432
2432
  /* TODO: change to use of 'full_scan' here? */
2433
2433
  if (copy_ref_key())
2434
2434
    return(1);
2435
2435
  if (table->status)
2436
2436
  {
2437
 
    /* 
2438
 
      We know that there will be no rows even if we scan. 
 
2437
    /*
 
2438
      We know that there will be no rows even if we scan.
2439
2439
      Can be set in copy_ref_key.
2440
2440
    */
2441
2441
    ((Item_in_subselect *) item)->value= 0;
2444
2444
 
2445
2445
  if (null_keypart)
2446
2446
    return(scan_table());
2447
 
 
 
2447
 
2448
2448
  if (!table->file->inited)
2449
2449
    table->file->ha_index_init(tab->ref.key, 0);
2450
2450
  error= table->file->index_read_map(table->record[0],
2476
2476
 
2477
2477
  SYNOPSIS
2478
2478
    subselect_indexsubquery_engine:exec()
2479
 
      full_scan 
 
2479
      full_scan
2480
2480
 
2481
2481
  DESCRIPTION
2482
2482
    The engine is used to resolve subqueries in form
2483
2483
 
2484
 
      oe IN (SELECT key FROM tbl WHERE subq_where) 
 
2484
      oe IN (SELECT key FROM tbl WHERE subq_where)
2485
2485
 
2486
 
    The value of the predicate is calculated as follows: 
 
2486
    The value of the predicate is calculated as follows:
2487
2487
    1. If oe IS NULL, this is a special case, do a full table scan on
2488
 
       table tbl and search for row that satisfies subq_where. If such 
 
2488
       table tbl and search for row that satisfies subq_where. If such
2489
2489
       row is found, return NULL, otherwise return false.
2490
2490
    2. Make an index lookup via key=oe, search for a row that satisfies
2491
2491
       subq_where. If found, return true.
2492
 
    3. If check_null==true, make another lookup via key=NULL, search for a 
 
2492
    3. If check_null==true, make another lookup via key=NULL, search for a
2493
2493
       row that satisfies subq_where. If found, return NULL, otherwise
2494
2494
       return false.
2495
2495
 
2496
2496
  TODO
2497
2497
    The step #1 can be optimized further when the index has several key
2498
2498
    parts. Consider a subquery:
2499
 
    
 
2499
 
2500
2500
      (oe1, oe2) IN (SELECT keypart1, keypart2 FROM tbl WHERE subq_where)
2501
2501
 
2502
2502
    and suppose we need to evaluate it for {oe1, oe2}=={const1, NULL}.
2506
2506
      SELECT keypart1, keypart2 FROM tbl WHERE subq_where            (1)
2507
2507
 
2508
2508
    and checking if it has produced any matching rows, evaluate
2509
 
    
 
2509
 
2510
2510
      SELECT keypart2 FROM tbl WHERE subq_where AND keypart1=const1  (2)
2511
2511
 
2512
 
    If this query produces a row, the result is NULL (as we're evaluating 
 
2512
    If this query produces a row, the result is NULL (as we're evaluating
2513
2513
    "(const1, NULL) IN { (const1, X), ... }", which has a value of UNKNOWN,
2514
2514
    i.e. NULL).  If the query produces no rows, the result is false.
2515
2515
 
2547
2547
 
2548
2548
  if (table->status)
2549
2549
  {
2550
 
    /* 
2551
 
      We know that there will be no rows even if we scan. 
 
2550
    /*
 
2551
      We know that there will be no rows even if we scan.
2552
2552
      Can be set in copy_ref_key.
2553
2553
    */
2554
2554
    ((Item_in_subselect *) item)->value= 0;
2985
2985
    - this JOIN_TAB has no corresponding JOIN (and doesn't need one), and
2986
2986
    - here we initialize only those members that are used by
2987
2987
      subselect_uniquesubquery_engine, so these objects are incomplete.
2988
 
  */ 
 
2988
  */
2989
2989
  if (!(tab= (JOIN_TAB*) session->alloc(sizeof(JOIN_TAB))))
2990
2990
    return(true);
2991
2991
  tab->table= tmp_table;
3003
3003
  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3004
3004
  store_key **ref_key= tab->ref.key_copy;
3005
3005
  unsigned char *cur_ref_buff= tab->ref.key_buff;
3006
 
  
 
3006
 
3007
3007
  for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3008
3008
  {
3009
3009
    tab->ref.items[i]= item_in->left_expr->element_index(i);