~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_subselect.cc

  • Committer: Jay Pipes
  • Date: 2008-07-21 17:52:33 UTC
  • mto: (201.2.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 204.
  • Revision ID: jay@mysql.com-20080721175233-mtyz298j8xl3v63y
cleanup of FAQ file

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
    - add function from mysql_select that use JOIN* as parameter to JOIN
24
24
    methods (sql_select.h/sql_select.cc)
25
25
*/
26
 
#include <drizzled/server_includes.h>
27
 
#include <drizzled/sql_select.h>
28
 
#include <drizzled/drizzled_error_messages.h>
 
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"
29
33
 
30
34
inline Item * and_items(Item* cond, Item *item)
31
35
{
143
147
}
144
148
 
145
149
Item_subselect::trans_res
146
 
Item_subselect::select_transformer(JOIN *join __attribute__((unused)))
 
150
Item_subselect::select_transformer(JOIN *join __attribute__((__unused__)))
147
151
{
148
152
  return(RES_OK);
149
153
}
152
156
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
153
157
{
154
158
  char const *save_where= thd_param->where;
155
 
  uint8_t uncacheable;
 
159
  uint8 uncacheable;
156
160
  bool res;
157
161
 
158
162
  assert(fixed == 0);
159
163
  engine->set_thd((thd= thd_param));
160
164
 
161
 
  if (check_stack_overrun(thd, STACK_MIN_SIZE, (unsigned char*)&res))
 
165
  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
162
166
    return true;
163
167
 
164
168
  res= engine->prepare();
221
225
 
222
226
 
223
227
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
224
 
                          unsigned char *argument)
 
228
                          uchar *argument)
225
229
{
226
230
 
227
231
  if (walk_subquery)
230
234
    {
231
235
      List_iterator<Item> li(lex->item_list);
232
236
      Item *item;
233
 
      order_st *order;
 
237
      ORDER *order;
234
238
 
235
239
      if (lex->where && (lex->where)->walk(processor, walk_subquery, argument))
236
240
        return 1;
243
247
        if (item->walk(processor, walk_subquery, argument))
244
248
          return 1;
245
249
      }
246
 
      for (order= (order_st*) lex->order_list.first ; order; order= order->next)
 
250
      for (order= (ORDER*) lex->order_list.first ; order; order= order->next)
247
251
      {
248
252
        if ((*order->item)->walk(processor, walk_subquery, argument))
249
253
          return 1;
250
254
      }
251
 
      for (order= (order_st*) lex->group_list.first ; order; order= order->next)
 
255
      for (order= (ORDER*) lex->group_list.first ; order; order= order->next)
252
256
      {
253
257
        if ((*order->item)->walk(processor, walk_subquery, argument))
254
258
          return 1;
495
499
    have_to_be_excluded= 1;
496
500
    if (thd->lex->describe)
497
501
    {
498
 
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
502
      char warn_buff[MYSQL_ERRMSG_SIZE];
499
503
      sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
500
 
      push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
504
      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
501
505
                   ER_SELECT_REDUCED, warn_buff);
502
506
    }
503
507
    substitution= select_lex->item_list.head();
506
510
      'upper' select is not really dependent => we remove this dependence
507
511
    */
508
512
    substitution->walk(&Item::remove_dependence_processor, 0,
509
 
                       (unsigned char *) select_lex->outer_select());
 
513
                       (uchar *) select_lex->outer_select());
510
514
    return(RES_REDUCE);
511
515
  }
512
516
  return(RES_OK);
513
517
}
514
518
 
515
519
 
516
 
void Item_singlerow_subselect::store(uint32_t i, Item *item)
 
520
void Item_singlerow_subselect::store(uint i, Item *item)
517
521
{
518
522
  row[i]->store(item);
519
523
}
555
559
    maybe_null= engine->may_be_null();
556
560
}
557
561
 
558
 
