You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MDEV-37933: Rewrite [NATURAL] FULL OUTER to LEFT, RIGHT, or INNER JOIN
Rewrite FULL OUTER JOIN queries as either LEFT, RIGHT, or INNER JOIN
by checking if and how the WHERE clause rejects nulls.
For example, the following two queries are equivalent because the
WHERE condition rejects nulls from the left table and allows matches
in the right table (or NULL from the right table) for the remaining
rows:
SELECT * FROM t1 FULL JOIN t2 ON t1.v = t2.v WHERE t1.v IS NOT NULL;
SELECT * FROM t1 LEFT JOIN t2 ON t1.v = t2.v;
Copy file name to clipboardExpand all lines: mysql-test/main/join.test
+103-6Lines changed: 103 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -2073,34 +2073,34 @@ explain extended select * from t1 natural full outer join t2;
2073
2073
select * from t1 natural full join t2;
2074
2074
explain extended select * from t1 natural full join t2;
2075
2075
2076
-
create view v1 as select * from t1 full join t2 on t1.a = t2.a;
2076
+
create view v1 as select t1.a as t1a, t2.a as t2a from t1 full join t2 on t1.a = t2.a;
2077
2077
--error ER_NOT_SUPPORTED_YET
2078
2078
select * from v1;
2079
2079
explain extended select * from v1;
2080
2080
drop view v1;
2081
2081
2082
-
create view v1 as select * from t1 full outer join t2 on t1.a = t2.a;
2082
+
create view v1 as select t1.a as t1a, t2.a as t2a from t1 full outer join t2 on t1.a = t2.a;
2083
2083
--error ER_NOT_SUPPORTED_YET
2084
2084
select * from v1;
2085
2085
explain extended select * from v1;
2086
2086
drop view v1;
2087
2087
2088
-
create view v1 as select * from t1 natural full join t2;
2088
+
create view v1 as select t1.a as t1a, t2.a as t2a from t1 natural full join t2;
2089
2089
--error ER_NOT_SUPPORTED_YET
2090
2090
select * from v1;
2091
2091
explain extended select * from v1;
2092
2092
drop view v1;
2093
2093
2094
-
create view v1 as select * from t1 natural full outer join t2;
2094
+
create view v1 as select t1.a as t1a, t2.a as t2a from t1 natural full outer join t2;
2095
2095
--error ER_NOT_SUPPORTED_YET
2096
2096
select * from v1;
2097
2097
explain extended select * from v1;
2098
2098
drop view v1;
2099
2099
2100
-
--error ER_BAD_FIELD_ERROR
2100
+
--error ER_NOT_SUPPORTED_YET
2101
2101
select * from (select t1.a from t1 full join t2 on t1.a = t2.a union select * from t1) dt;
2102
2102
2103
-
--error ER_BAD_FIELD_ERROR
2103
+
--error ER_NOT_SUPPORTED_YET
2104
2104
select * from (select t1.a from t1 full outer join t2 on t1.a = t2.a union select * from t1) dt;
2105
2105
2106
2106
--error ER_NOT_SUPPORTED_YET
@@ -2127,7 +2127,104 @@ select * from t1, t2 natural full join t3;
2127
2127
--error ER_NO_SUCH_TABLE
2128
2128
select * from t1, t2 natural full outer join t3;
2129
2129
2130
+
--error ER_FULL_JOIN_BASE_TABLES_ONLY
2131
+
select * from (select * from t1) dt natural full join (select * from t2) du;
2132
+
2133
+
--error ER_FULL_JOIN_BASE_TABLES_ONLY
2134
+
select * from (select * from t1) dt natural full join t2;
2135
+
2136
+
--error ER_FULL_JOIN_BASE_TABLES_ONLY
2137
+
select * from t1 natural full join (select * from t2) du;
2138
+
2130
2139
drop table t1, t2;
2140
+
2141
+
--echo # Exercise FULL JOIN rewrites to LEFT, RIGHT, and INNER JOIN.
2142
+
create table x (pk int auto_increment, x int, y int, primary key (pk));
2143
+
create table xsq (pk int auto_increment, x int, y int, primary key (pk));
2144
+
insert into x (x, y) values (-5,-5),(-4,-4),(-3,-3),(-2,-2),(-1,-1),(0,0),(1,1),(2,2),(3,3),(4,4),(5,5);
2145
+
insert into xsq (x, y) values (-5,25),(-4,16),(-3,9),(-2,4),(-1,1),(0,0),(1,1),(2,4),(3,9),(4,16),(5,25);
2146
+
2147
+
--echo # FULL to RIGHT JOIN, these two queries should be equal:
2148
+
select * from x full join xsq on x.y = xsq.y where xsq.pk is not null;
2149
+
select * from x right join xsq on x.y = xsq.y;
2150
+
2151
+
--echo # FULL to RIGHT JOIN, these two queries should be equal:
2152
+
select * from x full join xsq on x.x >= 0 and x.x <= 1 and xsq.x >= 0 and xsq.x <= 1 where xsq.pk is not null;
2153
+
select * from x right join xsq on x.x >= 0 and x.x <= 1 and xsq.x >= 0 and xsq.x <= 1;
2154
+
2155
+
--echo # FULL to INNER JOIN, these two queries should be equal:
2156
+
select * from x full join xsq on x.x >= 0 and x.x <= 1 and xsq.x >= 0 and xsq.x <= 1 where x.pk is not null and xsq.pk is not null;
2157
+
select * from x inner join xsq on x.x >= 0 and x.x <= 1 and xsq.x >= 0 and xsq.x <= 1;
2158
+
2159
+
--echo # FULL to LEFT JOIN, these two queries should be equal:
2160
+
select * from x full join xsq on x.x >= 0 and x.x <= 1 and xsq.x >= 0 and xsq.x <= 1 where x.pk is not null;
2161
+
select * from x left join xsq on x.x >= 0 and x.x <= 1 and xsq.x >= 0 and xsq.x <= 1;
2162
+
2163
+
--echo # FULL NATURAL to INNER JOIN, these two queries should be equal:
2164
+
select * from x natural full join xsq where x.pk is not null and xsq.pk is not null;
2165
+
select * from x inner join xsq on x.x = xsq.x and x.y = xsq.y;
2166
+
2167
+
--echo # FULL NATURAL to LEFT JOIN, these two queries should be equal:
2168
+
select * from x natural full join xsq where x.pk is not null;
2169
+
select * from x left join xsq on xsq.pk = x.pk and xsq.x = x.x and xsq.y = x.y;
2170
+
2171
+
--echo # FULL NATURAL to RIGHT JOIN
2172
+
select * from x natural full join xsq where xsq.pk is not null;
2173
+
select * from x right join xsq on x.pk = xsq.pk and x.x = xsq.x and x.y = xsq.y;
2174
+
2175
+
--echo # These two will fail because it cannot be rewritten to a LEFT, RIGHT, nor INNER JOIN.
2176
+
--error ER_NOT_SUPPORTED_YET
2177
+
select * from x full join xsq on x.x >= 0 and x.x <= 1 and xsq.x >= 0 and xsq.x <= 1;
2178
+
--error ER_NOT_SUPPORTED_YET
2179
+
select * from x natural full join xsq;
2180
+
2181
+
drop table x, xsq;
2182
+
2183
+
--echo # Nested JOINs
2184
+
create table one (v int);
2185
+
insert into one (v) values (1);
2186
+
create table two (v int);
2187
+
insert into two (v) values (2);
2188
+
create table three (v int);
2189
+
insert into three (v) values (3);
2190
+
2191
+
--echo # (FULL)FULL to (INNER)INNER JOIN
2192
+
select * from one full join two on one.v = two.v full join three on two.v = three.v where one.v is not null and two.v is not null and three.v is not null;
2193
+
select * from one inner join two on one.v = two.v inner join three on two.v = three.v;
2194
+
2195
+
--echo # (FULL)FULL to (RIGHT)LEFT JOIN
2196
+
select * from one full join two on one.v = two.v full join three on one.v = three.v where two.v is not null;
2197
+
select * from one right join two on one.v = two.v left join three on one.v = three.v;
2198
+
2199
+
--echo # (FULL)FULL to (LEFT)LEFT JOIN
2200
+
select * from one full join two on one.v = two.v full join three on one.v = three.v where one.v is not null;
2201
+
select * from one left join two on two.v = one.v left join three on three.v = one.v;
2202
+
2203
+
--echo # (FULL)LEFT to (LEFT)LEFT JOIN
2204
+
select * from one full join two on one.v = two.v left join three on two.v = three.v where one.v is not null;
2205
+
select * from one left join two on one.v = two.v left join three on two.v = three.v;
2206
+
2207
+
--echo # (FULL)LEFT to (RIGHT)LEFT JOIN
2208
+
select * from one full join two on one.v = two.v left join three on two.v = three.v where two.v is not null;
2209
+
select * from one right join two on one.v = two.v left join three on three.v = two.v;
2210
+
2211
+
--echo # (LEFT)FULL to (LEFT)RIGHT JOIN
2212
+
select * from one left join two on one.v = two.v full join three on two.v = three.v where three.v is not null;
2213
+
select * from one left join two on one.v = two.v right join three on two.v = three.v;
2214
+
2215
+
--echo # (LEFT)FULL to (LEFT)LEFT JOIN
2216
+
insert into one (v) values (2),(3);
2217
+
insert into two (v) values (1);
2218
+
truncate three;
2219
+
insert into three (v) values (1);
2220
+
select * from one;
2221
+
select * from two;
2222
+
select * from three;
2223
+
select * from one left join two on one.v = two.v full join three on two.v = three.v where three.v = 1;
2224
+
select * from three left join one on one.v = 1 left join two on two.v = 1;
2225
+
2226
+
drop table one, two, three;
2227
+
2131
2228
# TODO fix PS protocol before end of FULL OUTER JOIN development
0 commit comments