summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
authorEvgeny Potemkin <epotemkin@mysql.com>2009-12-02 00:25:51 +0300
committerEvgeny Potemkin <epotemkin@mysql.com>2009-12-02 00:25:51 +0300
commit9f7d24586b641fde19848dd77776d0fc7b0001f2 (patch)
treef6897e6f5c940d328bb17f29511b4e7dc729185b /sql/item.h
parent17a4c595bcc75b6de82129fe96b7b6245215ea78 (diff)
downloadmariadb-git-9f7d24586b641fde19848dd77776d0fc7b0001f2.tar.gz
Bug#33546: Slowdown on re-evaluation of constant expressions.
Constant expressions in WHERE/HAVING/ON clauses aren't cached and evaluated for each row. This causes slowdown of query execution especially if constant UDF/SP function are used. Now WHERE/HAVING/ON expressions are analyzed in the top-bottom direction with help of the compile function. When analyzer meets a constant item it sets a flag for the tree transformer to cache the item and doesn't allow tree walker to go deeper. Thus, the topmost item of a constant expression if cached. This is done after all other optimizations were applied to WHERE/HAVING/ON expressions A helper function called cache_const_exprs is added to the JOIN class. It calls compile method with caching analyzer and transformer on WHERE, HAVING, ON expressions if they're present. The cache_const_expr_analyzer and cache_const_expr_transformer functions are added to the Item class. The first one check if the item can be cached and the second caches it if so. A new Item_cache_datetime class is derived from the Item_cache class. It caches both int and string values of the underlying item independently to avoid DATETIME aware int-to-string conversion. Thus it completely relies on the ability of the underlying item to correctly convert DATETIME value from int to string and vice versa.
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h38
1 files changed, 38 insertions, 0 deletions
diff --git a/sql/item.h b/sql/item.h
index f69fa742744..0556c330088 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -903,6 +903,9 @@ public:
virtual bool reset_query_id_processor(uchar *query_id_arg) { return 0; }
virtual bool is_expensive_processor(uchar *arg) { return 0; }
virtual bool register_field_in_read_map(uchar *arg) { return 0; }
+
+ virtual bool cache_const_expr_analyzer(uchar **arg);
+ virtual Item* cache_const_expr_transformer(uchar *arg);
/*
Check if a partition function is allowed
SYNOPSIS
@@ -2292,6 +2295,7 @@ public:
if (ref && result_type() == ROW_RESULT)
(*ref)->bring_value();
}
+ bool basic_const_item() { return (*ref)->basic_const_item(); }
};
@@ -2977,6 +2981,8 @@ public:
}
virtual void store(Item *item);
virtual void cache_value()= 0;
+ bool basic_const_item() const
+ { return test(example && example->basic_const_item());}
};
@@ -3127,6 +3133,38 @@ public:
};
+class Item_cache_datetime: public Item_cache
+{
+protected:
+ String str_value;
+ ulonglong int_value;
+ bool str_value_cached;
+public:
+ Item_cache_datetime(enum_field_types field_type_arg):
+ Item_cache(field_type_arg), int_value(0), str_value_cached(0)
+ {
+ cmp_context= STRING_RESULT;
+ }
+
+ void store(Item *item, longlong val_arg);
+ double val_real();
+ longlong val_int();
+ String* val_str(String *str);
+ my_decimal *val_decimal(my_decimal *);
+ enum Item_result result_type() const { return STRING_RESULT; }
+ bool result_as_longlong() { return TRUE; }
+ /*
+ In order to avoid INT <-> STRING conversion of a DATETIME value
+ two cache_value functions are introduced. One (cache_value) caches STRING
+ value, another (cache_value_int) - INT value. Thus this cache item
+ completely relies on the ability of the underlying item to do the
+ correct conversion.
+ */
+ void cache_value_int();
+ void cache_value();
+};
+
+
/*
Item_type_holder used to store type. name, length of Item for UNIONS &
derived tables.