Commit 955be183 authored by unknown's avatar unknown

Merge mysql.com:/misc/mysql/34749/50-34749

into  mysql.com:/misc/mysql/34749/51-34749


mysql-test/r/func_misc.result:
  Auto merged
mysql-test/t/func_misc.test:
  Auto merged
sql/ha_ndbcluster_cond.cc:
  Auto merged
sql/ha_ndbcluster_cond.h:
  Auto merged
sql/item.cc:
  Auto merged
sql/item.h:
  Auto merged
sql/item_func.h:
  Auto merged
parents d13abd50 4715b478
...@@ -212,6 +212,25 @@ test ...@@ -212,6 +212,25 @@ test
SELECT NAME_CONST('test', 'test'); SELECT NAME_CONST('test', 'test');
test test
test test
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
SELECT NAME_CONST('flag',1) * MAX(a) FROM t1;
NAME_CONST('flag',1) * MAX(a)
3
SELECT NAME_CONST('flag',1.5) * MAX(a) FROM t1;
NAME_CONST('flag',1.5) * MAX(a)
4.5
SELECT NAME_CONST('flag',-1) * MAX(a) FROM t1;
NAME_CONST('flag',-1) * MAX(a)
-3
SELECT NAME_CONST('flag',-1.5) * MAX(a) FROM t1;
NAME_CONST('flag',-1.5) * MAX(a)
-4.5
SELECT NAME_CONST('flag', SQRT(4)) * MAX(a) FROM t1;
ERROR HY000: Incorrect arguments to NAME_CONST
SELECT NAME_CONST('flag',-SQRT(4)) * MAX(a) FROM t1;
ERROR HY000: Incorrect arguments to NAME_CONST
DROP TABLE t1;
CREATE TABLE t1 (a int); CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (5), (2); INSERT INTO t1 VALUES (5), (2);
SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t; SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t;
......
...@@ -213,6 +213,24 @@ SELECT NAME_CONST('test', 1.0); ...@@ -213,6 +213,24 @@ SELECT NAME_CONST('test', 1.0);
SELECT NAME_CONST('test', -1.0); SELECT NAME_CONST('test', -1.0);
SELECT NAME_CONST('test', 'test'); SELECT NAME_CONST('test', 'test');
#
# Bug #34749: Server crash when using NAME_CONST() with an aggregate function
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
# NAME_CONST() + aggregate.
SELECT NAME_CONST('flag',1) * MAX(a) FROM t1;
SELECT NAME_CONST('flag',1.5) * MAX(a) FROM t1;
# Now, wrap the INT_ITEM in Item_func_neg and watch the pretty explosions
SELECT NAME_CONST('flag',-1) * MAX(a) FROM t1;
SELECT NAME_CONST('flag',-1.5) * MAX(a) FROM t1;
--error ER_WRONG_ARGUMENTS
SELECT NAME_CONST('flag', SQRT(4)) * MAX(a) FROM t1;
--error ER_WRONG_ARGUMENTS
SELECT NAME_CONST('flag',-SQRT(4)) * MAX(a) FROM t1;
DROP TABLE t1;
# #
# Bug #27545: erroneous usage of NAME_CONST with a name as the first parameter # Bug #27545: erroneous usage of NAME_CONST with a name as the first parameter
# resolved against a column name of a derived table hangs the client # resolved against a column name of a derived table hangs the client
......
...@@ -117,7 +117,8 @@ void ndb_serialize_cond(const Item *item, void *arg) ...@@ -117,7 +117,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
if (item->type() == Item::FUNC_ITEM) if (item->type() == Item::FUNC_ITEM)
{ {
Item_func *func_item= (Item_func *) item; Item_func *func_item= (Item_func *) item;
if (func_item->functype() == Item_func::UNKNOWN_FUNC && if ((func_item->functype() == Item_func::UNKNOWN_FUNC ||
func_item->functype() == Item_func::NEG_FUNC) &&
func_item->const_item()) func_item->const_item())
{ {
// Skip any arguments since we will evaluate function instead // Skip any arguments since we will evaluate function instead
...@@ -369,8 +370,9 @@ void ndb_serialize_cond(const Item *item, void *arg) ...@@ -369,8 +370,9 @@ void ndb_serialize_cond(const Item *item, void *arg)
{ {
Item_func *func_item= (Item_func *) item; Item_func *func_item= (Item_func *) item;
// Check that we expect a function or functional expression here // Check that we expect a function or functional expression here
if (context->expecting(Item::FUNC_ITEM) || if (context->expecting(Item::FUNC_ITEM) ||
func_item->functype() == Item_func::UNKNOWN_FUNC) func_item->functype() == Item_func::UNKNOWN_FUNC ||
func_item->functype() == Item_func::NEG_FUNC)
context->expect_nothing(); context->expect_nothing();
else else
{ {
...@@ -584,6 +586,7 @@ void ndb_serialize_cond(const Item *item, void *arg) ...@@ -584,6 +586,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
context->expect(Item::FUNC_ITEM); context->expect(Item::FUNC_ITEM);
break; break;
} }
case Item_func::NEG_FUNC:
case Item_func::UNKNOWN_FUNC: case Item_func::UNKNOWN_FUNC:
{ {
DBUG_PRINT("info", ("UNKNOWN_FUNC %s", DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
......
...@@ -233,6 +233,7 @@ class Ndb_item : public Sql_alloc ...@@ -233,6 +233,7 @@ class Ndb_item : public Sql_alloc
case (Item_func::ISNOTNULL_FUNC): { return NDB_ISNOTNULL_FUNC; } case (Item_func::ISNOTNULL_FUNC): { return NDB_ISNOTNULL_FUNC; }
case (Item_func::LIKE_FUNC): { return NDB_LIKE_FUNC; } case (Item_func::LIKE_FUNC): { return NDB_LIKE_FUNC; }
case (Item_func::NOT_FUNC): { return NDB_NOT_FUNC; } case (Item_func::NOT_FUNC): { return NDB_NOT_FUNC; }
case (Item_func::NEG_FUNC): { return NDB_UNKNOWN_FUNC; }
case (Item_func::UNKNOWN_FUNC): { return NDB_UNKNOWN_FUNC; } case (Item_func::UNKNOWN_FUNC): { return NDB_UNKNOWN_FUNC; }
case (Item_func::COND_AND_FUNC): { return NDB_COND_AND_FUNC; } case (Item_func::COND_AND_FUNC): { return NDB_COND_AND_FUNC; }
case (Item_func::COND_OR_FUNC): { return NDB_COND_OR_FUNC; } case (Item_func::COND_OR_FUNC): { return NDB_COND_OR_FUNC; }
......
...@@ -1238,6 +1238,22 @@ bool Item_name_const::is_null() ...@@ -1238,6 +1238,22 @@ bool Item_name_const::is_null()
return value_item->is_null(); return value_item->is_null();
} }
Item_name_const::Item_name_const(Item *name_arg, Item *val):
value_item(val), name_item(name_arg)
{
if (!(valid_args= name_item->basic_const_item() &&
(value_item->basic_const_item() ||
((value_item->type() == FUNC_ITEM) &&
(((Item_func *) value_item)->functype() ==
Item_func::NEG_FUNC) &&
(((Item_func *) value_item)->key_item()->type() !=
FUNC_ITEM)))))
my_error(ER_WRONG_ARGUMENTS, MYF(0), "NAME_CONST");
Item::maybe_null= TRUE;
}
Item::Type Item_name_const::type() const Item::Type Item_name_const::type() const
{ {
/* /*
...@@ -1249,8 +1265,17 @@ Item::Type Item_name_const::type() const ...@@ -1249,8 +1265,17 @@ Item::Type Item_name_const::type() const
if (item->type() == FIELD_ITEM) if (item->type() == FIELD_ITEM)
((Item_field *) item)->... ((Item_field *) item)->...
we return NULL_ITEM in the case to avoid wrong casting. we return NULL_ITEM in the case to avoid wrong casting.
valid_args guarantees value_item->basic_const_item(); if type is
FUNC_ITEM, then we have a fudged item_func_neg() on our hands
and return the underlying type.
*/ */
return valid_args ? value_item->type() : NULL_ITEM; return valid_args ?
(((value_item->type() == FUNC_ITEM) &&
(((Item_func *) value_item)->functype() == Item_func::NEG_FUNC)) ?
((Item_func *) value_item)->key_item()->type() :
value_item->type()) :
NULL_ITEM;
} }
......
...@@ -1244,14 +1244,7 @@ class Item_name_const : public Item ...@@ -1244,14 +1244,7 @@ class Item_name_const : public Item
Item *name_item; Item *name_item;
bool valid_args; bool valid_args;
public: public:
Item_name_const(Item *name_arg, Item *val): Item_name_const(Item *name_arg, Item *val);
value_item(val), name_item(name_arg)
{
if (!(valid_args= name_item->basic_const_item() &
value_item->basic_const_item()))
my_error(ER_WRONG_ARGUMENTS, MYF(0), "NAME_CONST");
Item::maybe_null= TRUE;
}
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
......
...@@ -54,7 +54,8 @@ class Item_func :public Item_result_field ...@@ -54,7 +54,8 @@ class Item_func :public Item_result_field
NOT_FUNC, NOT_ALL_FUNC, NOT_FUNC, NOT_ALL_FUNC,
NOW_FUNC, TRIG_COND_FUNC, NOW_FUNC, TRIG_COND_FUNC,
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC }; EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
NEG_FUNC };
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
OPTIMIZE_EQUAL }; OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; } enum Type type() const { return FUNC_ITEM; }
...@@ -467,7 +468,7 @@ class Item_func_neg :public Item_func_num1 ...@@ -467,7 +468,7 @@ class Item_func_neg :public Item_func_num1
longlong int_op(); longlong int_op();
my_decimal *decimal_op(my_decimal *); my_decimal *decimal_op(my_decimal *);
const char *func_name() const { return "-"; } const char *func_name() const { return "-"; }
virtual bool basic_const_item() const { return args[0]->basic_const_item(); } enum Functype functype() const { return NEG_FUNC; }
void fix_length_and_dec(); void fix_length_and_dec();
void fix_num_length_and_dec(); void fix_num_length_and_dec();
uint decimal_precision() const { return args[0]->decimal_precision(); } uint decimal_precision() const { return args[0]->decimal_precision(); }
......
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