~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Monty Taylor
  • Date: 2011-03-10 18:09:05 UTC
  • mfrom: (2225.2.2 refactor)
  • mto: This revision was merged to the branch mainline in revision 2228.
  • Revision ID: mordred@inaugust.com-20110310180905-ttx05t7q7ff6nl7c
Merge Olad: Refactoring

Show diffs side-by-side

added added

removed removed

Lines of Context:
202
202
    true  an error occured
203
203
    false ok
204
204
*/
205
 
bool fix_inner_refs(Session *session, 
206
 
                    List<Item> &all_fields, 
207
 
                    Select_Lex *select, 
 
205
bool fix_inner_refs(Session *session,
 
206
                    List<Item> &all_fields,
 
207
                    Select_Lex *select,
208
208
                    Item **ref_pointer_array)
209
209
{
210
210
  Item_outer_ref *ref;
356
356
*/
357
357
bool select_query(Session *session,
358
358
                  Item ***rref_pointer_array,
359
 
                  TableList *tables, 
360
 
                  uint32_t wild_num, 
 
359
                  TableList *tables,
 
360
                  uint32_t wild_num,
361
361
                  List<Item> &fields,
362
 
                  COND *conds, 
363
 
                  uint32_t og_num,  
 
362
                  COND *conds,
 
363
                  uint32_t og_num,
364
364
                  Order *order,
365
365
                  Order *group,
366
 
                  Item *having, 
 
366
                  Item *having,
367
367
                  uint64_t select_options,
368
 
                  select_result *result, 
 
368
                  select_result *result,
369
369
                  Select_Lex_Unit *unit,
370
370
                  Select_Lex *select_lex)
371
371
{
545
545
                         DYNAMIC_ARRAY *keyuse,
546
546
                         JoinTable *join_tab,
547
547
                         uint32_t tables,
548
 
                         COND *cond, 
 
548
                         COND *cond,
549
549
                         COND_EQUAL *,
550
550
                         table_map normal_tables,
551
551
                         Select_Lex *select_lex,
562
562
    except BETWEEN predicates that have 3 arguments and
563
563
    IN predicates.
564
564
    This any predicate if it's not BETWEEN/IN can be used
565
 
    directly to fill at most 2 array elements, either of KeyField 
 
565
    directly to fill at most 2 array elements, either of KeyField
566
566
    or SargableParam type. For a BETWEEN predicate 3 elements
567
567
    can be filled as this predicate is considered as
568
568
    saragable with respect to each of its argument.
662
662
          use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
663
663
        if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
664
664
        {
665
 
          if (prev->getKeypart() + 1 < use->getKeypart() || 
 
665
          if (prev->getKeypart() + 1 < use->getKeypart() ||
666
666
              ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
667
667
            continue;                           /* remove */
668
668
        }
957
957
    *e1= e2;
958
958
}
959
959
 
960
 
bool create_ref_for_key(Join *join, 
961
 
                        JoinTable *j, 
 
960
bool create_ref_for_key(Join *join,
 
961
                        JoinTable *j,
962
962
                        optimizer::KeyUse *org_keyuse,
963
963
                        table_map used_tables)
964
964
{
1634
1634
    false   otherwise
1635
1635
*/
1636
1636
static bool check_row_equality(Session *session,
1637
 
                               Item *left_row, 
 
1637
                               Item *left_row,
1638
1638
                               Item_row *right_row,
1639
1639
                               COND_EQUAL *cond_equal,
1640
1640
                               List<Item>* eq_list)
2402
2402
      args[1]= tmp;
2403
2403
      func->update_used_tables();
2404
2404
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2405
 
                and_father != cond && 
 
2405
                and_father != cond &&
2406
2406
          ! left_item->const_item())
2407
2407
      {
2408
2408
        cond->marker=1;
2425
2425
      value= tmp;
2426
2426
      func->update_used_tables();
2427
2427
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2428
 
          and_father != cond && 
 
2428
          and_father != cond &&
2429
2429
          ! right_item->const_item())
2430
2430
      {
2431
2431
        args[0]= args[1];                       // For easy check
2469
2469
  return conds;
2470
2470
}
2471
2471
 
2472
 
static void propagate_cond_constants(Session *session, 
2473
 
                                     list<COND_CMP>& save_list, 
2474
 
                                     COND *and_father, 
 
2472
static void propagate_cond_constants(Session *session,
 
2473
                                     list<COND_CMP>& save_list,
 
2474
                                     COND *and_father,
2475
2475
                                     COND *cond)
2476
2476
{
2477
2477
  if (cond->type() == Item::COND_ITEM)
2730
2730
      if (*cond_value == Item::COND_UNDEF)
2731
2731
              *cond_value= tmp_cond_value;
2732
2732
 
2733
 
      switch (tmp_cond_value) 
 
2733
      switch (tmp_cond_value)
2734
2734
      {
2735
2735
        case Item::COND_OK:                     /* Not true or false */
2736
2736
          if (and_level || (*cond_value == Item::COND_FALSE))
2762
2762
      return (COND*) NULL;
2763
2763
 
2764
2764
    if (((Item_cond*) cond)->argument_list()->size() == 1)
2765
 
    {                                           
 
2765
    {
2766
2766
      /* Argument list contains only one element, so reduce it so a single item, then remove list */
2767
2767
      item= &((Item_cond*) cond)->argument_list()->front();
2768
2768
      ((Item_cond*) cond)->argument_list()->clear();
2786
2786
    if (args[0]->type() == Item::FIELD_ITEM)
2787
2787
    {
2788
2788
      Field *field= ((Item_field*) args[0])->field;
2789
 
      if (field->flags & AUTO_INCREMENT_FLAG 
2790
 
          && ! field->getTable()->maybe_null 
 
2789
      if (field->flags & AUTO_INCREMENT_FLAG
 
2790
          && ! field->getTable()->maybe_null
2791
2791
          && session->options & OPTION_AUTO_IS_NULL
2792
2792
          && (
2793
 
            session->first_successful_insert_id_in_prev_stmt > 0 
 
2793
            session->first_successful_insert_id_in_prev_stmt > 0
2794
2794
            && session->substitute_null_with_insert_id
2795
2795
            )
2796
2796
          )
2817
2817
#ifdef NOTDEFINED
2818
2818
      /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
2819
2819
      else if (
2820
 
          ((field->type() == DRIZZLE_TYPE_DATE) || (field->type() == DRIZZLE_TYPE_DATETIME)) 
2821
 
          && (field->flags & NOT_NULL_FLAG) 
 
2820
          ((field->type() == DRIZZLE_TYPE_DATE) || (field->type() == DRIZZLE_TYPE_DATETIME))
 
2821
          && (field->flags & NOT_NULL_FLAG)
2822
2822
          && ! field->table->maybe_null)
2823
2823
      {
2824
2824
        COND *new_cond;
2857
2857
    return (COND *) NULL;
2858
2858
  }
2859
2859
  else if ((*cond_value= cond->eq_cmp_result()) != Item::COND_OK)
2860
 
  {                                             
 
2860
  {
2861
2861
    /* boolan compare function */
2862
2862
    Item *left_item=    ((Item_func*) cond)->arguments()[0];
2863
2863
    Item *right_item= ((Item_func*) cond)->arguments()[1];
4063
4063
        if (fix)
4064
4064
          new_cond->argument_list()->push_back(fix);
4065
4065
      }
4066
 
      switch (new_cond->argument_list()->size()) 
 
4066
      switch (new_cond->argument_list()->size())
4067
4067
      {
4068
4068
        case 0:
4069
4069
          return (COND*) 0;                     // Always true
4166
4166
      if (field->eq(key_part->field) &&
4167
4167
          !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
4168
4168
          //If field can be NULL, we should not remove this predicate, as
4169
 
          //it may lead to non-rejection of NULL values. 
 
4169
          //it may lead to non-rejection of NULL values.
4170
4170
          !(field->real_maybe_null()))
4171
4171
      {
4172
4172
        return table->reginfo.join_tab->ref.items[part];
4860
4860
 
4861
4861
        /* ORDER BY range_key DESC */
4862
4862
        tmp= new optimizer::QuickSelectDescending((optimizer::QuickRangeSelect*)(select->quick),
4863
 
                                                  used_key_parts, 
 
4863
                                                  used_key_parts,
4864
4864
                                                  &error);
4865
4865
        if (! tmp || error)
4866
4866
        {
4980
4980
        For impossible ranges (like when doing a lookup on NULL on a NOT NULL
4981
4981
        field, quick will contain an empty record set.
4982
4982
      */
4983
 
      if (! (select->quick= (optimizer::get_quick_select_for_ref(session, 
4984
 
                                                                 table, 
 
4983
      if (! (select->quick= (optimizer::get_quick_select_for_ref(session,
 
4984
                                                                 table,
4985
4985
                                                                 &tab->ref,
4986
4986
                                                                 tab->found_records))))
4987
4987
      {
5108
5108
  @note
5109
5109
    Note that this will not work on tables with blobs!
5110
5110
*/
5111
 
int remove_dup_with_hash_index(Session *session, 
 
5111
int remove_dup_with_hash_index(Session *session,
5112
5112
                               Table *table,
5113
5113
                               uint32_t field_count,
5114
5114
                               Field **first_field,
5117
5117
{
5118
5118
  unsigned char *key_pos, *record=table->getInsertRecord();
5119
5119
  int error;
5120
 
  Cursor *cursor= table->cursor;
 
5120
  Cursor &cursor= *table->cursor;
5121
5121
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5122
5122
  uint32_t *field_length;
5123
5123
  HASH hash;
5124
 
  std::vector<unsigned char> key_buffer;
5125
 
  std::vector<uint32_t> field_lengths;
5126
 
 
5127
 
  key_buffer.resize((key_length + extra_length) * (long) cursor->stats.records);
5128
 
  field_lengths.resize(field_count);
 
5124
  std::vector<unsigned char> key_buffer((key_length + extra_length) * (long) cursor.stats.records);
 
5125
  std::vector<uint32_t> field_lengths(field_count);
5129
5126
 
5130
5127
  {
5131
5128
    Field **ptr;
5142
5139
    extra_length= ALIGN_SIZE(key_length)-key_length;
5143
5140
  }
5144
5141
 
5145
 
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor->stats.records, 0,
5146
 
                key_length, (hash_get_key) 0, 0, 0))
5147
 
  {
5148
 
    return(1);
5149
 
  }
 
5142
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor.stats.records, 0, key_length, (hash_get_key) 0, 0, 0))
 
5143
    return 1;
5150
5144
 
5151
 
  if ((error= cursor->startTableScan(1)))
 
5145
  if ((error= cursor.startTableScan(1)))
5152
5146
    goto err;
5153
5147
 
5154
5148
  key_pos= &key_buffer[0];
5155
5149
  for (;;)
5156
5150
  {
5157
 
    unsigned char *org_key_pos;
5158
5151
    if (session->getKilled())
5159
5152
    {
5160
5153
      session->send_kill_message();
5161
5154
      error=0;
5162
5155
      goto err;
5163
5156
    }
5164
 
    if ((error=cursor->rnd_next(record)))
 
5157
    if ((error=cursor.rnd_next(record)))
5165
5158
    {
5166
5159
      if (error == HA_ERR_RECORD_DELETED)
5167
5160
        continue;
5171
5164
    }
5172
5165
    if (having && !having->val_int())
5173
5166
    {
5174
 
      if ((error=cursor->deleteRecord(record)))
 
5167
      if ((error=cursor.deleteRecord(record)))
5175
5168
        goto err;
5176
5169
      continue;
5177
5170
    }
5178
5171
 
5179
5172
    /* copy fields to key buffer */
5180
 
    org_key_pos= key_pos;
 
5173
    unsigned char* org_key_pos= key_pos;
5181
5174
    field_length= &field_lengths[0];
5182
5175
    for (Field **ptr= first_field ; *ptr ; ptr++)
5183
5176
    {
5188
5181
    if (hash_search(&hash, org_key_pos, key_length))
5189
5182
    {
5190
5183
      /* Duplicated found ; Remove the row */
5191
 
      if ((error=cursor->deleteRecord(record)))
 
5184
      if ((error=cursor.deleteRecord(record)))
5192
5185
        goto err;
5193
5186
    }
5194
5187
    else
5196
5189
    key_pos+=extra_length;
5197
5190
  }
5198
5191
  hash_free(&hash);
5199
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5200
 
  (void) cursor->endTableScan();
5201
 
  return(0);
 
5192
  cursor.extra(HA_EXTRA_NO_CACHE);
 
5193
  (void) cursor.endTableScan();
 
5194
  return 0;
5202
5195
 
5203
5196
err:
5204
5197
  hash_free(&hash);
5205
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5206
 
  (void) cursor->endTableScan();
 
5198
  cursor.extra(HA_EXTRA_NO_CACHE);
 
5199
  (void) cursor.endTableScan();
5207
5200
  if (error)
5208
5201
    table->print_error(error,MYF(0));
5209
 
  return(1);
 
5202
  return 1;
5210
5203
}
5211
5204
 
5212
5205
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
5337
5330
  @retval
5338
5331
    true  if error occurred
5339
5332
*/
5340
 
static bool find_order_in_list(Session *session, 
5341
 
                               Item **ref_pointer_array, 
 
5333
static bool find_order_in_list(Session *session,
 
5334
                               Item **ref_pointer_array,
5342
5335
                               TableList *tables,
5343
5336
                               Order *order,
5344
5337
                               List<Item> &fields,
5872
5865
             !real_pos->with_sum_func)
5873
5866
    {                                           // Save for send fields
5874
5867
      pos= real_pos;
5875
 
      /* 
 
5868
      /*
5876
5869
        @todo In most cases this result will be sent to the user.
5877
5870
        This should be changed to use copy_int or copy_real depending
5878
5871
        on how the value is to be used: In some cases this may be an