summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <tnurnberg@white.intern.koehntopp.de>2008-03-10 07:07:56 +0100
committerunknown <tnurnberg@white.intern.koehntopp.de>2008-03-10 07:07:56 +0100
commit111de516ab972f076f5b6ec2399874391bfeb473 (patch)
tree51f2d1b0305bb5e58ebf2fe09ba255c8efdd44e2
parent4a8c442f040db67763697df8f109f79ec6240979 (diff)
parenta0eec8abbb233d9e3f278d343eaed2e70b55161e (diff)
downloadmariadb-git-111de516ab972f076f5b6ec2399874391bfeb473.tar.gz
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
-rw-r--r--mysql-test/r/func_misc.result19
-rw-r--r--mysql-test/t/func_misc.test18
-rw-r--r--sql/ha_ndbcluster_cond.cc9
-rw-r--r--sql/ha_ndbcluster_cond.h1
-rw-r--r--sql/item.cc27
-rw-r--r--sql/item.h9
-rw-r--r--sql/item_func.h5
7 files changed, 74 insertions, 14 deletions
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 745a340ec94..ec8c187e1f6 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -212,6 +212,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 --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index 7a579088d23..10a63b925d3 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -214,6 +214,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 --git a/sql/ha_ndbcluster_cond.cc b/sql/ha_ndbcluster_cond.cc
index d8dff3c7e2f..bb35211944b 100644
--- a/sql/ha_ndbcluster_cond.cc
+++ b/sql/ha_ndbcluster_cond.cc
@@ -117,7 +117,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
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, void *arg)
{
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, void *arg)
context->expect(Item::FUNC_ITEM);
break;
}
+ case Item_func::NEG_FUNC:
case Item_func::UNKNOWN_FUNC:
{
DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
diff --git a/sql/ha_ndbcluster_cond.h b/sql/ha_ndbcluster_cond.h
index 4d1d2ef9f92..4401a93c9e1 100644
--- a/sql/ha_ndbcluster_cond.h
+++ b/sql/ha_ndbcluster_cond.h
@@ -233,6 +233,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 --git a/sql/item.cc b/sql/item.cc
index 34f6eb9dc61..827b6330a07 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1238,6 +1238,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
{
/*
@@ -1249,8 +1265,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 --git a/sql/item.h b/sql/item.h
index b98389bc8d4..7cae7a20861 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1244,14 +1244,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 --git a/sql/item_func.h b/sql/item_func.h
index e09b584de95..65241dc40af 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -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; }
@@ -467,7 +468,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(); }