uint32_t Item_singlerow_subselect::cols()
 
562
uint Item_singlerow_subselect::cols()
559
563
{
560
564
  return engine->cols();
561
565
}
562
566
 
563
 
bool Item_singlerow_subselect::check_cols(uint32_t c)
 
567
bool Item_singlerow_subselect::check_cols(uint c)
564
568
{
565
569
  if (c != engine->cols())
566
570
  {
572
576
 
573
577
bool Item_singlerow_subselect::null_inside()
574
578
{
575
 
  for (uint32_t i= 0; i < max_columns ; i++)
 
579
  for (uint i= 0; i < max_columns ; i++)
576
580
  {
577
581
    if (row[i]->null_value)
578
582
      return 1;
736
740
   max_length= 1;
737
741
   max_columns= engine->cols();
738
742
  /* We need only 1 row to determine existence */
739
 
  unit->global_parameters->select_limit= new Item_int((int32_t) 1);
 
743
  unit->global_parameters->select_limit= new Item_int((int32) 1);
740
744
}
741
745
 
742
746
double Item_exists_subselect::val_real()
1285
1289
        have_to_be_excluded= 1;
1286
1290
        if (thd->lex->describe)
1287
1291
        {
1288
 
          char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
1292
          char warn_buff[MYSQL_ERRMSG_SIZE];
1289
1293
          sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
1290
 
          push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1294
          push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1291
1295
                       ER_SELECT_REDUCED, warn_buff);
1292
1296
        }
1293
1297
        return(RES_REDUCE);
1303
1307
Item_in_subselect::row_value_transformer(JOIN *join)
1304
1308
{
1305
1309
  SELECT_LEX *select_lex= join->select_lex;
1306
 
  uint32_t cols_num= left_expr->cols();
 
1310
  uint cols_num= left_expr->cols();
1307
1311
 
1308
1312
  if (select_lex->item_list.elements != left_expr->cols())
1309
1313
  {
1341
1345
      if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
1342
1346
                                                        left_expr->cols())))
1343
1347
        return(RES_ERROR);
1344
 
      for (uint32_t i= 0; i < cols_num; i++)
 
1348
      for (uint i= 0; i < cols_num; i++)
1345
1349
        pushed_cond_guards[i]= true;
1346
1350
    }
1347
1351
  }
