Skip to content

Commit b867ade

Browse files
author
Alexander Barkov
committed
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.
1 parent 3723c70 commit b867ade

File tree

5 files changed

+40
-19
lines changed

5 files changed

+40
-19
lines changed

sql/item.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3617,10 +3617,6 @@ class Used_tables_and_const_cache
36173617
used_tables_cache= 0;
36183618
const_item_cache= true;
36193619
}
3620-
void used_tables_and_const_cache_copy(const Used_tables_and_const_cache *c)
3621-
{
3622-
*this= *c;
3623-
}
36243620
void used_tables_and_const_cache_join(const Item *item)
36253621
{
36263622
used_tables_cache|= item->used_tables();

sql/item_func.cc

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3508,7 +3508,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
35083508

35093509
/* Fix all arguments */
35103510
func->maybe_null=0;
3511-
used_tables_and_const_cache_init();
3511+
func->used_tables_and_const_cache_init();
35123512

35133513
if ((f_args.arg_count=arg_count))
35143514
{
@@ -3550,7 +3550,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
35503550
func->with_sum_func= func->with_sum_func || item->with_sum_func;
35513551
func->with_field= func->with_field || item->with_field;
35523552
func->with_subselect|= item->with_subselect;
3553-
used_tables_and_const_cache_join(item);
3553+
func->used_tables_and_const_cache_join(item);
35543554
f_args.arg_type[i]=item->result_type();
35553555
}
35563556
//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,
35723572
func->fix_length_and_dec();
35733573
initid.max_length=func->max_length;
35743574
initid.maybe_null=func->maybe_null;
3575-
initid.const_item=const_item_cache;
3575+
initid.const_item=func->const_item_cache;
35763576
initid.decimals=func->decimals;
35773577
initid.ptr=0;
35783578

@@ -3637,13 +3637,12 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
36373637
}
36383638
func->max_length=MY_MIN(initid.max_length,MAX_BLOB_WIDTH);
36393639
func->maybe_null=initid.maybe_null;
3640-
const_item_cache=initid.const_item;
3641-
/*
3642-
Keep used_tables_cache in sync with const_item_cache.
3643-
See the comment in Item_udf_func::update_used tables.
3644-
*/
3645-
if (!const_item_cache && !used_tables_cache)
3646-
used_tables_cache= RAND_TABLE_BIT;
3640+
/*
3641+
The above call for init() can reset initid.const_item to "false",
3642+
e.g. when the UDF function wants to be non-deterministic.
3643+
See sequence_init() in udf_example.cc.
3644+
*/
3645+
func->const_item_cache= initid.const_item;
36473646
func->decimals=MY_MIN(initid.decimals,NOT_FIXED_DEC);
36483647
}
36493648
initialized=1;

sql/item_func.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,15 @@ class Item_func_sleep :public Item_int_func
13641364

13651365
class Item_udf_func :public Item_func
13661366
{
1367+
/**
1368+
Mark "this" as non-deterministic if it uses no tables
1369+
and is not a constant at the same time.
1370+
*/
1371+
void set_non_deterministic_if_needed()
1372+
{
1373+
if (!const_item_cache && !used_tables_cache)
1374+
used_tables_cache= RAND_TABLE_BIT;
1375+
}
13671376
protected:
13681377
udf_handler udf;
13691378
bool is_expensive_processor(uchar *arg) { return TRUE; }
@@ -1379,7 +1388,7 @@ class Item_udf_func :public Item_func
13791388
{
13801389
DBUG_ASSERT(fixed == 0);
13811390
bool res= udf.fix_fields(thd, this, arg_count, args);
1382-
used_tables_and_const_cache_copy(&udf);
1391+
set_non_deterministic_if_needed();
13831392
fixed= 1;
13841393
return res;
13851394
}
@@ -1430,8 +1439,7 @@ class Item_udf_func :public Item_func
14301439
!(used_tables_cache & RAND_TABLE_BIT))
14311440
{
14321441
Item_func::update_used_tables();
1433-
if (!const_item_cache && !used_tables_cache)
1434-
used_tables_cache= RAND_TABLE_BIT;
1442+
set_non_deterministic_if_needed();
14351443
}
14361444
}
14371445
void cleanup();

sql/item_sum.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1209,9 +1209,27 @@ class Item_udf_sum : public Item_sum
12091209
return TRUE;
12101210

12111211
fixed= 1;
1212+
/*
1213+
We set const_item_cache to false in constructors.
1214+
It can be later changed to "true", in a Item_sum::make_const() call.
1215+
No make_const() calls should have happened so far.
1216+
*/
1217+
DBUG_ASSERT(!const_item_cache);
12121218
if (udf.fix_fields(thd, this, this->arg_count, this->args))
12131219
return TRUE;
1214-
1220+
/**
1221+
The above call for udf.fix_fields() updates
1222+
the Used_tables_and_const_cache part of "this" as if it was a regular
1223+
non-aggregate UDF function and can change both const_item_cache and
1224+
used_tables_cache members.
1225+
- The used_tables_cache will be re-calculated in update_used_tables()
1226+
which is called from check_sum_func() below. So we don't care about
1227+
its current value.
1228+
- The const_item_cache must stay "false" until a Item_sum::make_const()
1229+
call happens, if ever. So we need to reset const_item_cache back to
1230+
"false" here.
1231+
*/
1232+
const_item_cache= false;
12151233
memcpy (orig_args, args, sizeof (Item *) * arg_count);
12161234
return check_sum_func(thd, ref);
12171235
}

sql/sql_udf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ typedef struct st_udf_func
5252

5353
class Item_result_field;
5454

55-
class udf_handler :public Sql_alloc, public Used_tables_and_const_cache
55+
class udf_handler :public Sql_alloc
5656
{
5757
protected:
5858
udf_func *u_d;

0 commit comments

Comments
 (0)