~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Lee Bieber
  • Date: 2010-12-15 16:23:36 UTC
  • mfrom: (1995.1.2 build)
  • Revision ID: kalebral@gmail.com-20101215162336-juntyt4gw4vgohg4
Merge Andrew - fix bug 628912: Crash / segfault in drizzled::Item_func::arguments (this=0x35) at ./drizzled/function/func.h
Merge Andrew - 663919: next query after KILL QUERY will error

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
  @file
18
18
 
19
19
  @brief
20
 
  select_query and join optimization
 
20
  mysql_select and join optimization
21
21
 
22
22
  @defgroup Query_Optimizer  Query Optimizer
23
23
  @{
52
52
#include "drizzled/records.h"
53
53
#include "drizzled/internal/iocache.h"
54
54
#include "drizzled/drizzled.h"
55
 
#include "drizzled/plugin/storage_engine.h"
56
55
 
57
56
#include "drizzled/sql_union.h"
58
57
#include "drizzled/optimizer/key_field.h"
79
78
static Item* part_of_refkey(Table *form,Field *field);
80
79
static bool cmp_buffer_with_ref(JoinTable *tab);
81
80
static void change_cond_ref_to_const(Session *session,
82
 
                                     list<COND_CMP>& save_list,
 
81
                                     vector<COND_CMP*>& save_list,
83
82
                                     Item *and_father,
84
83
                                     Item *cond,
85
84
                                     Item *field,
132
131
    unit->set_limit(unit->global_parameters);
133
132
    session->session_marker= 0;
134
133
    /*
135
 
      'options' of select_query will be set in JOIN, as far as JOIN for
 
134
      'options' of mysql_select will be set in JOIN, as far as JOIN for
136
135
      every PS/SP execution new, we will not need reset this flag if
137
136
      setup_tables_done_option changed for next rexecution
138
137
    */
139
 
    res= select_query(session,
140
 
                      &select_lex->ref_pointer_array,
 
138
    res= mysql_select(session, &select_lex->ref_pointer_array,
141
139
                      (TableList*) select_lex->table_list.first,
142
 
                      select_lex->with_wild,
143
 
                      select_lex->item_list,
 
140
                      select_lex->with_wild, select_lex->item_list,
144
141
                      select_lex->where,
145
142
                      select_lex->order_list.elements +
146
143
                      select_lex->group_list.elements,
271
268
 
272
269
/*****************************************************************************
273
270
  Check fields, find best join, do the select and output fields.
274
 
  select_query assumes that all tables are already opened
 
271
  mysql_select assumes that all tables are already opened
275
272
*****************************************************************************/
276
273
 
277
274
/*
351
348
  @retval
352
349
    true   an error
353
350
*/
354
 
bool select_query(Session *session,
 
351
bool mysql_select(Session *session,
355
352
                  Item ***rref_pointer_array,
356
353
                  TableList *tables, 
357
354
                  uint32_t wild_num, 
573
570
  sz= sizeof(optimizer::KeyField) *
574
571
      (((session->lex->current_select->cond_count+1)*2 +
575
572
        session->lex->current_select->between_count)*m+1);
576
 
  if (! (key_fields= (optimizer::KeyField*) session->getMemRoot()->allocate(sz)))
 
573
  if (! (key_fields= (optimizer::KeyField*) session->alloc(sz)))
577
574
    return true;
578
575
  and_level= 0;
579
576
  field= end= key_fields;
932
929
 
933
930
  /*
934
931
    we should restore old value of count_cuted_fields because
935
 
    store_val_in_field can be called from insert_query
 
932
    store_val_in_field can be called from mysql_insert
936
933
    with select_insert, which make count_cuted_fields= 1
937
934
   */
938
935
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
1005
1002
  j->ref.key_length=length;
1006
1003
  j->ref.key=(int) key;
1007
1004
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
1008
 
      !(j->ref.key_copy= (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
1005
      !(j->ref.key_copy= (StoredKey**) session->alloc((sizeof(StoredKey*) *
1009
1006
               (keyparts+1)))) ||
1010
 
      !(j->ref.items=    (Item**) session->getMemRoot()->allocate(sizeof(Item*)*keyparts)) ||
1011
 
      !(j->ref.cond_guards= (bool**) session->getMemRoot()->allocate(sizeof(uint*)*keyparts)))
 
1007
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
 
1008
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
1012
1009
  {
1013
1010
    return(true);
1014
1011
  }
2308
2305
  @param cond       condition whose multiple equalities are to be checked
2309
2306
  @param table      constant table that has been read
2310
2307
*/
2311
 
void update_const_equal_items(COND *cond, JoinTable *tab)
 
2308
static void update_const_equal_items(COND *cond, JoinTable *tab)
2312
2309
{
2313
2310
  if (!(cond->used_tables() & tab->table->map))
2314
2311
    return;
2365
2362
  and_level
2366
2363
*/
2367
2364
static void change_cond_ref_to_const(Session *session,
2368
 
                                     list<COND_CMP>& save_list,
 
2365
                                     vector<COND_CMP*>& save_list,
2369
2366
                                     Item *and_father,
2370
2367
                                     Item *cond,
2371
2368
                                     Item *field,
2378
2375
    Item *item;
2379
2376
    while ((item=li++))
2380
2377
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2381
 
 
2382
2378
    return;
2383
2379
  }
2384
2380
  if (cond->eq_cmp_result() == Item::COND_OK)
2407
2403
          ! left_item->const_item())
2408
2404
      {
2409
2405
        cond->marker=1;
2410
 
        save_list.push_back( COND_CMP(and_father, func) );
 
2406
        COND_CMP *new_cond_cmp= new COND_CMP(and_father, func);
 
2407
        save_list.push_back( new_cond_cmp );
2411
2408
      }
2412
2409
      func->set_cmp_func();
2413
2410
    }
2432
2429
        args[0]= args[1];                       // For easy check
2433
2430
        session->change_item_tree(args + 1, value);
2434
2431
        cond->marker=1;
2435
 
        save_list.push_back( COND_CMP(and_father, func) );
 
2432
        COND_CMP *new_cond_cmp= new COND_CMP(and_father, func);
 
2433
        save_list.push_back( new_cond_cmp );
2436
2434
      }
2437
2435
      func->set_cmp_func();
2438
2436
    }
2471
2469
}
2472
2470
 
2473
2471
static void propagate_cond_constants(Session *session, 
2474
 
                                     list<COND_CMP>& save_list, 
 
2472
                                     vector<COND_CMP*>& save_list, 
2475
2473
                                     COND *and_father, 
2476
2474
                                     COND *cond)
2477
2475
{
2480
2478
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2481
2479
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2482
2480
    Item *item;
2483
 
    list<COND_CMP> save;
 
2481
    vector<COND_CMP*> save;
2484
2482
    while ((item=li++))
2485
2483
    {
2486
2484
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2488
2486
    if (and_level)
2489
2487
    {
2490
2488
      // Handle other found items
2491
 
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2489
      for (vector<COND_CMP*>::iterator iter= save.begin(); iter < save.end(); iter++)
2492
2490
      {
2493
 
        Item **args= iter->second->arguments();
2494
 
        if (not args[0]->const_item())
 
2491
        Item **args= (*iter)->second->arguments();
 
2492
        if (!args[0]->const_item())
2495
2493
        {
2496
 
          change_cond_ref_to_const(session, save, iter->first,
2497
 
                                   iter->first, args[0], args[1] );
 
2494
          change_cond_ref_to_const( session, save_list, (*iter)->first,
 
2495
                                    (*iter)->first, args[0], args[1] );
2498
2496
        }
2499
2497
      }
2500
2498
    }
2607
2605
         position:
2608
2606
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2609
2607
             joins) we've opened but didn't close.
2610
 
          2. {each NestedJoin class not simplified away}->counter - number
 
2608
          2. {each nested_join_st structure not simplified away}->counter - number
2611
2609
             of this nested join's children that have already been added to to
2612
2610
             the partial join order.
2613
2611
  @endverbatim
2685
2683
                             &join->cond_equal);
2686
2684
 
2687
2685
    /* change field = field to field = const for each found field = const */
2688
 
    list<COND_CMP> temp;
 
2686
    vector<COND_CMP*> temp;
2689
2687
    propagate_cond_constants(session, temp, conds, conds);
2690
2688
    /*
2691
2689
      Remove all instances of item == item
3054
3052
    table->emptyRecord();
3055
3053
    if (table->group && join->tmp_table_param.sum_func_count &&
3056
3054
        table->getShare()->sizeKeys() && !table->cursor->inited)
3057
 
    {
3058
 
      int tmp_error;
3059
 
      tmp_error= table->cursor->startIndexScan(0, 0);
3060
 
      if (tmp_error != 0)
3061
 
      {
3062
 
        table->print_error(tmp_error, MYF(0));
3063
 
        return -1;
3064
 
      }
3065
 
    }
 
3055
      table->cursor->startIndexScan(0, 0);
3066
3056
  }
3067
3057
  /* Set up select_end */
3068
3058
  Next_select_func end_select= setup_end_select_func(join);
3368
3358
  return 0;
3369
3359
}
3370
3360
 
 
3361
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
 
3362
{
 
3363
  int error;
 
3364
  Table *table=tab->table;
 
3365
  table->const_table=1;
 
3366
  table->null_row=0;
 
3367
  table->status=STATUS_NO_RECORD;
 
3368
 
 
3369
  if (tab->type == AM_SYSTEM)
 
3370
  {
 
3371
    if ((error=join_read_system(tab)))
 
3372
    {                                           // Info for DESCRIBE
 
3373
      tab->info="const row not found";
 
3374
      /* Mark for EXPLAIN that the row was not found */
 
3375
      pos->setFanout(0.0);
 
3376
      pos->clearRefDependMap();
 
3377
      if (! table->maybe_null || error > 0)
 
3378
        return(error);
 
3379
    }
 
3380
  }
 
3381
  else
 
3382
  {
 
3383
    if (! table->key_read && 
 
3384
        table->covering_keys.test(tab->ref.key) && 
 
3385
        ! table->no_keyread &&
 
3386
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
 
3387
    {
 
3388
      table->key_read=1;
 
3389
      table->cursor->extra(HA_EXTRA_KEYREAD);
 
3390
      tab->index= tab->ref.key;
 
3391
    }
 
3392
    error=join_read_const(tab);
 
3393
    if (table->key_read)
 
3394
    {
 
3395
      table->key_read=0;
 
3396
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3397
    }
 
3398
    if (error)
 
3399
    {
 
3400
      tab->info="unique row not found";
 
3401
      /* Mark for EXPLAIN that the row was not found */
 
3402
      pos->setFanout(0.0);
 
3403
      pos->clearRefDependMap();
 
3404
      if (!table->maybe_null || error > 0)
 
3405
        return(error);
 
3406
    }
 
3407
  }
 
3408
  if (*tab->on_expr_ref && !table->null_row)
 
3409
  {
 
3410
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
 
3411
      table->mark_as_null_row();
 
3412
  }
 
3413
  if (!table->null_row)
 
3414
    table->maybe_null=0;
 
3415
 
 
3416
  /* Check appearance of new constant items in Item_equal objects */
 
3417
  Join *join= tab->join;
 
3418
  if (join->conds)
 
3419
    update_const_equal_items(join->conds, tab);
 
3420
  TableList *tbl;
 
3421
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
 
3422
  {
 
3423
    TableList *embedded;
 
3424
    TableList *embedding= tbl;
 
3425
    do
 
3426
    {
 
3427
      embedded= embedding;
 
3428
      if (embedded->on_expr)
 
3429
         update_const_equal_items(embedded->on_expr, tab);
 
3430
      embedding= embedded->getEmbedding();
 
3431
    }
 
3432
    while (embedding &&
 
3433
           embedding->getNestedJoin()->join_list.head() == embedded);
 
3434
  }
 
3435
 
 
3436
  return(0);
 
3437
}
 
3438
 
 
3439
int join_read_system(JoinTable *tab)
 
3440
{
 
3441
  Table *table= tab->table;
 
3442
  int error;
 
3443
  if (table->status & STATUS_GARBAGE)           // If first read
 
3444
  {
 
3445
    if ((error=table->cursor->read_first_row(table->getInsertRecord(),
 
3446
                                           table->getShare()->getPrimaryKey())))
 
3447
    {
 
3448
      if (error != HA_ERR_END_OF_FILE)
 
3449
        return table->report_error(error);
 
3450
      tab->table->mark_as_null_row();
 
3451
      table->emptyRecord();                     // Make empty record
 
3452
      return -1;
 
3453
    }
 
3454
    table->storeRecord();
 
3455
  }
 
3456
  else if (!table->status)                      // Only happens with left join
 
3457
    table->restoreRecord();                     // restore old record
 
3458
  table->null_row=0;
 
3459
  return table->status ? -1 : 0;
 
3460
}
 
3461
 
3371
3462
/**
3372
3463
  Read a (constant) table when there is at most one matching row.
3373
3464
 
3439
3530
 
3440
3531
  if (!table->cursor->inited)
3441
3532
  {
3442
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3443
 
    if (error != 0)
3444
 
    {
3445
 
      table->print_error(error, MYF(0));
3446
 
    }
 
3533
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3447
3534
  }
3448
3535
 
3449
3536
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3491
3578
 
3492
3579
  /* Initialize the index first */
3493
3580
  if (!table->cursor->inited)
3494
 
  {
3495
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3496
 
    if (error != 0)
3497
 
      return table->report_error(error);
3498
 
  }
 
3581
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3499
3582
 
3500
3583
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3501
3584
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3529
3612
  Table *table= tab->table;
3530
3613
 
3531
3614
  if (!table->cursor->inited)
3532
 
  {
3533
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3534
 
    if (error != 0)
3535
 
      return table->report_error(error);
3536
 
  }
 
3615
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3537
3616
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3538
3617
    return -1;
3539
3618
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
3648
3727
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3649
3728
    return 1;
3650
3729
 
3651
 
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
3652
 
    return 1;
 
3730
  tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true);
3653
3731
 
3654
3732
  return (*tab->read_record.read_record)(&tab->read_record);
3655
3733
}
3682
3760
  }
