-
Dag Wanvik authored
The problem is related to the changing value of found_rows during the query. It is evaluated more than once and the value in one case gives a NULL value for dayofmonth whereas another value gives a non-NULL value, which breaks things. In this case the subquery is materialized. The reason it changes is that initially, the value of found_rows is the the number of rows found during the previous query. Then, while evaluating the query, the sub-select modifies that value to the number of rows returned by the subquery. If those two values are sufficiently different (e.g. 101 in the first case and 1 in the second), the difference in the resulting null-ness of dayofmonth ensues. subselect_indexsubquery_engine::copy_ref_key has the following information: if (s_key->null_key) { /* If we have materialized the subquery: - this NULL ref item cannot be local to the subquery (any such conditions was handled during materialization) - neither can it be outer, because this case is separately managed in subselect_hash_sj_engine::exec(). */ The latter case is of interest here: in this case the search key was indeed *not* NULL before the materialization, but now it is NULL in the repro, because the number of rows returned from the subquery materialization is 1, not 101 as we had initially, and the former gives a NULL when fed into dayofmonth, whereas 101 gives 1. So, when we do the check above we enter and hit the assert. Because the code presumes a null value for the search argument would have been handled earlier, this case cannot be a case of HASH_SJ_ENGINE (asserted). The patch snapshots (into THD::previous_found_rows) the value of THD::limit_found_rows (renamed to current_found_rows) at the end of each query and consults that if/when FOUND_ROWS is performed throughout the next query. Also removed some inactive settings of limit_found_rows in opt_explain.cc The patch adds the repro test case to the regression tests.
Dag Wanvik authoredThe problem is related to the changing value of found_rows during the query. It is evaluated more than once and the value in one case gives a NULL value for dayofmonth whereas another value gives a non-NULL value, which breaks things. In this case the subquery is materialized. The reason it changes is that initially, the value of found_rows is the the number of rows found during the previous query. Then, while evaluating the query, the sub-select modifies that value to the number of rows returned by the subquery. If those two values are sufficiently different (e.g. 101 in the first case and 1 in the second), the difference in the resulting null-ness of dayofmonth ensues. subselect_indexsubquery_engine::copy_ref_key has the following information: if (s_key->null_key) { /* If we have materialized the subquery: - this NULL ref item cannot be local to the subquery (any such conditions was handled during materialization) - neither can it be outer, because this case is separately managed in subselect_hash_sj_engine::exec(). */ The latter case is of interest here: in this case the search key was indeed *not* NULL before the materialization, but now it is NULL in the repro, because the number of rows returned from the subquery materialization is 1, not 101 as we had initially, and the former gives a NULL when fed into dayofmonth, whereas 101 gives 1. So, when we do the check above we enter and hit the assert. Because the code presumes a null value for the search argument would have been handled earlier, this case cannot be a case of HASH_SJ_ENGINE (asserted). The patch snapshots (into THD::previous_found_rows) the value of THD::limit_found_rows (renamed to current_found_rows) at the end of each query and consults that if/when FOUND_ROWS is performed throughout the next query. Also removed some inactive settings of limit_found_rows in opt_explain.cc The patch adds the repro test case to the regression tests.
Loading