diff options
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ad7c095f353..3738a6bad7a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -788,10 +788,15 @@ JOIN::prepare(TABLE_LIST *tables_init, if (mixed_implicit_grouping && tbl->table) tbl->table->maybe_null= 1; } + + uint real_og_num= og_num; + if (skip_order_by && + select_lex != select_lex->master_unit()->global_parameters()) + real_og_num+= select_lex->order_list.elements; if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num)) DBUG_RETURN(-1); - if (select_lex->setup_ref_array(thd, og_num)) + if (select_lex->setup_ref_array(thd, real_og_num)) DBUG_RETURN(-1); ref_ptrs= ref_ptr_array_slice(0); @@ -1722,7 +1727,8 @@ JOIN::optimize_inner() <fields> to ORDER BY <fields>. There are three exceptions: - if skip_sort_order is set (see above), then we can simply skip GROUP BY; - - if we are in a subquery, we don't have to maintain order + - if we are in a subquery, we don't have to maintain order unless there + is a limit clause in the subquery. - we can only rewrite ORDER BY if the ORDER BY fields are 'compatible' with the GROUP BY ones, i.e. either one is a prefix of another. We only check if the ORDER BY is a prefix of GROUP BY. In this case @@ -1734,7 +1740,7 @@ JOIN::optimize_inner() if (!order || test_if_subpart(group_list, order)) { if (skip_sort_order || - select_lex->master_unit()->item) // This is a subquery + (select_lex->master_unit()->item && select_limit == HA_POS_ERROR)) // This is a subquery order= NULL; else order= group_list; @@ -13028,9 +13034,12 @@ COND *Item_cond_and::build_equal_items(THD *thd, COND_EQUAL cond_equal; cond_equal.upper_levels= inherited; + if (check_stack_overrun(thd, STACK_MIN_SIZE, NULL)) + return this; // Fatal error flag is set! + List<Item> eq_list; List<Item> *cond_args= argument_list(); - + List_iterator<Item> li(*cond_args); Item *item; @@ -13040,7 +13049,7 @@ COND *Item_cond_and::build_equal_items(THD *thd, that are subject to substitution by multiple equality items and removing each such predicate from the conjunction after having found/created a multiple equality whose inference the predicate is. - */ + */ while ((item= li++)) { /* @@ -16134,6 +16143,9 @@ setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps, uint field_count) bitmaps+= bitmap_size; my_bitmap_init(&table->cond_set, (my_bitmap_map*) bitmaps, field_count, FALSE); + bitmaps+= bitmap_size; + my_bitmap_init(&table->has_value_set, + (my_bitmap_map*) bitmaps, field_count, FALSE); /* write_set and all_set are copies of read_set */ table->def_write_set= table->def_read_set; table->s->all_set= table->def_read_set; @@ -16309,7 +16321,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, &tmpname, (uint) strlen(path)+1, &group_buff, (group && ! using_unique_constraint ? param->group_length : 0), - &bitmaps, bitmap_buffer_size(field_count)*5, + &bitmaps, bitmap_buffer_size(field_count)*6, NullS)) { if (temp_pool_slot != MY_BIT_NONE) @@ -17039,7 +17051,7 @@ bool Virtual_tmp_table::init(uint field_count) &s, sizeof(*s), &field, (field_count + 1) * sizeof(Field*), &blob_field, (field_count + 1) * sizeof(uint), - &bitmaps, bitmap_buffer_size(field_count) * 5, + &bitmaps, bitmap_buffer_size(field_count) * 6, NullS)) return true; bzero(s, sizeof(*s)); @@ -17844,7 +17856,7 @@ do_select(JOIN *join, Procedure *procedure) } join->procedure= procedure; - join->send_records=0; + join->duplicate_rows= join->send_records=0; if (join->only_const_tables() && !join->need_tmp) { Next_select_func end_select= setup_end_select_func(join, NULL); @@ -17907,7 +17919,7 @@ do_select(JOIN *join, Procedure *procedure) error= join->first_select(join,join_tab,1); } - join->thd->limit_found_rows= join->send_records; + join->thd->limit_found_rows= join->send_records - join->duplicate_rows; if (error == NESTED_LOOP_NO_MORE_ROWS || join->thd->killed == ABORT_QUERY) error= NESTED_LOOP_OK; @@ -19524,7 +19536,12 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), int error; /* result < 0 if row was not accepted and should not be counted */ if ((error= join->result->send_data(*fields))) - DBUG_RETURN(error < 0 ? NESTED_LOOP_OK : NESTED_LOOP_ERROR); + { + if (error > 0) + DBUG_RETURN(NESTED_LOOP_ERROR); + // error < 0 => duplicate row + join->duplicate_rows++; + } } ++join->send_records; @@ -19670,7 +19687,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (error < 0) { /* Duplicate row, don't count */ - join->send_records--; + join->duplicate_rows++; error= 0; } } |