Commit 82246120 authored by unknown's avatar unknown

Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-5.0-opt

into  moonbone.local:/work/19862-bug-5.0-opt-mysql


sql/item_func.h:
  Auto merged
sql/sql_select.cc:
  Auto merged
parents db7e5f0b 7af7bd48
......@@ -5057,4 +5057,23 @@ concat('data was: /', var1, '/')
data was: /1/
drop table t3|
drop procedure bug15217|
drop procedure if exists bug19862|
CREATE TABLE t11 (a INT)|
CREATE TABLE t12 (a INT)|
CREATE FUNCTION bug19862(x INT) RETURNS INT
BEGIN
INSERT INTO t11 VALUES (x);
RETURN x+1;
END|
INSERT INTO t12 VALUES (1), (2)|
SELECT bug19862(a) FROM t12 ORDER BY 1|
bug19862(a)
2
3
SELECT * FROM t11|
a
1
2
DROP TABLE t11, t12|
DROP FUNCTION bug19862|
drop table t1,t2;
......@@ -93,6 +93,12 @@ NULL
0R
FR
DROP TABLE bug19904;
create table t1(f1 int);
insert into t1 values(1),(2);
explain select myfunc_int(f1) from t1 order by 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
drop table t1;
End of 5.0 tests.
DROP FUNCTION metaphon;
DROP FUNCTION myfunc_double;
......
......@@ -5962,6 +5962,24 @@ call bug15217()|
drop table t3|
drop procedure bug15217|
#
# BUG#19862: Sort with filesort by function evaluates function twice
#
--disable_warnings
drop procedure if exists bug19862|
--enable_warnings
CREATE TABLE t11 (a INT)|
CREATE TABLE t12 (a INT)|
CREATE FUNCTION bug19862(x INT) RETURNS INT
BEGIN
INSERT INTO t11 VALUES (x);
RETURN x+1;
END|
INSERT INTO t12 VALUES (1), (2)|
SELECT bug19862(a) FROM t12 ORDER BY 1|
SELECT * FROM t11|
DROP TABLE t11, t12|
DROP FUNCTION bug19862|
#
# BUG#NNNN: New bug synopsis
#
......
......@@ -109,6 +109,13 @@ SELECT myfunc_double(n) AS f FROM bug19904;
SELECT metaphon(v) AS f FROM bug19904;
DROP TABLE bug19904;
#
# Bug#19862: Sort with filesort by function evaluates function twice
#
create table t1(f1 int);
insert into t1 values(1),(2);
explain select myfunc_int(f1) from t1 order by 1;
drop table t1;
--echo End of 5.0 tests.
#
......
......@@ -752,6 +752,7 @@ class Item {
virtual bool find_item_in_field_list_processor(byte *arg) { return 0; }
virtual bool change_context_processor(byte *context) { return 0; }
virtual bool reset_query_id_processor(byte *query_id) { return 0; }
virtual bool func_type_checker_processor(byte *arg) { return 0; }
virtual Item *equal_fields_propagator(byte * arg) { return this; }
virtual Item *set_no_const_sub(byte *arg) { return this; }
......
......@@ -398,6 +398,13 @@ Field *Item_func::tmp_table_field(TABLE *t_arg)
return res;
}
bool Item_func::func_type_checker_processor(byte *arg)
{
return *((Functype*)arg) == functype();
}
my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed);
......
......@@ -55,7 +55,7 @@ class Item_func :public Item_result_field
NOT_FUNC, NOT_ALL_FUNC,
NOW_FUNC, TRIG_COND_FUNC,
GUSERVAR_FUNC, COLLATE_FUNC,
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP };
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC };
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; }
......@@ -189,6 +189,7 @@ class Item_func :public Item_result_field
Item *transform(Item_transformer transformer, byte *arg);
void traverse_cond(Cond_traverser traverser,
void * arg, traverse_order order);
bool func_type_checker_processor(byte *arg);
};
......@@ -933,6 +934,7 @@ class Item_udf_func :public Item_func
Item_udf_func(udf_func *udf_arg, List<Item> &list)
:Item_func(list), udf(udf_arg) {}
const char *func_name() const { return udf.name(); }
enum Functype functype() const { return UDF_FUNC; }
bool fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
......
......@@ -1064,6 +1064,26 @@ JOIN::optimize()
{
need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort
}
if (order)
{
/*
Force using of tmp table if sorting by a SP or UDF function due to
their expensive and probably non-deterministic nature.
*/
for (ORDER *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
{
Item *item= *tmp_order->item;
Item_func::Functype type=Item_func::FUNC_SP;
Item_func::Functype type1=Item_func::UDF_FUNC;
if (item->walk(&Item::func_type_checker_processor,(byte*)&type) ||
item->walk(&Item::func_type_checker_processor,(byte*)&type1))
{
/* Force tmp table without sort */
need_tmp=1; simple_order=simple_group=0;
break;
}
}
}
}
tmp_having= having;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment