diff options
-rw-r--r-- | mysql-test/r/join_outer.result | 10 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 16 | ||||
-rw-r--r-- | sql/opt_range.cc | 16 | ||||
-rw-r--r-- | sql/sql_select.cc | 13 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 16 |
5 files changed, 25 insertions, 46 deletions
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 6295356b800..92b352aa608 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1123,14 +1123,14 @@ a b a b 7 8 7 5 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t1.a = t2.b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a IN(t2.a, t2.b); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a > IF(t1.a = t2.b-2, t2.b, t2.b-1); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 Using where +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 DROP TABLE t1,t2; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 46284c422c2..dfdc7319d4d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1018,9 +1018,9 @@ longlong Item_func_interval::val_int() */ bool -Item_func_between::fix_fields(THD *thd, struct st_table_list *tables, Item **ref) +Item_func_between::fix_fields(THD *thd, Item **ref) { - if (Item_func_opt_neg::fix_fields(thd, tables, ref)) + if (Item_func_opt_neg::fix_fields(thd, ref)) return 1; /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */ @@ -1132,8 +1132,8 @@ longlong Item_func_between::val_int() a_dec= args[1]->val_decimal(&a_buf); b_dec= args[2]->val_decimal(&b_buf); if (!args[1]->null_value && !args[2]->null_value) - return (my_decimal_cmp(dec, a_dec)>=0) && (my_decimal_cmp(dec, b_dec)<=0); - + return (longlong) ((my_decimal_cmp(dec, a_dec) >= 0 && + my_decimal_cmp(dec, b_dec) <= 0) != negated); if (args[1]->null_value && args[2]->null_value) null_value=1; else if (args[1]->null_value) @@ -1320,12 +1320,12 @@ Item_func_ifnull::str_op(String *str) */ bool -Item_func_if::fix_fields(THD *thd, struct st_table_list *tlist, Item **ref) +Item_func_if::fix_fields(THD *thd, Item **ref) { DBUG_ASSERT(fixed == 0); args[0]->top_level_item(); - if (Item_func::fix_fields(thd, tlist, ref)) + if (Item_func::fix_fields(thd, ref)) return 1; not_null_tables_cache= (args[1]->not_null_tables() @@ -2305,11 +2305,11 @@ bool Item_func_in::nulls_in_row() */ bool -Item_func_in::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) +Item_func_in::fix_fields(THD *thd, Item **ref) { Item **arg, **arg_end; - if (Item_func_opt_neg::fix_fields(thd, tables, ref)) + if (Item_func_opt_neg::fix_fields(thd, ref)) return 1; /* not_null_tables_cache == union(T1(e),union(T1(ei))) */ diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ecf4b5de1cb..cb250251155 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3524,20 +3524,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) } Item_func *cond_func= (Item_func*) cond; - if (cond_func->functype() == Item_func::NOT_FUNC) - { - /* Optimize NOT BETWEEN and NOT IN */ - Item *arg= cond_func->arguments()[0]; - if (arg->type() != Item::FUNC_ITEM) - DBUG_RETURN(0); - cond_func= (Item_func*) arg; - if (cond_func->functype() != Item_func::BETWEEN && - cond_func->functype() != Item_func::IN_FUNC) - DBUG_RETURN(0); - inv= TRUE; - } + if (cond_func->functype() == Item_func::BETWEEN || + cond_func->functype() == Item_func::IN_FUNC) + inv= ((Item_func_opt_neg *) cond_func)->negated; else if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE) DBUG_RETURN(0); + param->cond= cond; switch (cond_func->functype()) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0de06ea395a..83a4cd4bbf3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2862,19 +2862,6 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level, if (cond->type() != Item::FUNC_ITEM) return; Item_func *cond_func= (Item_func*) cond; - if (cond_func->functype() == Item_func::NOT_FUNC) - { - Item *item= cond_func->arguments()[0]; - /* - At this moment all NOT before simple comparison predicates - are eliminated. NOT IN and NOT BETWEEN are treated similar - IN and BETWEEN respectively. - */ - if (item->type() == Item::FUNC_ITEM && - ((Item_func *) item)->select_optimize() == Item_func::OPTIMIZE_KEY) - add_key_fields(key_fields,and_level,item,usable_tables); - return; - } switch (cond_func->select_optimize()) { case Item_func::OPTIMIZE_NONE: break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8723c558df3..ad1fd68ddcd 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4274,7 +4274,9 @@ predicate: else { $5->push_front($1); - $$= negate_expression(YYTHD, new Item_func_in(*$5)); + Item_func_in *item = new Item_func_in(*$5); + item->negate(); + $$= item; } } | bit_expr IN_SYM in_subselect @@ -4284,7 +4286,11 @@ predicate: | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate { $$= new Item_func_between($1,$3,$5); } | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate - { $$= negate_expression(YYTHD, new Item_func_between($1,$4,$6)); } + { + Item_func_between *item= new Item_func_between($1,$4,$6); + item->negate(); + $$= item; + } | bit_expr SOUNDS_SYM LIKE bit_expr { $$= new Item_func_eq(new Item_func_soundex($1), new Item_func_soundex($4)); } @@ -4350,12 +4356,6 @@ all_or_any: ALL { $$ = 1; } | ANY_SYM { $$ = 0; } ; - - - - - - interval_expr: INTERVAL_SYM expr { $$=$2; } ; |