summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <igor@rurik.mysql.com>2005-04-15 22:35:29 -0700
committerunknown <igor@rurik.mysql.com>2005-04-15 22:35:29 -0700
commite77860b7beb0254fc71c607fad8365002430f0d2 (patch)
treecdff756bb1448d19bdfb97a877812565effe685a
parent88538066ba1cbf80da5f88b0d4188f8b875127c9 (diff)
parentd85fdc1b84a3e2c617578baf38ffcb568cf62f27 (diff)
downloadmariadb-git-e77860b7beb0254fc71c607fad8365002430f0d2.tar.gz
Merge rurik.mysql.com:/home/igor/mysql-5.0
into rurik.mysql.com:/home/igor/dev/mysql-5.0-0 sql/item.h: Auto merged sql/sql_select.cc: Auto merged
-rw-r--r--mysql-test/r/subselect.result35
-rw-r--r--mysql-test/t/subselect.test47
-rw-r--r--sql/item.cc29
-rw-r--r--sql/item.h4
-rw-r--r--sql/item_subselect.h1
-rw-r--r--sql/sql_select.cc2
6 files changed, 99 insertions, 19 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 0e8ba49d88d..fa5f27b7eed 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -2746,3 +2746,38 @@ NULL
2.00
4.00
drop table t1;
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+c1 c2
+1 1
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+c1 c2
+1 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+c1 c2
+2 NULL
+3 NULL
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 3bb1da0eddf..fe7cd42995d 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1752,3 +1752,50 @@ insert into t1 values (1, 1), (2, 2), (2, 3), (3, 4), (3, 5), (3, 6), (NULL, NUL
select * from t1;
select min(a) from t1 group by grp;
drop table t1;
+
+#
+# Test for bug #9338: lame substitution of c1 instead of c2
+#
+
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+ WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+
+DROP TABLE t1,t2;
+
+#
+# Test for bug #9516: wrong evaluation of not_null_tables attribute in SQ
+#
+
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+ WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+
+DROP TABLE t1,t2,t3;
+
diff --git a/sql/item.cc b/sql/item.cc
index 46fbaf2ed85..73c8e80228b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2978,41 +2978,38 @@ Item *Item_field::set_no_const_sub(byte *arg)
/*
- Set a pointer to the multiple equality the field reference belongs to
+ Replace an Item_field for an equal Item_field that evaluated earlier
(if any)
SYNOPSIS
- replace_equal_field_processor()
+ replace_equal_field_()
arg - a dummy parameter, is not used here
DESCRIPTION
- The function replaces a pointer to a field in the Item_field object
- by a pointer to another field.
- The replacement field is taken from the very beginning of
- the item_equal list which the Item_field object refers to (belongs to)
- If the Item_field object does not refer any Item_equal object,
- nothing is done.
+ The function returns a pointer to an item that is taken from
+ the very beginning of the item_equal list which the Item_field
+ object refers to (belongs to).
+ If the Item_field object does not refer any Item_equal object
+ 'this' is returned
NOTES
This function is supposed to be called as a callback parameter in calls
- of the walk method.
+ of the thransformer method.
RETURN VALUES
- 0
+ pointer to a replacement Item_field if there is a better equal item;
+ this - otherwise.
*/
-bool Item_field::replace_equal_field_processor(byte *arg)
+Item *Item_field::replace_equal_field(byte *arg)
{
if (item_equal)
{
Item_field *subst= item_equal->get_first();
if (!field->eq(subst->field))
- {
- field= subst->field;
- return 0;
- }
+ return subst;
}
- return 0;
+ return this;
}
diff --git a/sql/item.h b/sql/item.h
index f7bb98bb8ad..e86c66ca6f3 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -520,7 +520,7 @@ public:
virtual bool collect_item_field_processor(byte * arg) { return 0; }
virtual Item *equal_fields_propagator(byte * arg) { return this; }
virtual Item *set_no_const_sub(byte *arg) { return this; }
- virtual bool replace_equal_field_processor(byte * arg) { return 0; }
+ virtual Item *replace_equal_field(byte * arg) { return this; }
virtual Item *this_item() { return this; } /* For SPs mostly. */
virtual Item *this_const_item() const { return const_cast<Item*>(this); } /* For SPs mostly. */
@@ -754,7 +754,7 @@ public:
Item_equal *find_item_equal(COND_EQUAL *cond_equal);
Item *equal_fields_propagator(byte *arg);
Item *set_no_const_sub(byte *arg);
- bool replace_equal_field_processor(byte *arg);
+ Item *replace_equal_field(byte *arg);
inline uint32 max_disp_length() { return field->max_length(); }
Item_field *filed_for_view_update() { return this; }
Item *safe_charset_converter(CHARSET_INFO *tocs);
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 56864109a04..1a407c695b2 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -96,6 +96,7 @@ public:
virtual bool exec();
virtual void fix_length_and_dec();
table_map used_tables() const;
+ table_map not_null_tables() const { return 0; }
bool const_item() const;
inline table_map get_used_tables_cache() { return used_tables_cache; }
inline bool get_const_item_cache() { return const_item_cache; }
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index a54294f00c0..f380876577a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7054,7 +7054,7 @@ static COND* substitute_for_best_equal_field(COND *cond,
return eliminate_item_equal(0, cond_equal, item_equal);
}
else
- cond->walk(&Item::replace_equal_field_processor, 0);
+ cond->transform(&Item::replace_equal_field, 0);
return cond;
}