summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item_cmpfunc.cc39
-rw-r--r--sql/item_cmpfunc.h3
-rw-r--r--sql/opt_sum.cc13
-rw-r--r--sql/sql_analyse.cc2
4 files changed, 56 insertions, 1 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index bf3c0af1ea6..3cd55934950 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1236,6 +1236,45 @@ longlong Item_cond_or::val_int()
return 0;
}
+/*
+ Create an AND expression from two expressions
+
+ SYNOPSIS
+ and_expressions()
+ a expression or NULL
+ b expression.
+ org_item Don't modify a if a == *org_item
+ If a == NULL, org_item is set to point at b,
+ to ensure that future calls will not modify b.
+
+ NOTES
+ This will not modify item pointed to by org_item or b
+ The idea is that one can call this in a loop and create and
+ 'and' over all items without modifying any of the original items.
+
+ RETURN
+ NULL Error
+ Item
+*/
+
+Item *and_expressions(Item *a, Item *b, Item **org_item)
+{
+ if (!a)
+ return (*org_item= (Item*) b);
+ if (a == *org_item)
+ {
+ Item_cond *res;
+ if ((res= new Item_cond_and(a, (Item*) b)))
+ res->used_tables_cache= a->used_tables() | b->used_tables();
+ return res;
+ }
+ if (((Item_cond_and*) a)->add((Item*) b))
+ return 0;
+ ((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
+ return a;
+}
+
+
longlong Item_func_isnull::val_int()
{
/*
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 214abff4b77..83035720df6 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -621,3 +621,6 @@ public:
longlong val_int();
const char *func_name() const { return "xor"; }
};
+
+
+Item *and_expressions(Item *a, Item *b, Item **org_item);
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 74e7b2ef3be..4b6a196051e 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -37,6 +37,19 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
bool recalc_const_item=0;
table_map removed_tables=0;
Item *item;
+ COND *org_conds= conds;
+
+ /* Add all ON conditions to WHERE condition */
+ for (TABLE_LIST *tl=tables; tl ; tl= tl->next)
+ {
+ if (tl->on_expr)
+ conds= and_expressions(conds, tl->on_expr, &org_conds);
+ }
+
+ /*
+ Iterate through item is select part and replace COUNT(), MIN() and MAX()
+ with constants (if possible)
+ */
while ((item= it++))
{
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index bbe82653190..96bbd731882 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -677,7 +677,7 @@ bool analyse::end_of_records()
case FIELD_TYPE_DECIMAL:
ans.append("DECIMAL", 7);
// if item is FIELD_ITEM, it _must_be_ Field_num in this case
- if (((Field_num*) (*f)->item)->zerofill)
+ if (((Field_num*) ((Item_field*) (*f)->item)->field)->zerofill)
ans.append(" ZEROFILL");
break;
default: