Bug #50089 | Second call of procedure with view in subselect crashes server | ||
---|---|---|---|
Submitted: | 5 Jan 2010 14:57 | Modified: | 22 Nov 2010 0:35 |
Reporter: | Jørgen Løland | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 6.0 | OS: | Any |
Assigned to: | Roy Lyseng | CPU Architecture: | Any |
Tags: | optimizer_switch, semijoin, SP, VIEW |
[5 Jan 2010 14:57]
Jørgen Løland
[1 Feb 2010 14:46]
Roy Lyseng
The regression bug number is 45863. This is a preliminary analysis of the situation: View definition: SELECT t1field AS v1_field FROM t1 AS A WHERE A.t1field IN (SELECT t1field FROM t1); Select_lex graph: VS1(A) \ VS2(t1) query: SELECT t1field FROM t1 WHERE t1field IN (SELECT * FROM v1); expanded query: SELECT t1field FROM t1 WHERE t1field IN (SELECT t1field AS v1_field FROM t1 AS A WHERE A.t1field IN (SELECT t1field FROM t1)); Select_lex graph: S1(t1) \ S2(A) \ VS2(t1) after semijoin conversion: SELECT t1_field FROM t1 semijoin t1 AS A ON t1.t1_field = A.t1_field WHERE A.t1_field IN (SELECT t1_field FROM t1)); Now, S2 is optimized away and the table A is added to S1. The master field of VS2 points to S1 after conversion. However, the return_to field of VS2 points to VS1. This means that when re-resolving A.t1_field, function mark_select_range_as_dependent() is called with VS1 as current_sel and S1 as last_select arguments. Now, the master unit of VS1 does not have an "item", and we segfault.
[9 Feb 2010 12:40]
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/99719 3873 Roy Lyseng 2010-02-09 BUG#50089: Second call of procedure with view in subselect crashes server See bug report for an analysis of the situation. Problem occurs when mark_select_range_as_dependent() is called with two select_lex pointers that point into different query trees, one tree being the main query tree, the other being the tree representing the view. This problem is due to the fact that the function return_after_parsing() is used to provide pointer to the select_lex object representing the outer query specification of a subquery. However, the return_to field was not properly updated in all situations. But it was also noticed that outer_select()gives the same information as return_after_parsing(), and the data used by this function is always kept up-to-date. The bug was thus fixed by removing return_after_parsing() and associated data, and replacing calls with outer_select(). mysql-test/r/subselect_sj.result Test result for BUG#50089 mysql-test/r/subselect_sj_jcl6.result Test result for BUG#50089 mysql-test/t/subselect_sj.test Test case for BUG#50089 sql/item_subselect.cc Replaced references to return_after_parsing() with outer_select(). sql/sql_lex.cc Removed function return_after_parsing() and data field return_to. sql/sql_lex.h Removed function return_after_parsing() and data field return_to. sql/sql_parse.cc Replaced reference to return_after_parsing() with outer_select(). sql/sql_select.cc Replaced reference to return_after_parsing() with outer_select(). sql/sql_yacc.yy Replaced reference to return_after_parsing() with outer_select().
[9 Feb 2010 12:42]
Roy Lyseng
Please note that the attached bug fix depends on the fix for bug#49198. Without that fix, this fix will still cause an invalid result on second and subsequent executions.
[9 Feb 2010 21:38]
Guilhem Bichot
approved with minor comments sent by mail
[10 Feb 2010 7:57]
Tor Didriksen
See also: Bug #50996 Wrong result for second call of prepared statement with view in subselect
[10 Mar 2010 11:15]
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/102862 3804 Roy Lyseng 2010-03-10 Bug#50089: Second call of procedure with view in subselect crashes server The bug case contains a query that references a view. Here is the view definition: SELECT t1field AS v1_field FROM t1 AS A WHERE A.t1field IN (SELECT t1field FROM t1); When expanding the view at prepare time, this select_lex graph is created: VS1(A) \ VS2(t1) This is the query that is executed: SELECT t1field FROM t1 WHERE t1field IN (SELECT * FROM v1); At prepare time, the query is conceptually expanded to the following query: SELECT t1field FROM t1 WHERE t1field IN (SELECT t1field AS v1_field FROM t1 AS A WHERE A.t1field IN (SELECT t1field FROM t1)); Here is the select_lex graph after view expansion: S1(t1) \ S2(A) \ VS2(t1) The contents of select_lex VS1 is merged with the query graph and VS1 is discarded after merging. At first execution, semijoin conversion is performed, and the query is transformed to: SELECT t1_field FROM t1 semijoin t1 AS A ON t1.t1_field = A.t1_field WHERE A.t1_field IN (SELECT t1_field FROM t1)); Now, the select_lex object S2 is optimized away and the table A is added to S1. Here is the select_lex graph after transformation: S1(t1) \ VS2(t1) The master field of VS2 points to S1 after conversion. However, the return_to field of VS2 still points to VS1. First execution proceeds normally after this. At second execution, all items in the transformed query are first re-resolved. When re-resolving A.t1_field, function mark_select_range_as_dependent() is called with VS1 as current_sel and S1 as last_select arguments. Now, the master unit of VS1 does not have an "item", and we segfault. Problem occurs when mark_select_range_as_dependent() is called with two select_lex pointers that point into different query trees, one tree being the main query tree, the other being the tree representing the view. This problem is due to the fact that the function return_after_parsing() is used to provide pointer to the select_lex object representing the outer query specification of a subquery. However, the return_to field was not properly updated in all situations. But it was also noticed that outer_select() gives the same information as return_after_parsing(), and the data used by this function is always kept up-to-date. The bug was thus fixed by removing return_after_parsing() and associated data, and replacing calls with outer_select(). Notice also that queries within procedures internally create prepared statements, so the solution works equally well for procedures as well as for prepared statements. mysql-test/r/subselect_sj.result Test result for Bug#50089 mysql-test/r/subselect_sj_jcl6.result Test result for Bug#50089 mysql-test/t/subselect_sj.test Test case for Bug#50089 sql/item_subselect.cc Replaced references to return_after_parsing() with outer_select(). sql/sql_lex.cc Removed function return_after_parsing() and data field return_to. sql/sql_lex.h Removed function return_after_parsing() and data field return_to. sql/sql_parse.cc Replaced reference to return_after_parsing() with outer_select(). sql/sql_select.cc Replaced reference to return_after_parsing() with outer_select(). sql/sql_yacc.yy Replaced reference to return_after_parsing() with outer_select().
[10 Mar 2010 13:38]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100310133305-0jdlngbtrkoqzckh) (version source revid:alik@sun.com-20100310132404-uqarl0o0vlra2kjx) (merge vers: 6.0.14-alpha) (pib:16)
[13 Mar 2010 23:34]
Paul DuBois
Noted in 6.0.14 changelog. With semijoin optimization enabled, references to views within a subquery could cause a server crash.
[15 Mar 2010 13:45]
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/103247 3824 Roy Lyseng 2010-03-15 Bug#50089: Second call of procedure with view in subselect crashes server Followup commit to test case: Use lowercase table alias name to avoid platform dependent test results. mysql-test/r/subselect_sj.result Test result for Bug#50089 mysql-test/r/subselect_sj_jcl6.result Test result for Bug#50089 mysql-test/t/subselect_sj.test Rename table alias from A (upper case a) to a (lower case a).
[24 Mar 2010 8:14]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100324081249-yfwol7qtcek6dh7w) (version source revid:alik@sun.com-20100324081113-kc7x1iytnplww91u) (merge vers: 6.0.14-alpha) (pib:16)
[7 May 2010 12:17]
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/107741 3148 Roy Lyseng 2010-05-07 Bug#50089: Second call of procedure with view in subselect crashes server The bug case contains a query that references a view. Here is the view definition: SELECT t1field AS v1_field FROM t1 AS A WHERE A.t1field IN (SELECT t1field FROM t1); When expanding the view at prepare time, this select_lex graph is created: VS1(A) \ VS2(t1) This is the query that is executed: SELECT t1field FROM t1 WHERE t1field IN (SELECT * FROM v1); At prepare time, the query is conceptually expanded to the following query: SELECT t1field FROM t1 WHERE t1field IN (SELECT t1field AS v1_field FROM t1 AS A WHERE A.t1field IN (SELECT t1field FROM t1)); Here is the select_lex graph after view expansion: S1(t1) \ S2(A) \ VS2(t1) The contents of select_lex VS1 is merged with the query graph and VS1 is discarded after merging. At first execution, semijoin conversion is performed, and the query is transformed to: SELECT t1_field FROM t1 semijoin t1 AS A ON t1.t1_field = A.t1_field WHERE A.t1_field IN (SELECT t1_field FROM t1)); Now, the select_lex object S2 is optimized away and the table A is added to S1. Here is the select_lex graph after transformation: S1(t1) \ VS2(t1) The master field of VS2 points to S1 after conversion. However, the return_to field of VS2 still points to VS1. First execution proceeds normally after this. At second execution, all items in the transformed query are first re-resolved. When re-resolving A.t1_field, function mark_select_range_as_dependent() is called with VS1 as current_sel and S1 as last_select arguments. Now, the master unit of VS1 does not have an "item", and we segfault. Problem occurs when mark_select_range_as_dependent() is called with two select_lex pointers that point into different query trees, one tree being the main query tree, the other being the tree representing the view. This problem is due to the fact that the function return_after_parsing() is used to provide pointer to the select_lex object representing the outer query specification of a subquery. However, the return_to field was not properly updated in all situations. But it was also noticed that outer_select() gives the same information as return_after_parsing(), and the data used by this function is always kept up-to-date. The bug was thus fixed by removing return_after_parsing() and associated data, and replacing calls with outer_select(). Notice also that queries within procedures internally create prepared statements, so the solution works equally well for procedures as well as for prepared statements. mysql-test/r/subselect_sj.result Test result for Bug#50089 mysql-test/r/subselect_sj_jcl6.result Test result for Bug#50089 mysql-test/t/subselect_sj.test Test case for Bug#50089 sql/item_subselect.cc Replaced references to return_after_parsing() with outer_select(). sql/sql_lex.cc Removed function return_after_parsing() and data field return_to. sql/sql_lex.h Removed function return_after_parsing() and data field return_to. sql/sql_parse.cc Replaced reference to return_after_parsing() with outer_select(). sql/sql_select.cc Replaced reference to return_after_parsing() with outer_select(). sql/sql_yacc.yy Replaced reference to return_after_parsing() with outer_select(). revid:marc.alff@sun.com-20100310053357-iufi8n11rjkh8lrb..roy.lyseng@sun.com-20100310111425-7r30qg17f5z13ptd
[7 May 2010 12:21]
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/107742 3149 Roy Lyseng 2010-05-07 Bug#50089: Second call of procedure with view in subselect crashes server Followup commit to test case: Use lowercase table alias name to avoid platform dependent test results. mysql-test/r/subselect_sj.result Test result for Bug#50089 mysql-test/r/subselect_sj_jcl6.result Test result for Bug#50089 mysql-test/t/subselect_sj.test Rename table alias from A (upper case a) to a (lower case a). revid:alik@sun.com-20100315102711-m5b8u7banzzc30q7..roy.lyseng@sun.com-20100315134319-qe3k8vb0l371340w
[16 Aug 2010 6:31]
Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100816062819-bluwgdq8q4xysmlg) (version source revid:alik@sun.com-20100816062612-enatdwnv809iw3s9) (pib:20)
[13 Nov 2010 16:16]
Bugs System
Pushed into mysql-trunk 5.6.99-m5 (revid:alexander.nozdrin@oracle.com-20101113155825-czmva9kg4n31anmu) (version source revid:vasil.dimov@oracle.com-20100629074804-359l9m9gniauxr94) (merge vers: 5.6.99-m4) (pib:21)
[22 Nov 2010 0:35]
Paul DuBois
Noted in 5.6.1 changelog.
[23 Nov 2010 2:17]
Paul DuBois
Correction: No 5.6.1 changelog entry. Bug does not appear in any released 5.6.x version.