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.


mysql-test/r/func_misc.result:
  show that a combination of NAME_CONST('x', -y) and an aggregate
  no longer crashes the server.
mysql-test/t/func_misc.test:
  show that a combination of NAME_CONST('x', -y) and an aggregate
  no longer crashes the server.
sql/ha_ndbcluster_cond.cc:
  tell cluster about "new" function type NEG_FUNC.
  (this was previous identified as UNKNOWN_FUNC,
  so we just handle it the same way, that's all.)
sql/ha_ndbcluster_cond.h:
  tell cluster about "new" function type NEG_FUNC.
  (this was previous identified as UNKNOWN_FUNC,
  so we just handle it the same way, that's all.)
sql/item.cc:
  make NAME_CONST() transparent in that type() of
  -constant is that of constant, not that of unary
  minus (id est, FUNC_ITEM).
sql/item.h:
  Move constructor to item.cc
sql/item_func.h:
  Revert Bug#30832; we can apply the magic more narrowly
  (just for NAME_CONST() rather than all Item_func_neg).
  
  Introduce new function type "NEG_FUNC."
This commit is contained in:
unknown 2008-02-28 14:23:22 +01:00
commit a0eec8abbb
7 changed files with 74 additions and 14 deletions

View file

@ -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;
}