diff options
author | unknown <igor@rurik.mysql.com> | 2006-04-01 02:57:56 -0800 |
---|---|---|
committer | unknown <igor@rurik.mysql.com> | 2006-04-01 02:57:56 -0800 |
commit | a5abc598e5efe21b3599e6f4fda9ab02f6194be3 (patch) | |
tree | de80900626c18453d590c01fd12d6b92f474cdeb /sql/sql_select.cc | |
parent | d5db81aa34da471ab1f4cd84317e85ec83f42fdf (diff) | |
parent | f0bfea2bb0789bd5bcd2a8d85c42dd310e245d1a (diff) | |
download | mariadb-git-a5abc598e5efe21b3599e6f4fda9ab02f6194be3.tar.gz |
Merge rurik.mysql.com:/home/igor/dev/mysql-5.0-0
into rurik.mysql.com:/home/igor/dev/mysql-5.1-0
mysql-test/r/ctype_utf8.result:
Auto merged
mysql-test/r/func_gconcat.result:
Auto merged
mysql-test/r/subselect.result:
Auto merged
sql/field.cc:
Auto merged
sql/ha_heap.cc:
Auto merged
sql/item.cc:
Auto merged
sql/item_cmpfunc.cc:
Auto merged
sql/item_sum.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_table.cc:
Auto merged
storage/myisam/mi_search.c:
Auto merged
storage/ndb/tools/Makefile.am:
Auto merged
strings/ctype-ucs2.c:
Auto merged
tests/mysql_client_test.c:
Auto merged
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 95 |
1 files changed, 82 insertions, 13 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 524f9c7b09b..76bb7f088b5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -136,7 +136,7 @@ static enum_nested_loop_state end_write_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records); static int test_if_group_changed(List<Cached_item> &list); -static int join_read_const_table(JOIN_TAB *tab, POSITION *pos); +static int join_read_const_table(JOIN *join, JOIN_TAB *tab, POSITION *pos); static int join_read_system(JOIN_TAB *tab); static int join_read_const(JOIN_TAB *tab); static int join_read_key(JOIN_TAB *tab); @@ -2153,7 +2153,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, s= p_pos->table; s->type=JT_SYSTEM; join->const_table_map|=s->table->map; - if ((tmp=join_read_const_table(s, p_pos))) + if ((tmp=join_read_const_table(join, s, p_pos))) { if (tmp > 0) DBUG_RETURN(1); // Fatal error @@ -2190,7 +2190,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, s->type=JT_SYSTEM; join->const_table_map|=table->map; set_position(join,const_count++,s,(KEYUSE*) 0); - if ((tmp= join_read_const_table(s,join->positions+const_count-1))) + if ((tmp= join_read_const_table(join, s, + join->positions+const_count-1))) { if (tmp > 0) DBUG_RETURN(1); // Fatal error @@ -2242,7 +2243,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if (create_ref_for_key(join, s, start_keyuse, found_const_table_map)) DBUG_RETURN(1); - if ((tmp=join_read_const_table(s, + if ((tmp=join_read_const_table(join, s, join->positions+const_count-1))) { if (tmp > 0) @@ -6844,8 +6845,8 @@ static COND *build_equal_items_for_cond(COND *cond, return item_equal; } /* - For each field reference in cond, not from equalitym predicates, - set a pointer to the multiple equality if belongs to (if there is any) + For each field reference in cond, not from equal item predicates, + set a pointer to the multiple equality it belongs to (if there is any) */ cond= cond->transform(&Item::equal_fields_propagator, (byte *) inherited); @@ -7030,7 +7031,7 @@ static int compare_fields_by_table_order(Item_field *field1, NOTES Before generating an equality function checks that it has not - been generated for multiple equalies of the upper levels. + been generated for multiple equalities of the upper levels. E.g. for the following where condition WHERE a=5 AND ((a=b AND b=c) OR c>4) the upper level AND condition will contain =(5,a), @@ -7203,7 +7204,7 @@ static COND* substitute_for_best_equal_field(COND *cond, { cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal); // This occurs when eliminate_item_equal() founds that cond is - // always false and substitues it with Item_int 0. + // always false and substitutes it with Item_int 0. // Due to this, value of item_equal will be 0, so just return it. if (cond->type() != Item::COND_ITEM) break; @@ -7225,6 +7226,45 @@ static COND* substitute_for_best_equal_field(COND *cond, } +/* + Check appearance of new constant items in multiple equalities + of a condition after reading a constant table + + SYNOPSIS + check_const_equal_item() + cond condition whose multiple equalities are to be checked + table constant table that has been read + + DESCRIPTION + The function retrieves the cond condition and for each encountered + multiple equality checks whether new constants have appeared after + reading the constant (single row) table tab. If so it adjusts + the multiple equality appropriately. +*/ + +static void check_const_equal_items(COND *cond, + JOIN_TAB *tab) +{ + if (!(cond->used_tables() & tab->table->map)) + return; + + if (cond->type() == Item::COND_ITEM) + { + List<Item> *cond_list= ((Item_cond*) cond)->argument_list(); + List_iterator_fast<Item> li(*cond_list); + Item *item; + while ((item= li++)) + check_const_equal_items(item, tab); + } + else if (cond->type() == Item::FUNC_ITEM && + ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC) + { + Item_equal *item_equal= (Item_equal *) cond; + item_equal->check_const(); + } +} + + /* change field = field to field = const for each found field = const in the and_level @@ -8355,6 +8395,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item ***copy_func, Field **from_field, bool group, bool modify_item, bool table_cant_handle_bit_fields, + bool make_copy_field, uint convert_blob_length) { Item::Type orig_type= type; @@ -8436,7 +8477,13 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::REF_ITEM: case Item::NULL_ITEM: case Item::VARBIN_ITEM: - return create_tmp_field_from_item(thd, item, table, copy_func, modify_item, + if (make_copy_field) + { + DBUG_ASSERT(((Item_result_field*)item)->result_field); + *from_field= ((Item_result_field*)item)->result_field; + } + return create_tmp_field_from_item(thd, item, table, (make_copy_field ? 0 : + copy_func), modify_item, convert_blob_length); case Item::TYPE_HOLDER: return ((Item_type_holder *)item)->make_field_by_type(table); @@ -8509,6 +8556,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, Item **copy_func; MI_COLUMNDEF *recinfo; uint total_uneven_bit_length= 0; + bool force_copy_fields= param->force_copy_fields; DBUG_ENTER("create_tmp_table"); DBUG_PRINT("enter",("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d", (int) distinct, (int) save_sum_fields, @@ -8668,7 +8716,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, Field *new_field= create_tmp_field(thd, table, arg, arg->type(), ©_func, tmp_from_field, group != 0,not_all_columns, - distinct, + distinct, 0, param->convert_blob_length); if (!new_field) goto err; // Should be OOM @@ -8725,8 +8773,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, create_tmp_field_for_schema(thd, item, table) : create_tmp_field(thd, table, item, type, ©_func, tmp_from_field, group != 0, - not_all_columns || group != 0, - item->marker == 4, + !force_copy_fields && + (not_all_columns || group !=0), + item->marker == 4, force_copy_fields, param->convert_blob_length); if (!new_field) @@ -10163,7 +10212,7 @@ int safe_index_read(JOIN_TAB *tab) static int -join_read_const_table(JOIN_TAB *tab, POSITION *pos) +join_read_const_table(JOIN *join, JOIN_TAB *tab, POSITION *pos) { int error; DBUG_ENTER("join_read_const_table"); @@ -10215,6 +10264,26 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos) } if (!table->null_row) table->maybe_null=0; + + /* Check appearance of new constant items in Item_equal objects */ + if (join->conds) + check_const_equal_items(join->conds, tab); + TABLE_LIST *tbl; + for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf) + { + TABLE_LIST *embedded; + TABLE_LIST *embedding= tbl; + do + { + embedded= embedding; + if (embedded->on_expr) + check_const_equal_items(embedded->on_expr, tab); + embedding= embedded->embedding; + } + while (embedding && + embedding->nested_join->join_list.head() == embedded); + } + DBUG_RETURN(0); } |