summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2015-10-14 18:33:16 +0400
committerAlexander Barkov <bar@mariadb.org>2015-10-14 18:33:16 +0400
commitb867ade5916941c25a714068a913c4b75aabe868 (patch)
tree25d0f52ea0db68f7385fe0b4a9f2581f64229357
parent3723c70a304566d867b6fb22f1b102d389d66321 (diff)
downloadmariadb-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.h4
-rw-r--r--sql/item_func.cc19
-rw-r--r--sql/item_func.h14
-rw-r--r--sql/item_sum.h20
-rw-r--r--sql/sql_udf.h2
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;