3683
3761
 
3684
3762
  if (!table->cursor->inited)
3685
 
  {
3686
 
    error= table->cursor->startIndexScan(tab->index, tab->sorted);
3687
 
    if (error != 0)
3688
 
    {
3689
 
      table->report_error(error);
3690
 
      return -1;
3691
 
    }
3692
 
  }
 
3763
    table->cursor->startIndexScan(tab->index, tab->sorted);
3693
3764
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
3694
3765
  {
3695
3766
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
3748
3819
  tab->read_record.index=tab->index;
3749
3820
  tab->read_record.record=table->getInsertRecord();
3750
3821
  if (!table->cursor->inited)
3751
 
  {
3752
 
    error= table->cursor->startIndexScan(tab->index, 1);
3753
 
    if (error != 0)
3754
 
      return table->report_error(error);
3755
 
  }
 
3822
    table->cursor->startIndexScan(tab->index, 1);
3756
3823
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
3757
3824
    return table->report_error(error);
3758
3825
 
3832
3899
              error=join->result->send_data(*join->fields) ? 1 : 0;
3833
3900
            join->send_records++;
3834
3901
          }
3835
 
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
 
3902
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
3836
3903
          {
3837
3904
            if (join->rollup_send_data((uint32_t) (idx+1)))
3838
3905
              error= 1;
3922
3989
            return NESTED_LOOP_ERROR;
3923
3990
          }
