| Bug #34749 | Server crash when using NAME_CONST() with an aggregate function | ||
|---|---|---|---|
| Submitted: | 21 Feb 22:10 | Modified: | 15 Mar 22:17 |
| Reporter: | David Shrewsbury | ||
| Status: | Closed | ||
| Category: | Server | Severity: | S1 (Critical) |
| Version: | 5.0.54a, 5.1.23-rc | OS: | Linux |
| Assigned to: | Tatjana A. Nuernberg | Target Version: | 5.0+ |
| Tags: | name_const | ||
| Triage: | D1 (Critical) | ||
[21 Feb 22:10]
David Shrewsbury
[26 Feb 9:45]
Tatjana A. Nuernberg
#0 Item_name_const::type (this=0x8d9c448) at item.cc:1222
#1 0x08181e17 in Item::split_sum_func2 (this=0x8d9c448, thd=0x8d642e8,
ref_pointer_array=0x8d9d738, fields=@0x8d9d678, ref=0x8d9c65c, skip_registered=true) at
item.cc:1308
#2 0x081b14f7 in Item_func::split_sum_func (this=0x8d9c608, thd=0x8d642e8,
ref_pointer_array=0x8d9d738, fields=@0x8d9d678) at item_func.cc:342
#3 0x08270957 in setup_fields (thd=0x8d642e8, ref_pointer_array=0x8d9d738,
fields=@0x8d65320, set_query_id=true, sum_func_list=0x8d9d678, allow_sum_func=true) at
sql_base.cc:5124
#4 0x082a48e4 in JOIN::prepare (this=0x8d9c938, rref_pointer_array=0x8d653b0,
tables_init=0x8d9c710, wild_num=0, conds_init=0x0, og_num=0, order_init=0x0,
group_init=0x0, having_init=0x0, proc_param_init=0x0, select_lex_arg=0x8d6528c,
unit_arg=0x8d65054) at sql_select.cc:467
#5 0x082a5723 in mysql_select (thd=0x8d642e8, rref_pointer_array=0x8d653b0,
tables=0x8d9c710, wild_num=0, fields=@0x8d65320, conds=0x0, og_num=0, order=0x0,
group=0x0, having=0x0, proc_param=0x0, select_options=2156153344, result=0x8d9c920,
unit=0x8d65054, select_lex=0x8d6528c) at sql_select.cc:2274
#6 0x082a9ba6 in handle_select (thd=0x8d642e8, lex=0x8d64ffc, result=0x8d9c920,
setup_tables_done_option=0) at sql_select.cc:257
#7 0x0823d89d in mysql_execute_command (thd=0x8d642e8) at sql_parse.cc:2736
#8 0x08245cde in mysql_parse (thd=0x8d642e8, inBuf=0x8d9c290 "SELECT
NAME_CONST('flag',-1)*max(1) FROM t1", length=43, found_semicolon=0xb50db1c0) at
sql_parse.cc:6174
#9 0x08248528 in dispatch_command (command=COM_QUERY, thd=0x8d642e8, packet=0x8d94231
"SELECT NAME_CONST('flag',-1)*max(1) FROM t1", packet_length=44) at sql_parse.cc:1889
#10 0x08249a81 in do_command (thd=0x8d642e8) at sql_parse.cc:1595
#11 0x0824ac5b in handle_one_connection (arg=0x8d642e8) at sql_parse.cc:1201
(gdb) print ((Item_func_neg *) value_item)->func_name()
$5 = 0x86353c7 "-"
(gdb) print ((Item_func_neg *) value_item)->val_int()
$6 = -1
(gdb) print ((Item_func_neg *) value_item)->basic_const_item()
$7 = true
(gdb) print ((Item_func_neg *) value_item)->args[0]
$8 = (class Item *) 0x8d9c370
(gdb) graph display *(((Item_func_neg *) this->value_item)->args[0])
(gdb) print (((Item_func_neg *) this->value_item)->args[0])->type()
$10 = INT_ITEM
[26 Feb 9:46]
Tatjana A. Nuernberg
This of course is "more fun with Item_func_neg" inasmuch as overloading like so unbreaks
the crash as such:
virtual enum Type type() const { return args[0]->type() == INT_ITEM ? INT_ITEM :
FUNC_ITEM; }
mysql> SELECT NAME_CONST('flag',-1) * MAX(a) FROM t1;
+--------------------------------+
| NAME_CONST('flag',-1) * MAX(a) |
+--------------------------------+
| -3 |
+--------------------------------+
[26 Feb 9:55]
Tatjana A. Nuernberg
(note that above is just an illustration, not the actual fix as for instance doesn't hotfix REAL_ITEM. fix in proper place.)
[27 Feb 20:01]
Tatjana A. Nuernberg
Fixing this in the same place as Bug#30832 in the name of consistency is a nice idea, but (rather expectedly) affects execution plans. It is still interesting in that we get neg(1) rather than -1 as an integer const in the first place or, to rephrase, that the item identifies as FUNC and the func-type as UNKNOWN (implying at face value that to identify neg() you'd look at the function's name(!!) instead, which I really won't comment on, which in turn might lead one to conclude that since nobody introduced FUNC_NEG identification, no such rewriting is taking place). Hence, this is looks like a good idea (to the extent that it fixes in the same place that the fix for #30832 does), but ends up too broad: class Item_func_neg :public Item_func_num1 { ... virtual enum Type type() const { return args[0]->basic_const_item() ? args[0]->type() : Item_func_num1::type(); } ... On the other hand, this only fixes the offending item-type "NAME_CONST" by making it transparent where possible (that is, returns the underlying type of a item_func_neg()). Which gives us, wait for it, this: Item::Type Item_name_const::type() const { ... /* 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() == FUNC_ITEM) ? (((Item_func *) value_item)->key_item()->type() : value_item->type()) : NULL_ITEM; }
[27 Feb 20:32]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/43104 ChangeSet@1.2608, 2008-02-27 20:31:50+01:00, tnurnberg@mysql.com +3 -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 in that when it is transparent with regard to basic_const_item(), it also is with regard to type().
[28 Feb 13:37]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/43139 ChangeSet@1.2595, 2008-02-28 13:35:56+01:00, tnurnberg@mysql.com +5 -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.
[28 Feb 14:01]
Tatjana A. Nuernberg
REVIEWERS! : ) There are three ChangeSets attached. This is not evolution, it is choice. 1 - Keep original patch for Bug#30832. Least intrusive code-wise, but a tad messy in terms of style. 2 - Rewrite Bug#30832 to apply more narrowly (only to NAME_CONST(), not to all unary minus). More elegant than 1, but uses funcname() to identify unary minus ("My func has no name!" "How does it smell?" "AWFUL!!!") 3 - Like 2, but uses new identifier NEG_FUNC (as it should be). As a result also teaches ndb about this type because otherwise, we'll lose some rewrites, and execution plans will be affected. Most stylish, but also most intrusive. See all and decide which you'd like! ; ) http://crazy.codetroop.com/randimg/?valfritt.jpg
[28 Feb 14:42]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/43149 ChangeSet@1.2595, 2008-02-28 13:54:58+01:00, tnurnberg@mysql.com +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.
[8 Mar 1:18]
Sergey Petrunia
Ok to push patch #3. Tatjana, thanks for going extra kilometer to present all the options.
[10 Mar 7:42]
Tatjana A. Nuernberg
autopushing to 5.0.58, 5.1.24, 6.0.5 in opt
[13 Mar 20:29]
Bugs System
Pushed into 6.0.5-alpha
[13 Mar 20:36]
Bugs System
Pushed into 5.1.24-rc
[13 Mar 20:43]
Bugs System
Pushed into 5.0.60
[15 Mar 22:17]
Jon Stephens
Documented bugfix in the 5.0.60, 5.1.24, and 6.0.5 changelogs, as follows:
Using NAME_CONST() with a negative number and an aggregate function
caused MySQL to crash. This could also have a negative impact on
replication.
[2 Apr 22:15]
Jon Stephens
Also noted in the 5.1.23-ndb-6.3.11 changelog.
[15 Apr 10:55]
Valeriy Kravchuk
Bug #36084 was marked as a duplicate of this one.
