Commit 43d7fb43 authored by Georgi Kodinov's avatar Georgi Kodinov

Bug #46175: NULL read_view and consistent read assertion

The SE API requires mysql to notify the storage engine that
it's going to read certain tables at the beginning of the 
statement (by calling start_stmt(), store_lock() or
external_lock()).
These are typically called by the lock_tables(). 
However SHOW CREATE TABLE is not pre-locking the tables
because it's not expected to access the data at all.
But for some view definitions (that include comparing a
date/datetime/timestamp column to a string returning
scalar subquery) the JOIN::prepare may still access data
when materializing the scalar non-correlated subquery
in Arg_comparator::can_compare_as_dates().
Fixed by not materializing the subquery when the function
is called in a SHOW/EXPLAIN/CREATE VIEW
parent b7ceeccd
...@@ -2251,4 +2251,26 @@ c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00'; ...@@ -2251,4 +2251,26 @@ c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
DROP TABLE t1; DROP TABLE t1;
#
# Bug #46175: NULL read_view and consistent read assertion
#
CREATE TABLE t1(a CHAR(13),KEY(a)) ENGINE=innodb;
CREATE TABLE t2(b DATETIME,KEY(b)) ENGINE=innodb;
INSERT INTO t1 VALUES (),();
INSERT INTO t2 VALUES (),();
CREATE OR REPLACE VIEW v1 AS SELECT 1 FROM t2
WHERE b =(SELECT a FROM t1 LIMIT 1);
CREATE PROCEDURE p1(num INT)
BEGIN
DECLARE i INT DEFAULT 0;
REPEAT
SHOW CREATE VIEW v1;
SET i:=i+1;
UNTIL i>num END REPEAT;
END|
# Should not crash
# Should not crash
DROP PROCEDURE p1;
DROP VIEW v1;
DROP TABLE t1,t2;
End of 5.1 tests End of 5.1 tests
...@@ -489,5 +489,51 @@ EXPLAIN SELECT * FROM t1 WHERE a = 'TEST' AND ...@@ -489,5 +489,51 @@ EXPLAIN SELECT * FROM t1 WHERE a = 'TEST' AND
c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00'; c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00';
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug #46175: NULL read_view and consistent read assertion
--echo #
CREATE TABLE t1(a CHAR(13),KEY(a)) ENGINE=innodb;
CREATE TABLE t2(b DATETIME,KEY(b)) ENGINE=innodb;
INSERT INTO t1 VALUES (),();
INSERT INTO t2 VALUES (),();
CREATE OR REPLACE VIEW v1 AS SELECT 1 FROM t2
WHERE b =(SELECT a FROM t1 LIMIT 1);
--disable_query_log
--disable_result_log
CONNECT (con1, localhost, root,,);
--enable_query_log
--enable_result_log
CONNECTION default;
DELIMITER |;
CREATE PROCEDURE p1(num INT)
BEGIN
DECLARE i INT DEFAULT 0;
REPEAT
SHOW CREATE VIEW v1;
SET i:=i+1;
UNTIL i>num END REPEAT;
END|
DELIMITER ;|
--echo # Should not crash
--disable_query_log
--disable_result_log
--send CALL p1(1000)
CONNECTION con1;
--echo # Should not crash
CALL p1(1000);
CONNECTION default;
--reap
--enable_query_log
--enable_result_log
DISCONNECT con1;
DROP PROCEDURE p1;
DROP VIEW v1;
DROP TABLE t1,t2;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -785,15 +785,21 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value) ...@@ -785,15 +785,21 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value)
if (cmp_type != CMP_DATE_DFLT) if (cmp_type != CMP_DATE_DFLT)
{ {
THD *thd= current_thd;
/* /*
Do not cache GET_USER_VAR() function as its const_item() may return TRUE Do not cache GET_USER_VAR() function as its const_item() may return TRUE
for the current thread but it still may change during the execution. for the current thread but it still may change during the execution.
Don't use cache while in the context analysis mode only (i.e. for
EXPLAIN/CREATE VIEW and similar queries). Cache is useless in such
cases and can cause problems. For example evaluating subqueries can
confuse storage engines since in context analysis mode tables
aren't locked.
*/ */
if (cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() && if (!thd->is_context_analysis_only() &&
cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() &&
(str_arg->type() != Item::FUNC_ITEM || (str_arg->type() != Item::FUNC_ITEM ||
((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC)) ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
{ {
THD *thd= current_thd;
ulonglong value; ulonglong value;
bool error; bool error;
String tmp, *str_val= 0; String tmp, *str_val= 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment