summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authortnurnberg@mysql.com/white.intern.koehntopp.de <>2008-02-28 14:23:22 +0100
committertnurnberg@mysql.com/white.intern.koehntopp.de <>2008-02-28 14:23:22 +0100
commitc6b4d7a7c41a2469a69e0d2a8a883c83cbff3ea9 (patch)
treed7fe47965f56b028624438c1549357c09d710ab1 /sql/item.cc
parent140ca5953815ac1f773ae518cb021783e3334e20 (diff)
downloadmariadb-git-c6b4d7a7c41a2469a69e0d2a8a883c83cbff3ea9.tar.gz
Bug#34749: Server crash when using NAME_CONST() with an aggregate function
NAME_CONST('whatever', -1) * MAX(whatever) bombed since -1 was not seen as constant, but as FUNCTION_UNARY_MINUS(constant) while we are at the same time pretending it was a basic const item. This confused the aggregate handlers in exciting ways. We now make NAME_CONST() behave more consistently.
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc27
1 files changed, 26 insertions, 1 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 713e7709bcb..acd8053cbdf 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1207,6 +1207,22 @@ bool Item_name_const::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
{
/*
@@ -1218,8 +1234,17 @@ Item::Type Item_name_const::type() const
if (item->type() == FIELD_ITEM)
((Item_field *) item)->...
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;
}