Below is the list of changes that have just been committed into a local
5.0 repository of tnurnberg. When tnurnberg does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-02-28 13:54:58+01:00, tnurnberg@stripped +7 -0
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@stripped, 2008-02-28 13:54:56+01:00, tnurnberg@stripped +19
-0
show that a combination of NAME_CONST('x', -y) and an aggregate
no longer crashes the server
mysql-test/t/func_misc.test@stripped, 2008-02-28 13:54:56+01:00, tnurnberg@stripped +18 -0
show that a combination of NAME_CONST('x', -y) and an aggregate
no longer crashes the server
sql/ha_ndbcluster_cond.cc@stripped, 2008-02-28 13:54:56+01:00, tnurnberg@stripped +6 -3
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@stripped, 2008-02-28 13:54:56+01:00, tnurnberg@stripped +1 -0
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@stripped, 2008-02-28 13:54:56+01:00, tnurnberg@stripped +26 -1
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@stripped, 2008-02-28 13:54:57+01:00, tnurnberg@stripped +1 -8
Move constructor to item.cc
sql/item_func.h@stripped, 2008-02-28 13:54:57+01:00, tnurnberg@stripped +3 -2
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."
diff -Nrup a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
--- a/mysql-test/r/func_misc.result 2007-12-13 12:47:21 +01:00
+++ b/mysql-test/r/func_misc.result 2008-02-28 13:54:56 +01:00
@@ -207,6 +207,25 @@ test
SELECT NAME_CONST('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);
INSERT INTO t1 VALUES (5), (2);
SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t;
diff -Nrup a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
--- a/mysql-test/t/func_misc.test 2007-12-13 12:47:21 +01:00
+++ b/mysql-test/t/func_misc.test 2008-02-28 13:54:56 +01:00
@@ -205,6 +205,24 @@ SELECT NAME_CONST('test', -1.0);
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
# resolved against a column name of a derived table hangs the client
#
diff -Nrup a/sql/ha_ndbcluster_cond.cc b/sql/ha_ndbcluster_cond.cc
--- a/sql/ha_ndbcluster_cond.cc 2007-10-04 10:52:14 +02:00
+++ b/sql/ha_ndbcluster_cond.cc 2008-02-28 13:54:56 +01:00
@@ -117,7 +117,8 @@ void ndb_serialize_cond(const Item *item
if (item->type() == 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())
{
// Skip any arguments since we will evaluate function instead
@@ -369,8 +370,9 @@ void ndb_serialize_cond(const Item *item
{
Item_func *func_item= (Item_func *) item;
// Check that we expect a function or functional expression here
- if (context->expecting(Item::FUNC_ITEM) ||
- func_item->functype() == Item_func::UNKNOWN_FUNC)
+ if (context->expecting(Item::FUNC_ITEM) ||
+ func_item->functype() == Item_func::UNKNOWN_FUNC ||
+ func_item->functype() == Item_func::NEG_FUNC)
context->expect_nothing();
else
{
@@ -584,6 +586,7 @@ void ndb_serialize_cond(const Item *item
context->expect(Item::FUNC_ITEM);
break;
}
+ case Item_func::NEG_FUNC:
case Item_func::UNKNOWN_FUNC:
{
DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
diff -Nrup a/sql/ha_ndbcluster_cond.h b/sql/ha_ndbcluster_cond.h
--- a/sql/ha_ndbcluster_cond.h 2007-06-19 13:56:00 +02:00
+++ b/sql/ha_ndbcluster_cond.h 2008-02-28 13:54:56 +01:00
@@ -228,6 +228,7 @@ public:
case (Item_func::ISNOTNULL_FUNC): { return NDB_ISNOTNULL_FUNC; }
case (Item_func::LIKE_FUNC): { return NDB_LIKE_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::COND_AND_FUNC): { return NDB_COND_AND_FUNC; }
case (Item_func::COND_OR_FUNC): { return NDB_COND_OR_FUNC; }
diff -Nrup a/sql/item.cc b/sql/item.cc
--- a/sql/item.cc 2008-01-11 18:57:33 +01:00
+++ b/sql/item.cc 2008-02-28 13:54:56 +01:00
@@ -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;
}
diff -Nrup a/sql/item.h b/sql/item.h
--- a/sql/item.h 2007-12-13 11:49:11 +01:00
+++ b/sql/item.h 2008-02-28 13:54:57 +01:00
@@ -1113,14 +1113,7 @@ class Item_name_const : public Item
Item *name_item;
bool valid_args;
public:
- 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;
- }
+ Item_name_const(Item *name_arg, Item *val);
bool fix_fields(THD *, Item **);
diff -Nrup a/sql/item_func.h b/sql/item_func.h
--- a/sql/item_func.h 2007-12-13 11:49:11 +01:00
+++ b/sql/item_func.h 2008-02-28 13:54:57 +01:00
@@ -54,7 +54,8 @@ public:
NOT_FUNC, NOT_ALL_FUNC,
NOW_FUNC, TRIG_COND_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,
OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; }
@@ -466,7 +467,7 @@ public:
longlong int_op();
my_decimal *decimal_op(my_decimal *);
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_num_length_and_dec();
uint decimal_precision() const { return args[0]->decimal_precision(); }
| Thread |
|---|
| • bk commit into 5.0 tree (tnurnberg:1.2595) BUG#34749 | Tatjana A Nuernberg | 28 Feb 2008 |