#At file:///home/gluh/MySQL/mysql-5.1-bugteam/ based on revid:tor.didriksen@stripped
3520 Sergey Glukhov 2010-12-14
Fixed following problems:
--Bug#52157 various crashes and assertions with multi-table update, stored function
--Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb
--Bug#57703 create view cause Assertion failed: 0, file .\item_subselect.cc, line 846
--Bug#57352 valgrind warnings when creating view
--Recently discovered problem when a nested materialized derived table is used
before being populated and it leads to incorrect result
We have several modes when we should disable subquery evaluation.
The reasons for disabling are different. It could be
uselessness of the evaluation as in case of 'CREATE VIEW'
or 'PREPARE stmt', or we should disable subquery evaluation
if tables are not locked yet as it happens in bug#54475, or
too early evaluation of subqueries can lead to wrong result
as it happened in Bug#19077.
Main problem is that if subquery items are treated as const
they are evaluated in ::fix_fields(), ::fix_length_and_dec()
of the parental items as a lot of these methods have
Item::val_...() calls inside.
We have to make subqueries non-const to prevent unnecessary
subquery evaluation. At the moment we have different methods
for this. Here is a list of these modes:
1. PREPARE stmt;
We use UNCACHEABLE_PREPARE flag.
It is set during parsing in sql_parse.cc, mysql_new_select() for
each SELECT_LEX object and cleared at the end of PREPARE in
sql_prepare.cc, init_stmt_after_parse(). If this flag is set
subquery becomes non-const and evaluation does not happen.
2. CREATE|ALTER VIEW, SHOW CREATE VIEW, I_S tables which
process FRM files
We use LEX::view_prepare_mode field. We set it before
view preparation and check this flag in
::fix_fields(), ::fix_length_and_dec().
Some bugs are fixed using this approach,
some are not(Bug#57352, Bug#57703). The problem here is
that we have a lot of ::fix_fields(), ::fix_length_and_dec()
where we use Item::val_...() calls for const items.
3. Derived tables with subquery = wrong result(Bug19077)
The reason of this bug is too early subquery evaluation.
It was fixed by adding Item::with_subselect field
The check of this field in appropriate places prevents
const item evaluation if the item have subquery.
The fix for Bug19077 fixes only the problem with
convert_constant_item() function and does not cover
other places(::fix_fields(), ::fix_length_and_dec() again)
where subqueries could be evaluated.
Example:
CREATE TABLE t1 (i INT, j BIGINT);
INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
SELECT * FROM (SELECT MIN(i) FROM t1
WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3;
DROP TABLE t1;
4. Derived tables with subquery where subquery
is evaluated before table locking(Bug#54475, Bug#52157)
Suggested solution is following:
-Introduce new field LEX::context_analysis_only with the following
possible flags:
#define CONTEXT_ANALYSIS_ONLY_PREPARE 1
#define CONTEXT_ANALYSIS_ONLY_VIEW 2
#define CONTEXT_ANALYSIS_ONLY_DERIVED 4
-Set/clean these flags when we perform
context analysis operation
-Item_subselect::const_item() returns
result depending on LEX::context_analysis_only.
If context_analysis_only is set then we return
FALSE that means that subquery is non-const.
As all subquery types are wrapped by Item_subselect
it allow as to make subquery non-const when
it's necessary.
@ mysql-test/r/derived.result
test case
@ mysql-test/r/multi_update.result
test case
@ mysql-test/r/view.result
test case
@ mysql-test/suite/innodb/r/innodb_multi_update.result
test case
@ mysql-test/suite/innodb/t/innodb_multi_update.test
test case
@ mysql-test/suite/innodb_plugin/r/innodb_multi_update.result
test case
@ mysql-test/suite/innodb_plugin/t/innodb_multi_update.test
test case
@ mysql-test/t/derived.test
test case
@ mysql-test/t/multi_update.test
test case
@ mysql-test/t/view.test
test case
@ sql/item.cc
--removed unnecessary code
@ sql/item_cmpfunc.cc
--removed unnecessary checks
--THD::is_context_analysis_only() is replaced with LEX::is_ps_or_view_context_analysis()
@ sql/item_func.cc
--refactored context analysis checks
@ sql/item_row.cc
--removed unnecessary checks
@ sql/item_subselect.cc
--removed unnecessary code
--added DBUG_ASSERT into Item_subselect::exec()
which asserts that subquery execution can not happen
if LEX::context_analysis_only is set, i.e. at context
analysis stage.
--Item_subselect::const_item()
Return FALSE if LEX::context_analysis_only is set.
It prevents subquery evaluation in ::fix_fields &
::fix_length_and_dec at context analysis stage.
@ sql/item_subselect.h
--removed unnecessary code
@ sql/mysql_priv.h
--Added new set of flags.
@ sql/sql_class.h
--removed unnecessary code
@ sql/sql_derived.cc
--added LEX::context_analysis_only analysis intialization/cleanup
@ sql/sql_lex.cc
--init LEX::context_analysis_only field
@ sql/sql_lex.h
--New LEX::context_analysis_only field
@ sql/sql_parse.cc
--removed unnecessary code
@ sql/sql_prepare.cc
--removed unnecessary code
--added LEX::context_analysis_only analysis intialization/cleanup
@ sql/sql_select.cc
--refactored context analysis checks
@ sql/sql_show.cc
--added LEX::context_analysis_only analysis intialization/cleanup
@ sql/sql_view.cc
--added LEX::context_analysis_only analysis intialization/cleanup
modified:
mysql-test/r/derived.result
mysql-test/r/multi_update.result
mysql-test/r/view.result
mysql-test/suite/innodb/r/innodb_multi_update.result
mysql-test/suite/innodb/t/innodb_multi_update.test
mysql-test/suite/innodb_plugin/r/innodb_multi_update.result
mysql-test/suite/innodb_plugin/t/innodb_multi_update.test
mysql-test/t/derived.test
mysql-test/t/multi_update.test
mysql-test/t/view.test
sql/item.cc
sql/item_cmpfunc.cc
sql/item_func.cc
sql/item_row.cc
sql/item_subselect.cc
sql/item_subselect.h
sql/mysql_priv.h
sql/sql_class.h
sql/sql_derived.cc
sql/sql_lex.cc
sql/sql_lex.h
sql/sql_parse.cc
sql/sql_prepare.cc
sql/sql_select.cc
sql/sql_show.cc
sql/sql_view.cc
=== modified file 'mysql-test/r/derived.result'
--- a/mysql-test/r/derived.result 2009-07-11 18:44:29 +0000
+++ b/mysql-test/r/derived.result 2010-12-14 09:33:03 +0000
@@ -400,4 +400,15 @@ SELECT 0 FROM
(SELECT 0) t61;
0
0
+#
+# A nested materialized derived table is used before being populated.
+# (addon for bug#19077)
+#
+CREATE TABLE t1 (i INT, j BIGINT);
+INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
+SELECT * FROM (SELECT MIN(i) FROM t1
+WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3;
+MIN(i)
+1
+DROP TABLE t1;
# End of 5.0 tests
=== modified file 'mysql-test/r/multi_update.result'
--- a/mysql-test/r/multi_update.result 2010-09-07 07:58:05 +0000
+++ b/mysql-test/r/multi_update.result 2010-12-14 09:33:03 +0000
@@ -659,4 +659,15 @@ Error 1242 Subquery returns more than 1
Error 1242 Subquery returns more than 1 row
DROP TABLE t1, t2, t3;
SET SESSION sql_safe_updates = DEFAULT;
+#
+# Bug#52157 various crashes and assertions with multi-table update, stored function
+#
+CREATE FUNCTION f1 () RETURNS BLOB RETURN 1;
+CREATE TABLE t1 (f1 DATE);
+INSERT INTO t1 VALUES('2001-01-01');
+UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1;
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '1'
+DROP FUNCTION f1;
+DROP TABLE t1;
end of tests
=== modified file 'mysql-test/r/view.result'
--- a/mysql-test/r/view.result 2010-11-30 17:51:25 +0000
+++ b/mysql-test/r/view.result 2010-12-14 09:33:03 +0000
@@ -3884,6 +3884,19 @@ CREATE VIEW v1 AS SELECT 1 from t1
WHERE t1.b <=> (SELECT a FROM t1 WHERE a < SOME(SELECT '1'));
DROP VIEW v1;
DROP TABLE t1;
+#
+# Bug#57703 create view cause Assertion failed: 0, file .\item_subselect.cc, line 846
+#
+CREATE TABLE t1(a int);
+CREATE VIEW v1 AS SELECT 1 FROM t1 GROUP BY
+SUBSTRING(1 FROM (SELECT 3 FROM t1 WHERE a >= ANY(SELECT 1)));
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# Bug#57352 valgrind warnings when creating view
+#
+CREATE VIEW v1 AS SELECT 1 IN (1 LIKE 2,0) AS f;
+DROP VIEW v1;
# -----------------------------------------------------------------
# -- End of 5.1 tests.
# -----------------------------------------------------------------
=== modified file 'mysql-test/suite/innodb/r/innodb_multi_update.result'
--- a/mysql-test/suite/innodb/r/innodb_multi_update.result 2010-05-05 10:40:01 +0000
+++ b/mysql-test/suite/innodb/r/innodb_multi_update.result 2010-12-14 09:33:03 +0000
@@ -74,3 +74,11 @@ a b
4 14
5 15
drop table bug38999_1,bug38999_2;
+#
+# Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb
+#
+CREATE TABLE t1(f1 INT) ENGINE=INNODB;
+INSERT INTO t1 VALUES(1);
+UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1;
+ERROR 21000: Operand should contain 1 column(s)
+DROP TABLE t1;
=== modified file 'mysql-test/suite/innodb/t/innodb_multi_update.test'
--- a/mysql-test/suite/innodb/t/innodb_multi_update.test 2010-05-05 10:40:01 +0000
+++ b/mysql-test/suite/innodb/t/innodb_multi_update.test 2010-12-14 09:33:03 +0000
@@ -27,3 +27,14 @@ select * from bug38999_1;
select * from bug38999_2;
drop table bug38999_1,bug38999_2;
+
+
+--echo #
+--echo # Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb
+--echo #
+CREATE TABLE t1(f1 INT) ENGINE=INNODB;
+INSERT INTO t1 VALUES(1);
+--error ER_OPERAND_COLUMNS
+UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1;
+DROP TABLE t1;
+
=== modified file 'mysql-test/suite/innodb_plugin/r/innodb_multi_update.result'
--- a/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result 2010-05-05 10:44:25 +0000
+++ b/mysql-test/suite/innodb_plugin/r/innodb_multi_update.result 2010-12-14 09:33:03 +0000
@@ -74,3 +74,11 @@ a b
4 14
5 15
drop table bug38999_1,bug38999_2;
+#
+# Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb
+#
+CREATE TABLE t1(f1 INT) ENGINE=INNODB;
+INSERT INTO t1 VALUES(1);
+UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1;
+ERROR 21000: Operand should contain 1 column(s)
+DROP TABLE t1;
=== modified file 'mysql-test/suite/innodb_plugin/t/innodb_multi_update.test'
--- a/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test 2010-06-03 09:46:37 +0000
+++ b/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test 2010-12-14 09:33:03 +0000
@@ -27,3 +27,14 @@ select * from bug38999_1;
select * from bug38999_2;
drop table bug38999_1,bug38999_2;
+
+
+--echo #
+--echo # Bug#54475 improper error handling causes cascading crashing failures in innodb/ndb
+--echo #
+CREATE TABLE t1(f1 INT) ENGINE=INNODB;
+INSERT INTO t1 VALUES(1);
+--error ER_OPERAND_COLUMNS
+UPDATE (SELECT ((SELECT 1 FROM t1), 1) FROM t1 WHERE (SELECT 1 FROM t1)) x, (SELECT 1) AS d SET d.f1 = 1;
+DROP TABLE t1;
+
=== modified file 'mysql-test/t/derived.test'
--- a/mysql-test/t/derived.test 2009-07-11 18:44:29 +0000
+++ b/mysql-test/t/derived.test 2010-12-14 09:33:03 +0000
@@ -301,4 +301,15 @@ SELECT 0 FROM
(SELECT 0) t56, (SELECT 0) t57, (SELECT 0) t58, (SELECT 0) t59, (SELECT 0) t60,
(SELECT 0) t61; # 61 == MAX_TABLES
+--echo #
+--echo # A nested materialized derived table is used before being populated.
+--echo # (addon for bug#19077)
+--echo #
+
+CREATE TABLE t1 (i INT, j BIGINT);
+INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
+SELECT * FROM (SELECT MIN(i) FROM t1
+WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3;
+DROP TABLE t1;
+
--echo # End of 5.0 tests
=== modified file 'mysql-test/t/multi_update.test'
--- a/mysql-test/t/multi_update.test 2010-09-07 07:58:05 +0000
+++ b/mysql-test/t/multi_update.test 2010-12-14 09:33:03 +0000
@@ -673,4 +673,15 @@ SET t3.a = 0;
DROP TABLE t1, t2, t3;
SET SESSION sql_safe_updates = DEFAULT;
+--echo #
+--echo # Bug#52157 various crashes and assertions with multi-table update, stored function
+--echo #
+
+CREATE FUNCTION f1 () RETURNS BLOB RETURN 1;
+CREATE TABLE t1 (f1 DATE);
+INSERT INTO t1 VALUES('2001-01-01');
+UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1;
+DROP FUNCTION f1;
+DROP TABLE t1;
+
--echo end of tests
=== modified file 'mysql-test/t/view.test'
--- a/mysql-test/t/view.test 2010-04-06 07:26:59 +0000
+++ b/mysql-test/t/view.test 2010-12-14 09:33:03 +0000
@@ -3925,6 +3925,22 @@ WHERE t1.b <=> (SELECT a FROM t1 WHERE a
DROP VIEW v1;
DROP TABLE t1;
+--echo #
+--echo # Bug#57703 create view cause Assertion failed: 0, file .\item_subselect.cc, line 846
+--echo #
+
+CREATE TABLE t1(a int);
+CREATE VIEW v1 AS SELECT 1 FROM t1 GROUP BY
+SUBSTRING(1 FROM (SELECT 3 FROM t1 WHERE a >= ANY(SELECT 1)));
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#57352 valgrind warnings when creating view
+--echo #
+CREATE VIEW v1 AS SELECT 1 IN (1 LIKE 2,0) AS f;
+DROP VIEW v1;
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.1 tests.
--echo # -----------------------------------------------------------------
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2010-11-18 13:11:18 +0000
+++ b/sql/item.cc 2010-12-14 09:33:03 +0000
@@ -1712,16 +1712,7 @@ bool agg_item_set_converter(DTCollation
if (!(conv= (*arg)->safe_charset_converter(coll.collation)) &&
((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII))
- {
- /*
- We should disable const subselect item evaluation because
- subselect transformation does not happen in view_prepare_mode
- and thus val_...() methods can not be called for const items.
- */
- bool resolve_const= ((*arg)->type() == Item::SUBSELECT_ITEM &&
- thd->lex->view_prepare_mode) ? FALSE : TRUE;
- conv= new Item_func_conv_charset(*arg, coll.collation, resolve_const);
- }
+ conv= new Item_func_conv_charset(*arg, coll.collation, 1);
if (!conv)
{
=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc 2010-09-09 12:48:06 +0000
+++ b/sql/item_cmpfunc.cc 2010-12-14 09:33:03 +0000
@@ -401,7 +401,7 @@ static bool convert_constant_item(THD *t
Field *field= field_item->field;
int result= 0;
- if (!(*item)->with_subselect && (*item)->const_item())
+ if ((*item)->const_item())
{
TABLE *table= field->table;
ulong orig_sql_mode= thd->variables.sql_mode;
@@ -497,7 +497,7 @@ void Item_bool_func2::fix_length_and_dec
}
thd= current_thd;
- if (!thd->is_context_analysis_only())
+ if (!thd->lex->is_ps_or_view_context_analysis())
{
if (args[0]->real_item()->type() == FIELD_ITEM)
{
@@ -801,7 +801,7 @@ Arg_comparator::can_compare_as_dates(Ite
confuse storage engines since in context analysis mode tables
aren't locked.
*/
- if (!thd->is_context_analysis_only() &&
+ if (!thd->lex->is_ps_or_view_context_analysis() &&
cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() &&
(str_arg->type() != Item::FUNC_ITEM ||
((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
@@ -1027,7 +1027,7 @@ Item** Arg_comparator::cache_converted_c
Item_result type)
{
/* Don't need cache if doing context analysis only. */
- if (!thd_arg->is_context_analysis_only() &&
+ if (!thd->lex->is_ps_or_view_context_analysis() &&
(*value)->const_item() && type != (*value)->result_type())
{
Item_cache *cache= Item_cache::get_cache(*value, type);
@@ -4686,7 +4686,7 @@ bool Item_func_like::fix_fields(THD *thd
return TRUE;
}
- if (escape_item->const_item() && !thd->lex->view_prepare_mode)
+ if (escape_item->const_item())
{
/* If we are on execution stage */
String *escape_str= escape_item->val_str(&cmp.value1);
=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc 2010-11-26 12:51:48 +0000
+++ b/sql/item_func.cc 2010-12-14 09:33:03 +0000
@@ -6066,7 +6066,7 @@ Item_func_sp::fix_fields(THD *thd, Item
if (res)
DBUG_RETURN(res);
- if (thd->lex->view_prepare_mode)
+ if (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)
{
/*
Here we check privileges of the stored routine only during view
=== modified file 'sql/item_row.cc'
--- a/sql/item_row.cc 2010-03-19 06:21:37 +0000
+++ b/sql/item_row.cc 2010-12-14 09:33:03 +0000
@@ -73,12 +73,8 @@ bool Item_row::fix_fields(THD *thd, Item
used_tables_cache |= item->used_tables();
const_item_cache&= item->const_item() && !with_null;
not_null_tables_cache|= item->not_null_tables();
- /*
- Some subqueries transformations aren't done in the view_prepare_mode thus
- is_null() will fail. So we skip is_null() calculation for CREATE VIEW as
- not necessary.
- */
- if (const_item_cache && !thd->lex->view_prepare_mode)
+
+ if (const_item_cache)
{
if (item->cols() > 1)
with_null|= item->null_inside();
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2010-10-18 12:12:27 +0000
+++ b/sql/item_subselect.cc 2010-12-14 09:33:03 +0000
@@ -123,20 +123,6 @@ void Item_subselect::cleanup()
}
-/*
- We cannot use generic Item::safe_charset_converter() because
- Subselect transformation does not happen in view_prepare_mode
- and thus we can not evaluate val_...() for const items.
-*/
-
-Item *Item_subselect::safe_charset_converter(CHARSET_INFO *tocs)
-{
- Item_func_conv_charset *conv=
- new Item_func_conv_charset(this, tocs, thd->lex->view_prepare_mode ? 0 : 1);
- return conv->safe ? conv : NULL;
-}
-
-
void Item_singlerow_subselect::cleanup()
{
DBUG_ENTER("Item_singlerow_subselect::cleanup");
@@ -271,6 +257,7 @@ bool Item_subselect::exec()
if (thd->is_error() || thd->killed)
return 1;
+ DBUG_ASSERT(!thd->lex->context_analysis_only);
/*
Simulate a failure in sub-query execution. Used to test e.g.
out of memory or query being killed conditions.
@@ -307,7 +294,7 @@ table_map Item_subselect::used_tables()
bool Item_subselect::const_item() const
{
- return const_item_cache;
+ return thd->lex->context_analysis_only ? FALSE : const_item_cache;
}
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
@@ -1638,7 +1625,8 @@ bool Item_in_subselect::fix_fields(THD *
{
bool result = 0;
- if (thd_arg->lex->view_prepare_mode && left_expr && !left_expr->fixed)
+ if ((thd_arg->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) &&
+ left_expr && !left_expr->fixed)
result = left_expr->fix_fields(thd_arg, &left_expr);
return result || Item_subselect::fix_fields(thd_arg, ref);
=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h 2010-04-06 07:26:59 +0000
+++ b/sql/item_subselect.h 2010-12-14 09:33:03 +0000
@@ -126,7 +126,6 @@ public:
virtual void reset_value_registration() {}
enum_parsing_place place() { return parsing_place; }
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
- Item *safe_charset_converter(CHARSET_INFO *tocs);
/**
Get the SELECT_LEX structure associated with this Item.
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2010-10-07 08:13:11 +0000
+++ b/sql/mysql_priv.h 2010-12-14 09:33:03 +0000
@@ -566,17 +566,42 @@ protected:
#define MY_CHARSET_BIN_MB_MAXLEN 1
+/*
+ Flags below are set when we perform
+ context analysis of the statement and make
+ subqueries non-const. It prevents subquery
+ evaluation at context analysis stage.
+*/
+
+/*
+ Don't evaluate this subquery during statement prepare even if
+ it's a constant one. The flag is switched off in the end of
+ mysqld_stmt_prepare.
+*/
+#define CONTEXT_ANALYSIS_ONLY_PREPARE 1
+/*
+ Special JOIN::prepare mode: changing of query is prohibited.
+ When creating a view, we need to just check its syntax omitting
+ any optimizations: afterwards definition of the view will be
+ reconstructed by means of ::print() methods and written to
+ to an .frm file. We need this definition to stay untouched.
+*/
+#define CONTEXT_ANALYSIS_ONLY_VIEW 2
+/*
+ Don't evaluate this subquery during derived table prepare even if
+ it's a constant one.
+*/
+#define CONTEXT_ANALYSIS_ONLY_DERIVED 4
+
// uncachable cause
#define UNCACHEABLE_DEPENDENT 1
#define UNCACHEABLE_RAND 2
#define UNCACHEABLE_SIDEEFFECT 4
/// forcing to save JOIN for explain
#define UNCACHEABLE_EXPLAIN 8
-/** Don't evaluate subqueries in prepare even if they're not correlated */
-#define UNCACHEABLE_PREPARE 16
/* For uncorrelated SELECT in an UNION with some correlated SELECTs */
-#define UNCACHEABLE_UNITED 32
-#define UNCACHEABLE_CHECKOPTION 64
+#define UNCACHEABLE_UNITED 16
+#define UNCACHEABLE_CHECKOPTION 32
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
#define UNDEF_POS (-1)
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2010-10-23 12:55:44 +0000
+++ b/sql/sql_class.h 2010-12-14 09:33:03 +0000
@@ -2180,8 +2180,6 @@ public:
(variables.sql_mode & MODE_STRICT_ALL_TABLES)));
}
void set_status_var_init();
- bool is_context_analysis_only()
- { return stmt_arena->is_stmt_prepare() || lex->view_prepare_mode; }
void reset_n_backup_open_tables_state(Open_tables_state *backup);
void restore_backup_open_tables_state(Open_tables_state *backup);
void reset_sub_statement_state(Sub_statement_state *backup, uint new_state);
=== modified file 'sql/sql_derived.cc'
--- a/sql/sql_derived.cc 2010-06-10 20:45:22 +0000
+++ b/sql/sql_derived.cc 2010-12-14 09:33:03 +0000
@@ -147,10 +147,11 @@ bool mysql_derived_prepare(THD *thd, LEX
if (!(derived_result= new select_union))
DBUG_RETURN(TRUE); // out of memory
+ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED;
// st_select_lex_unit::prepare correctly work for single select
if ((res= unit->prepare(thd, derived_result, 0)))
goto exit;
-
+ lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED;
if ((res= check_duplicate_names(unit->types, 0)))
goto exit;
=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc 2010-07-30 20:33:10 +0000
+++ b/sql/sql_lex.cc 2010-12-14 09:33:03 +0000
@@ -305,7 +305,7 @@ void lex_start(THD *thd)
lex->select_lex.group_list.empty();
lex->describe= 0;
lex->subqueries= FALSE;
- lex->view_prepare_mode= FALSE;
+ lex->context_analysis_only= 0;
lex->derived_tables= 0;
lex->lock_option= TL_READ;
lex->safe_to_cache_query= 1;
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2010-08-18 04:56:06 +0000
+++ b/sql/sql_lex.h 2010-12-14 09:33:03 +0000
@@ -1715,14 +1715,8 @@ typedef struct st_lex : public Query_tab
bool verbose, no_write_to_binlog;
bool tx_chain, tx_release;
- /*
- Special JOIN::prepare mode: changing of query is prohibited.
- When creating a view, we need to just check its syntax omitting
- any optimizations: afterwards definition of the view will be
- reconstructed by means of ::print() methods and written to
- to an .frm file. We need this definition to stay untouched.
- */
- bool view_prepare_mode;
+
+ uint8 context_analysis_only;
bool safe_to_cache_query;
bool subqueries, ignore;
st_parsing_options parsing_options;
@@ -1843,6 +1837,13 @@ typedef struct st_lex : public Query_tab
delete_dynamic(&plugins);
}
+ inline bool is_ps_or_view_context_analysis()
+ {
+ return (context_analysis_only &
+ (CONTEXT_ANALYSIS_ONLY_PREPARE |
+ CONTEXT_ANALYSIS_ONLY_VIEW));
+ }
+
inline void uncacheable(uint8 cause)
{
safe_to_cache_query= 0;
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-10-23 12:55:44 +0000
+++ b/sql/sql_parse.cc 2010-12-14 09:33:03 +0000
@@ -5865,13 +5865,6 @@ mysql_new_select(LEX *lex, bool move_dow
DBUG_RETURN(1);
}
select_lex->nest_level= lex->nest_level;
- /*
- Don't evaluate this subquery during statement prepare even if
- it's a constant one. The flag is switched off in the end of
- mysqld_stmt_prepare.
- */
- if (thd->stmt_arena->is_stmt_prepare())
- select_lex->uncacheable|= UNCACHEABLE_PREPARE;
if (move_down)
{
SELECT_LEX_UNIT *unit;
=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc 2010-11-03 10:24:47 +0000
+++ b/sql/sql_prepare.cc 2010-12-14 09:33:03 +0000
@@ -1688,7 +1688,7 @@ static bool mysql_test_create_view(Prepa
if (open_normal_and_derived_tables(thd, tables, 0))
goto err;
- lex->view_prepare_mode= 1;
+ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
res= select_like_stmt_test(stmt, 0, 0);
err:
@@ -2234,19 +2234,6 @@ end:
}
-/** Init PS/SP specific parse tree members. */
-
-static void init_stmt_after_parse(LEX *lex)
-{
- SELECT_LEX *sl= lex->all_selects_list;
- /*
- Switch off a temporary flag that prevents evaluation of
- subqueries in statement prepare.
- */
- for (; sl; sl= sl->next_select_in_list())
- sl->uncacheable&= ~UNCACHEABLE_PREPARE;
-}
-
/**
SQLCOM_PREPARE implementation.
@@ -3080,6 +3067,7 @@ bool Prepared_statement::prepare(const c
parser_state.m_lip.stmt_prepare_mode= TRUE;
lex_start(thd);
+ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_PREPARE;
error= parse_sql(thd, & parser_state, NULL) ||
thd->is_error() ||
@@ -3132,7 +3120,7 @@ bool Prepared_statement::prepare(const c
if (error == 0)
{
setup_set_params();
- init_stmt_after_parse(lex);
+ lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
state= Query_arena::PREPARED;
flags&= ~ (uint) IS_IN_USE;
/*
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2010-11-26 12:51:48 +0000
+++ b/sql/sql_select.cc 2010-12-14 09:33:03 +0000
@@ -538,7 +538,8 @@ JOIN::prepare(Item ***rref_pointer_array
thd->lex->allow_sum_func= save_allow_sum_func;
}
- if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE))
+ if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) &&
+ !(select_options & SELECT_DESCRIBE))
{
Item_subselect *subselect;
/* Is it subselect? */
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2010-11-30 17:51:25 +0000
+++ b/sql/sql_show.cc 2010-12-14 09:33:03 +0000
@@ -718,7 +718,7 @@ mysqld_show_create(THD *thd, TABLE_LIST
table_list->table_name));
/* We want to preserve the tree for views. */
- thd->lex->view_prepare_mode= TRUE;
+ thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
{
Show_create_error_handler view_error_suppressor(thd, table_list);
@@ -3315,7 +3315,7 @@ int get_all_tables(THD *thd, TABLE_LIST
uint derived_tables= lex->derived_tables;
int error= 1;
Open_tables_state open_tables_state_backup;
- bool save_view_prepare_mode= lex->view_prepare_mode;
+ uint8 save_context_analysis_only= lex->context_analysis_only;
Query_tables_list query_tables_list_backup;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *sctx= thd->security_ctx;
@@ -3323,7 +3323,7 @@ int get_all_tables(THD *thd, TABLE_LIST
uint table_open_method;
DBUG_ENTER("get_all_tables");
- lex->view_prepare_mode= TRUE;
+ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
/*
@@ -3540,7 +3540,7 @@ err:
lex->restore_backup_query_tables_list(&query_tables_list_backup);
lex->derived_tables= derived_tables;
lex->all_selects_list= old_all_select_lex;
- lex->view_prepare_mode= save_view_prepare_mode;
+ lex->context_analysis_only= save_context_analysis_only;
lex->sql_command= save_sql_command;
DBUG_RETURN(error);
}
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-06-11 12:52:06 +0000
+++ b/sql/sql_view.cc 2010-12-14 09:33:03 +0000
@@ -545,7 +545,7 @@ bool mysql_create_view(THD *thd, TABLE_L
}
/* prepare select to resolve all fields */
- lex->view_prepare_mode= 1;
+ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
if (unit->prepare(thd, 0, 0))
{
/*
Attachment: [text/bzr-bundle] bzr/sergey.glukhov@oracle.com-20101214093303-wmo9mqcb8rz0wv9f.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-bugteam branch (sergey.glukhov:3520) Bug#52157Bug#54475 Bug#57352 Bug#57703 | Sergey Glukhov | 14 Dec |