-
Norvald H. Ryeng authored
Problem: Some queries with subqueries and a HAVING clause that consists only of a column not in the select or grouping lists causes the server to crash. During parsing, an Item_ref is constructed for the HAVING column. The name of the column is resolved when JOIN::prepare calls fix_fields() on its having clause. Since the column is not mentioned in the select or grouping lists, a ref pointer is not found and a new Item_field is created instead. The Item_ref is replaced by the Item_field in the tree of HAVING clauses. Since the tree consists only of this item, the pointer that is updated is JOIN::having. However, st_select_lex::having still points to the Item_ref as the root of the tree of HAVING clauses. The bug is triggered when doing filesort for create_sort_index(). When find_all_keys() calls select->cond->walk() it eventually reaches Item_subselect::walk() where it continues to walk the having clauses from lex->having. This means that it finds the Item_ref instead of the new Item_field, and Item_ref::walk() tries to dereference the ref pointer, which is still null. The crash is reproducible only in 5.5, but the problem lies latent in 5.1 and trunk as well. Fix: After calling fix_fields on the having clause in JOIN::prepare(), set select_lex::having to point to the same item as JOIN::having. This patch also fixes a bug in 5.1 and 5.5 that is triggered if the query is executed as a prepared statement. The Item_field is created in the runtime arena when the query is prepared, and the pointer to the item is saved by st_select_lex::fix_prepare_information() and brought back as a dangling pointer when the query is executed, after the runtime arena has been reclaimed. Fix: Backport fix from trunk that switches to the permanent arena before calling Item_ref::fix_fields() in JOIN::prepare().
5f61cc43