1381
1385
{
1382
1386
  SELECT_LEX *select_lex= join->select_lex;
1383
1387
  Item *having_item= 0;
1384
 
  uint32_t cols_num= left_expr->cols();
 
1388
  uint cols_num= left_expr->cols();
1385
1389
  bool is_having_used= (join->having || select_lex->with_sum_func ||
1386
1390
                        select_lex->group_list.first ||
1387
1391
                        !select_lex->table_list.elements);
1403
1407
      TODO: say here explicitly if the order of AND parts matters or not.
1404
1408
    */
1405
1409
    Item *item_having_part2= 0;
1406
 
    for (uint32_t i= 0; i < cols_num; i++)
 
1410
    for (uint i= 0; i < cols_num; i++)
1407
1411
    {
1408
1412
      assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1409
1413
                  (select_lex->ref_pointer_array[i]->type() == REF_ITEM &&
1479
1483
                               (l3 = v3)
1480
1484
    */
1481
1485
    Item *where_item= 0;
1482
 
    for (uint32_t i= 0; i < cols_num; i++)
 
1486
    for (uint i= 0; i < cols_num; i++)
1483
1487
    {
1484
1488
      Item *item, *item_isnull;
1485
1489
      assert((left_expr->fixed && select_lex->ref_pointer_array[i]->fixed) ||
1613
1617
  {
1614
1618
    /*
1615
1619
      IN/SOME/ALL/ANY subqueries aren't support LIMIT clause. Without it
1616
 
      order_st BY clause becomes meaningless thus we drop it here.
 
1620
      ORDER BY clause becomes meaningless thus we drop it here.
1617
1621
    */
1618
1622
    SELECT_LEX *sl= current->master_unit()->first_select();
1619
1623
    for (; sl; sl= sl->next_select())
1828
1832
  if (!(left_expr_cache= new List<Cached_item>))
1829
1833
    return true;
1830
1834
 
1831
 
  for (uint32_t i= 0; i < left_expr->cols(); i++)
 
1835
  for (uint i= 0; i < left_expr->cols(); i++)
1832
1836
  {
1833
1837
    Cached_item *cur_item_cache= new_Cached_item(thd,
1834
1838
                                                 left_expr->element_index(i),
1853
1857
  @retval false otherwise
1854
1858
*/
1855
1859
 
1856
 
bool Item_in_subselect::is_expensive_processor(unsigned char *arg __attribute__((unused)))
 
1860
bool Item_in_subselect::is_expensive_processor(uchar *arg __attribute__((__unused__)))
1857
1861
{
1858
1862
  return exec_method == MATERIALIZATION;
1859
1863
}
2005
2009
  SELECT_LEX *save_select= thd->lex->current_select;
2006
2010
  thd->lex->current_select= select_lex;
2007
2011
  if (join->prepare(&select_lex->ref_pointer_array,
2008
 
                    (TableList*) select_lex->table_list.first,
 
2012
                    (TABLE_LIST*) select_lex->table_list.first,
2009
2013
                    select_lex->with_wild,
2010
2014
                    select_lex->where,
2011
2015
                    select_lex->order_list.elements +
2012
2016
                    select_lex->group_list.elements,
2013
 
                    (order_st*) select_lex->order_list.first,
2014
 
                    (order_st*) select_lex->group_list.first,
 
2017
                    (ORDER*) select_lex->order_list.first,
 
2018
                    (ORDER*) select_lex->group_list.first,
2015
2019
                    select_lex->having,
2016
 
                    (order_st*) 0, select_lex,
 
2020
                    (ORDER*) 0, select_lex,
2017
2021
                    select_lex->master_unit()))
2018
2022
    return 1;
2019
2023
  thd->lex->current_select= save_select;
2063
2067
  Item *sel_item;
2064
2068
  List_iterator_fast<Item> li(item_list);
2065
2069
  res_type= STRING_RESULT;
2066
 
  res_field_type= DRIZZLE_TYPE_VARCHAR;
2067
 
  for (uint32_t i= 0; (sel_item= li++); i++)
 
2070
  res_field_type= MYSQL_TYPE_STRING;
 
2071
  for (uint i= 0; (sel_item= li++); i++)
2068
2072
  {
2069
2073
    item->max_length= sel_item->max_length;
2070
2074
    res_type= sel_item->result_type();
2106
2110
  }
2107
2111
}
2108
2112
 
2109
 
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row __attribute__((unused)))
 
2113
void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row __attribute__((__unused__)))
2110
2114
{
2111
2115
  //this never should be called
2112
2116
  assert(0);
2184
2188
        pushed down into the subquery. Those optimizations are ref[_or_null]
2185
2189
        acceses. Change them to be full table scans.
2186
2190
      */
2187
 
      for (uint32_t i=join->const_tables ; i < join->tables ; i++)
 
2191
      for (uint i=join->const_tables ; i < join->tables ; i++)
2188
2192
      {
2189
2193
        JOIN_TAB *tab=join->join_tab+i;
2190
2194
        if (tab && tab->keyuse)
2191
2195
        {
2192
 
          for (uint32_t i= 0; i < tab->ref.key_parts; i++)
 
2196
          for (uint i= 0; i < tab->ref.key_parts; i++)
2193
2197
          {
2194
2198
            bool *cond_guard= tab->ref.cond_guards[i];
2195
2199
            if (cond_guard && !*cond_guard)
2260
2264
int subselect_uniquesubquery_engine::scan_table()
2261
2265
{
2262
2266
  int error;
2263
 
  Table *table= tab->table;
 
2267
  TABLE *table= tab->table;
2264
2268
 
2265
2269
  if (table->file->inited)
2266
2270
    table->file->ha_index_end();
2274
2278
    error=table->file->rnd_next(table->record[0]);
2275
2279
    if (error && error != HA_ERR_END_OF_FILE)
2276
2280
    {
2277
 
      error= table->report_error(error);
 
2281
      error= report_error(table, error);
2278
2282
      break;
2279
2283
    }
2280
2284
    /* No more rows */
2422
2426
int subselect_uniquesubquery_engine::exec()
2423
2427
{
2424
2428
  int error;
2425
 
  Table *table= tab->table;
 
2429
  TABLE *table= tab->table;
2426
2430
  empty_result_set= true;
2427
2431
  table->status= 0;
2428
2432
 
2450
2454
                                     HA_READ_KEY_EXACT);
2451
2455
  if (error &&
2452
2456
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2453
 
    error= table->report_error(error);
 
2457
    error= report_error(table, error);
2454
2458
  else
2455
2459
  {
2456
2460
    error= 0;
2524
2528
{
2525
2529
  int error;
2526
2530
  bool null_finding= 0;
2527
 
  Table *table= tab->table;
 
2531
  TABLE *table= tab->table;
2528
2532
 
2529
2533
  ((Item_in_subselect *) item)->value= 0;
2530
2534
  empty_result_set= true;
2563
2567
                                     HA_READ_KEY_EXACT);
2564
2568
  if (error &&
2565
2569
      error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
2566
 
    error= table->report_error(error);
 
2570
    error= report_error(table, error);
2567
2571
  else
2568
2572
  {
2569
2573
    for (;;)
2586
2590
                                            tab->ref.key_length);
2587
2591
        if (error && error != HA_ERR_END_OF_FILE)
2588
2592
        {
2589
 
          error= table->report_error(error);
 
2593
          error= report_error(table, error);
2590
2594
          break;
2591
2595
        }
2592
2596
      }
2606
2610
}
2607
2611
 
2608
2612
 
2609
 
uint32_t subselect_single_select_engine::cols()
 
2613
uint subselect_single_select_engine::cols()
2610
2614
{
2611
2615
  return select_lex->item_list.elements;
2612
2616
}
2613
2617
 
2614
2618
 
2615
 
uint32_t subselect_union_engine::cols()
 
2619
uint subselect_union_engine::cols()
2616
2620
{
2617
2621
  return unit->types.elements;
2618
2622
}
2619
2623
 
2620
2624
 
2621
 
uint8_t subselect_single_select_engine::uncacheable()
 
2625
uint8 subselect_single_select_engine::uncacheable()
2622
2626
{
2623
2627
  return select_lex->uncacheable;
2624
2628
}
2625
2629
 
2626
2630
 
2627
 
uint8_t subselect_union_engine::uncacheable()
 
2631
uint8 subselect_union_engine::uncacheable()
2628
2632
{
2629
2633
  return unit->uncacheable;
2630
2634
}
2648
2652
}
2649
2653
 
2650
2654
 
2651
 
table_map subselect_engine::calc_const_tables(TableList *table)
 
2655
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
2652
2656
{
2653
2657
  table_map map= 0;
2654
2658
  for (; table; table= table->next_leaf)
2655
2659
  {
2656
 
    Table *tbl= table->table;
 
2660
    TABLE *tbl= table->table;
2657
2661
    if (tbl && tbl->const_table)
2658
2662
      map|= tbl->map;
2659
2663
  }
2663
2667
 
2664
2668
table_map subselect_single_select_engine::upper_select_const_tables()
2665
2669
{
2666
 
  return calc_const_tables((TableList *) select_lex->outer_select()->
 
2670
  return calc_const_tables((TABLE_LIST *) select_lex->outer_select()->
2667
2671
                           leaf_tables);
2668
2672
}
2669
2673
 
2670
2674
 
2671
2675
table_map subselect_union_engine::upper_select_const_tables()
2672
2676
{
2673
 
  return calc_const_tables((TableList *) unit->outer_select()->leaf_tables);
 
2677
  return calc_const_tables((TABLE_LIST *) unit->outer_select()->leaf_tables);
2674
2678
}
2675
2679
 
2676
2680
 
2724
2728
{
2725
2729
  KEY *key_info= tab->table->key_info + tab->ref.key;
2726
2730
  str->append(STRING_WITH_LEN("<primary_index_lookup>("));
2727
 
  for (uint32_t i= 0; i < key_info->key_parts; i++)
 
2731
  for (uint i= 0; i < key_info->key_parts; i++)
2728
2732
    tab->ref.items[i]->print(str);
2729
2733
  str->append(STRING_WITH_LEN(" in "));
2730
2734
  str->append(tab->table->s->table_name.str, tab->table->s->table_name.length);
2819
2823
    true  error
2820
2824
*/
2821
2825
 
2822
 
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((unused)),
2823
 
                                                    select_result_interceptor *res __attribute__((unused)))
 
2826
bool subselect_uniquesubquery_engine::change_result(Item_subselect *si __attribute__((__unused__)),
 
2827
                                                    select_result_interceptor *res __attribute__((__unused__)))
2824
2828
{
2825
2829
  assert(0);
2826
2830
  return true;
2922
2926
  /* The result sink where we will materialize the subquery result. */
2923
2927
  select_union  *tmp_result_sink;
2924
2928
  /* The table into which the subquery is materialized. */
2925
 
  Table         *tmp_table;
 
2929
  TABLE         *tmp_table;
2926
2930
  KEY           *tmp_key; /* The only index on the temporary table. */
2927
 
  uint32_t          tmp_key_parts; /* Number of keyparts in tmp_key. */
 
2931
  uint          tmp_key_parts; /* Number of keyparts in tmp_key. */
2928
2932
  Item_in_subselect *item_in= (Item_in_subselect *) item;
2929
2933
 
2930
2934
  /* 1. Create/initialize materialization related objects. */
2960
2964
      tmp_table->s->uniques ||
2961
2965
      tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
2962
2966
      tmp_table->key_info->key_parts > tmp_table->file->max_key_parts());
2963
 
    tmp_table->free_tmp_table(thd);
 
2967
    free_tmp_table(thd, tmp_table);
2964
2968
    delete result;
2965
2969
    result= NULL;
2966
2970
    return(true);
2989
2993
  tab->ref.key= 0; /* The only temp table index. */
2990
2994
  tab->ref.key_length= tmp_key->key_length;
2991
2995
  if (!(tab->ref.key_buff=
2992
 
        (unsigned char*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
 
2996
        (uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
2993
2997
      !(tab->ref.key_copy=
2994
2998
        (store_key**) thd->alloc((sizeof(store_key*) *
2995
2999
                                  (tmp_key_parts + 1)))) ||
2999
3003
 
3000
3004
  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
3001
3005
  store_key **ref_key= tab->ref.key_copy;
3002
 
  unsigned char *cur_ref_buff= tab->ref.key_buff;
 
3006
  uchar *cur_ref_buff= tab->ref.key_buff;
3003
3007
  
3004
 
  for (uint32_t i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
 
3008
  for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
3005
3009
  {
3006
3010
    tab->ref.items[i]= item_in->left_expr->element_index(i);
3007
3011
    int null_count= test(cur_key_part->field->real_maybe_null());
3051
3055
{
3052
3056
  delete result;
3053
3057
  if (tab)
3054
 
    tab->table->free_tmp_table(thd);
 
3058
    free_tmp_table(thd, tab->table);
3055
3059
}
3056
3060
 
3057
3061