diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-10-14 18:33:16 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-10-14 18:33:16 +0400 |
commit | b867ade5916941c25a714068a913c4b75aabe868 (patch) | |
tree | 25d0f52ea0db68f7385fe0b4a9f2581f64229357 | |
parent | 3723c70a304566d867b6fb22f1b102d389d66321 (diff) | |
download | mariadb-git-b867ade5916941c25a714068a913c4b75aabe868.tar.gz |
Removing Used_tables_and_const_cache from "class udf_handler".
It was used only temporary, during udf_handler::fix_fields() time,
and then copied to the owner Item_func_or_sum object.
Changing the code to use the Used_tables_and_const_cache part
of the owner Item_sum_or_func object directly.
-rw-r--r-- | sql/item.h | 4 | ||||
-rw-r--r-- | sql/item_func.cc | 19 | ||||
-rw-r--r-- | sql/item_func.h | 14 | ||||
-rw-r--r-- | sql/item_sum.h | 20 | ||||
-rw-r--r-- | sql/sql_udf.h | 2 |
5 files changed, 40 insertions, 19 deletions
diff --git a/sql/item.h b/sql/item.h index 3b0dddc4ab1..1db4e62051c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3617,10 +3617,6 @@ public: used_tables_cache= 0; const_item_cache= true; } - void used_tables_and_const_cache_copy(const Used_tables_and_const_cache *c) - { - *this= *c; - } void used_tables_and_const_cache_join(const Item *item) { used_tables_cache|= item->used_tables(); diff --git a/sql/item_func.cc b/sql/item_func.cc index f3d3a54561c..235aec4a17e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3508,7 +3508,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, /* Fix all arguments */ func->maybe_null=0; - used_tables_and_const_cache_init(); + func->used_tables_and_const_cache_init(); if ((f_args.arg_count=arg_count)) { @@ -3550,7 +3550,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, func->with_sum_func= func->with_sum_func || item->with_sum_func; func->with_field= func->with_field || item->with_field; func->with_subselect|= item->with_subselect; - used_tables_and_const_cache_join(item); + func->used_tables_and_const_cache_join(item); f_args.arg_type[i]=item->result_type(); } //TODO: why all following memory is not allocated with 1 call of sql_alloc? @@ -3572,7 +3572,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, func->fix_length_and_dec(); initid.max_length=func->max_length; initid.maybe_null=func->maybe_null; - initid.const_item=const_item_cache; + initid.const_item=func->const_item_cache; initid.decimals=func->decimals; initid.ptr=0; @@ -3637,13 +3637,12 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func, } func->max_length=MY_MIN(initid.max_length,MAX_BLOB_WIDTH); func->maybe_null=initid.maybe_null; - const_item_cache=initid.const_item; - /* - Keep used_tables_cache in sync with const_item_cache. - See the comment in Item_udf_func::update_used tables. - */ - if (!const_item_cache && !used_tables_cache) - used_tables_cache= RAND_TABLE_BIT; + /* + The above call for init() can reset initid.const_item to "false", + e.g. when the UDF function wants to be non-deterministic. + See sequence_init() in udf_example.cc. + */ + func->const_item_cache= initid.const_item; func->decimals=MY_MIN(initid.decimals,NOT_FIXED_DEC); } initialized=1; diff --git a/sql/item_func.h b/sql/item_func.h index dfd404fbfb7..7f301b6801e 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1364,6 +1364,15 @@ public: class Item_udf_func :public Item_func { + /** + Mark "this" as non-deterministic if it uses no tables + and is not a constant at the same time. + */ + void set_non_deterministic_if_needed() + { + if (!const_item_cache && !used_tables_cache) + used_tables_cache= RAND_TABLE_BIT; + } protected: udf_handler udf; bool is_expensive_processor(uchar *arg) { return TRUE; } @@ -1379,7 +1388,7 @@ public: { DBUG_ASSERT(fixed == 0); bool res= udf.fix_fields(thd, this, arg_count, args); - used_tables_and_const_cache_copy(&udf); + set_non_deterministic_if_needed(); fixed= 1; return res; } @@ -1430,8 +1439,7 @@ public: !(used_tables_cache & RAND_TABLE_BIT)) { Item_func::update_used_tables(); - if (!const_item_cache && !used_tables_cache) - used_tables_cache= RAND_TABLE_BIT; + set_non_deterministic_if_needed(); } } void cleanup(); diff --git a/sql/item_sum.h b/sql/item_sum.h index 9486317c401..db3312c42f4 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1209,9 +1209,27 @@ public: return TRUE; fixed= 1; + /* + We set const_item_cache to false in constructors. + It can be later changed to "true", in a Item_sum::make_const() call. + No make_const() calls should have happened so far. + */ + DBUG_ASSERT(!const_item_cache); if (udf.fix_fields(thd, this, this->arg_count, this->args)) return TRUE; - + /** + The above call for udf.fix_fields() updates + the Used_tables_and_const_cache part of "this" as if it was a regular + non-aggregate UDF function and can change both const_item_cache and + used_tables_cache members. + - The used_tables_cache will be re-calculated in update_used_tables() + which is called from check_sum_func() below. So we don't care about + its current value. + - The const_item_cache must stay "false" until a Item_sum::make_const() + call happens, if ever. So we need to reset const_item_cache back to + "false" here. + */ + const_item_cache= false; memcpy (orig_args, args, sizeof (Item *) * arg_count); return check_sum_func(thd, ref); } diff --git a/sql/sql_udf.h b/sql/sql_udf.h index 700f868eea4..a42fe686637 100644 --- a/sql/sql_udf.h +++ b/sql/sql_udf.h @@ -52,7 +52,7 @@ typedef struct st_udf_func class Item_result_field; -class udf_handler :public Sql_alloc, public Used_tables_and_const_cache +class udf_handler :public Sql_alloc { protected: udf_func *u_d; |