3924
3991
        }
3925
 
        if (join->rollup.getState() != Rollup::STATE_NONE)
 
3992
        if (join->rollup.state != ROLLUP::STATE_NONE)
3926
3993
        {
3927
3994
          if (join->rollup_write_data((uint32_t) (idx+1), table))
3928
3995
            return NESTED_LOOP_ERROR;
5031
5098
  org_record=(char*) (record=table->getInsertRecord())+offset;
5032
5099
  new_record=(char*) table->getUpdateRecord()+offset;
5033
5100
 
5034
 
  if ((error= cursor->startTableScan(1)))
5035
 
    goto err;
5036
 
 
 
5101
  cursor->startTableScan(1);
5037
5102
  error=cursor->rnd_next(record);
5038
5103
  for (;;)
5039
5104
  {
5150
5215
    return(1);
5151
5216
  }
5152
5217
 
5153
 
  if ((error= cursor->startTableScan(1)))
5154
 
    goto err;
5155
 
 
 
5218
  cursor->startTableScan(1);
5156
5219
  key_pos= &key_buffer[0];
5157
5220
  for (;;)
5158
5221
  {
5364
5427
    if (!count || count > fields.elements)
5365
5428
    {
5366
5429
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5367
 
               order_item->full_name(), session->where());
 
5430
               order_item->full_name(), session->where);
5368
5431
      return true;
5369
5432
    }
