From 20a2e1d0ac46e375ee7246576b541624c6f8f028 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Jul 2011 11:20:55 +0300 Subject: [PATCH] Fix of LP BUG#777809 There are 2 volatile condition constructions AND/OR constructions and fields(references) when first good supported to be top elements of conditions because it is normal practice (see copy_andor_structure for example) fields without any expression in the condition is really rare and mostly useless case however it could lead to problems when optimiser changes/moves them unaware of other variables referring to them. An easy solution of this problem is just to replace single field in a condition with equivalent expression well supported by the server ( -> != 0). mysql-test/r/view.result: New test added. mysql-test/t/view.test: New test added. sql/sql_parse.cc: -> != 0 sql/sql_yacc.yy: -> != 0 --- mysql-test/r/view.result | 17 +++++++++++++++++ mysql-test/t/view.test | 20 ++++++++++++++++++++ sql/sql_parse.cc | 23 +++++++++++++++++++++++ sql/sql_yacc.yy | 6 +++--- 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 80f19bd2fa9..93ebb3365b4 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3906,6 +3906,23 @@ SELECT * FROM v1; a DROP VIEW v1; DROP TABLE t1; +# +# LP BUG#777809 (a retrograded condition for view ON) +# +CREATE TABLE t1 ( f1 int NOT NULL , f6 int NOT NULL ) ; +INSERT IGNORE INTO t1 VALUES (20, 2); +CREATE TABLE t2 ( f3 int NOT NULL ) ; +INSERT IGNORE INTO t2 VALUES (7); +CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2; +PREPARE prep_stmt FROM 'SELECT t1.f6 FROM t1 RIGHT JOIN v2 ON v2.f3 WHERE t1.f1 != 0'; +EXECUTE prep_stmt; +f6 +2 +EXECUTE prep_stmt; +f6 +2 +drop view v2; +drop table t1,t2; # ----------------------------------------------------------------- # -- End of 5.1 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 2eed4fad18d..644fbe0443f 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3953,6 +3953,26 @@ SELECT * FROM v1; DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # LP BUG#777809 (a retrograded condition for view ON) +--echo # + +CREATE TABLE t1 ( f1 int NOT NULL , f6 int NOT NULL ) ; +INSERT IGNORE INTO t1 VALUES (20, 2); + +CREATE TABLE t2 ( f3 int NOT NULL ) ; +INSERT IGNORE INTO t2 VALUES (7); + +CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2; + +PREPARE prep_stmt FROM 'SELECT t1.f6 FROM t1 RIGHT JOIN v2 ON v2.f3 WHERE t1.f1 != 0'; + +EXECUTE prep_stmt; +EXECUTE prep_stmt; + +drop view v2; +drop table t1,t2; + --echo # ----------------------------------------------------------------- --echo # -- End of 5.1 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1544c13f666..1d833d540a5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6890,6 +6890,28 @@ push_new_name_resolution_context(THD *thd, } +/** + Fix condition which contains only field (f turns to f <> 0 ) + + @param cond The condition to fix + + @return fixed condition +*/ + +Item *normalize_cond(Item *cond) +{ + if (cond) + { + Item::Type type= cond->type(); + if (type == Item::FIELD_ITEM || type == Item::REF_ITEM) + { + cond= new Item_func_ne(cond, new Item_int(0)); + } + } + return cond; +} + + /** Add an ON condition to the second operand of a JOIN ... ON. @@ -6908,6 +6930,7 @@ void add_join_on(TABLE_LIST *b, Item *expr) { if (expr) { + expr= normalize_cond(expr); if (!b->on_expr) b->on_expr= expr; else diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6f89b2bd837..c84b549bbc0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -9029,7 +9029,7 @@ where_clause: expr { SELECT_LEX *select= Select; - select->where= $3; + select->where= normalize_cond($3); select->parsing_place= NO_MATTER; if ($3) $3->top_level_item(); @@ -9045,7 +9045,7 @@ having_clause: expr { SELECT_LEX *sel= Select; - sel->having= $3; + sel->having= normalize_cond($3); sel->parsing_place= NO_MATTER; if ($3) $3->top_level_item(); @@ -10483,7 +10483,7 @@ wild_and_where: } | WHERE expr { - Select->where= $2; + Select->where= normalize_cond($2); if ($2) $2->top_level_item(); }