diff options
author | igor@rurik.mysql.com <> | 2005-07-16 18:28:09 -0700 |
---|---|---|
committer | igor@rurik.mysql.com <> | 2005-07-16 18:28:09 -0700 |
commit | 553f2a59f37e0e12f245134f95ea5d93a342b77e (patch) | |
tree | 5adb79b583d6818c30f26a1c7d4f8adaffce4367 /sql/sql_select.cc | |
parent | 36945e144c73d2da0c03c108603aecedf24b4608 (diff) | |
parent | ff0c7f22cfab033022d4090c7cb324d4b4ace619 (diff) | |
download | mariadb-git-553f2a59f37e0e12f245134f95ea5d93a342b77e.tar.gz |
Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-4.1
into rurik.mysql.com:/home/igor/mysql-4.1
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7abdde25911..a70fa1c8d5e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3508,7 +3508,23 @@ inline void add_cond_and_fix(Item **e1, Item *e2) (where othertbl is a non-const table and othertbl.field may be NULL) and add them to conditions on correspoding tables (othertbl in this example). - + + Exception from that is the case when referred_tab->join != join. + I.e. don't add NOT NULL constraints from any embedded subquery. + Consider this query: + SELECT A.f2 FROM t1 LEFT JOIN t2 A ON A.f2 = f1 + WHERE A.f3=(SELECT MIN(f3) FROM t2 C WHERE A.f4 = C.f4) OR A.f3 IS NULL; + Here condition A.f3 IS NOT NULL is going to be added to the WHERE + condition of the embedding query. + Another example: + SELECT * FROM t10, t11 WHERE (t10.a < 10 OR t10.a IS NULL) + AND t11.b <=> t10.b AND (t11.a = (SELECT MAX(a) FROM t12 + WHERE t12.b = t10.a )); + Here condition t10.a IS NOT NULL is going to be added. + In both cases addition of NOT NULL condition will erroneously reject + some rows of the result set. + referred_tab->join != join constraint would disallow such additions. + This optimization doesn't affect the choices that ref, range, or join optimizer make. This was intentional because this was added after 4.1 was GA. @@ -3539,11 +3555,24 @@ static void add_not_null_conds(JOIN *join) DBUG_ASSERT(item->type() == Item::FIELD_ITEM); Item_field *not_null_item= (Item_field*)item; JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; - Item_func_isnotnull *notnull; + /* + For UPDATE queries such as: + UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1); + not_null_item is the t1.f1, but it's referred_tab is 0. + */ + if (!referred_tab || referred_tab->join != join) + continue; + Item *notnull; if (!(notnull= new Item_func_isnotnull(not_null_item))) DBUG_VOID_RETURN; - - notnull->quick_fix_field(); + /* + We need to do full fix_fields() call here in order to have correct + notnull->const_item(). This is needed e.g. by test_quick_select + when it is called from make_join_select after this function is + called. + */ + if (notnull->fix_fields(join->thd, join->tables_list, ¬null)) + DBUG_VOID_RETURN; DBUG_EXECUTE("where",print_where(notnull, referred_tab->table->table_name);); add_cond_and_fix(&referred_tab->select_cond, notnull); |