5370
5433
    order->item= ref_pointer_array + count - 1;
5441
5504
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5442
5505
                          ER(ER_NON_UNIQ_ERROR),
5443
5506
                          ((Item_ident*) order_item)->field_name,
5444
 
                          session->where());
 
5507
                          session->where);
5445
5508
    }
5446
5509
  }
5447
5510
 
5483
5546
                List<Item> &all_fields,
5484
5547
                Order *order)
5485
5548
{
5486
 
  session->setWhere("order clause");
 
5549
  session->where="order clause";
5487
5550
  for (; order; order=order->next)
5488
5551
  {
5489
5552
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5534
5597
 
5535
5598
  uint32_t org_fields=all_fields.elements;
5536
5599
 
5537
 
  session->setWhere("group statement");
 
5600
  session->where="group statement";
5538
5601
  for (ord= order; ord; ord= ord->next)
5539
5602
  {
5540
5603
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5637
5700
  {
5638
5701
    if (order->in_field_list)
5639
5702
    {
5640
 
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
 
5703
      Order *ord=(Order*) session->memdup((char*) order,sizeof(Order));
5641
5704
      if (!ord)
5642
5705
        return 0;
5643
5706
      *prev=ord;
6292
6355
{
6293
6356
  /* List is reversed => we should reverse it before using */
6294
6357
  List_iterator_fast<TableList> ti(*tables);
6295
 
  TableList **table= (TableList **)session->getMemRoot()->allocate(sizeof(TableList*) *
 
6358
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
6296
6359
                                                tables->elements);
6297
6360
  if (table == 0)
6298
6361
    return;  // out of memory