Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions mysql-test/main/join.result
Original file line number Diff line number Diff line change
Expand Up @@ -3667,17 +3667,117 @@ create table t2 (a int);
insert into t2 (a) values (1),(2),(3);
select * from t1 full join t2 on t1.a = t2.a;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from t1 full join t2 on t1.a = t2.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 UNKNOWN NULL NULL NULL NULL 0 0.00
1 SIMPLE t2 UNKNOWN NULL NULL NULL NULL 0 0.00
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` full join `test`.`t2` on(multiple equal(`test`.`t1`.`a`, `test`.`t2`.`a`))
select * from t1 full outer join t2 on t1.a = t2.a;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from t1 full outer join t2 on t1.a = t2.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 UNKNOWN NULL NULL NULL NULL 0 0.00
1 SIMPLE t2 UNKNOWN NULL NULL NULL NULL 0 0.00
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` full join `test`.`t2` on(multiple equal(`test`.`t1`.`a`, `test`.`t2`.`a`))
select * from t1 natural full outer join t2;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from t1 natural full outer join t2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 UNKNOWN NULL NULL NULL NULL 0 0.00
1 SIMPLE t2 UNKNOWN NULL NULL NULL NULL 0 0.00
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` natural full join `test`.`t2`
select * from t1 natural full join t2;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from t1 natural full join t2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 UNKNOWN NULL NULL NULL NULL 0 0.00
1 SIMPLE t2 UNKNOWN NULL NULL NULL NULL 0 0.00
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` natural full join `test`.`t2`
create view v1 as select * from t1 full join t2 on t1.a = t2.a;
select * from v1;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from v1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 UNKNOWN NULL NULL NULL NULL 0 0.00
1 SIMPLE t2 UNKNOWN NULL NULL NULL NULL 0 0.00
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` full join `test`.`t2` on(multiple equal(`test`.`t1`.`a`, `test`.`t2`.`a`))
drop view v1;
create view v1 as select * from t1 full outer join t2 on t1.a = t2.a;
select * from v1;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from v1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 UNKNOWN NULL NULL NULL NULL 0 0.00
1 SIMPLE t2 UNKNOWN NULL NULL NULL NULL 0 0.00
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` full join `test`.`t2` on(multiple equal(`test`.`t1`.`a`, `test`.`t2`.`a`))
drop view v1;
create view v1 as select * from t1 natural full join t2;
select * from v1;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from v1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 UNKNOWN NULL NULL NULL NULL 0 0.00
1 SIMPLE t2 UNKNOWN NULL NULL NULL NULL 0 0.00
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` natural full join `test`.`t2`
drop view v1;
create view v1 as select * from t1 natural full outer join t2;
select * from v1;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from v1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 UNKNOWN NULL NULL NULL NULL 0 0.00
1 SIMPLE t2 UNKNOWN NULL NULL NULL NULL 0 0.00
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` natural full join `test`.`t2`
drop view v1;
select * from (select t1.a from t1 full join t2 on t1.a = t2.a union select * from t1) dt;
ERROR 42S22: Unknown column 't1.a' in 'SELECT'
select * from (select t1.a from t1 full outer join t2 on t1.a = t2.a union select * from t1) dt;
ERROR 42S22: Unknown column 't1.a' in 'SELECT'
select * from (select t1.a from t1 natural full join t2 union select * from t1) dt;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from (select t1.a from t1 natural full join t2 union select * from t1) dt;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> UNKNOWN NULL NULL NULL NULL 0 0.00
2 DERIVED t1 UNKNOWN NULL NULL NULL NULL 0 0.00
2 DERIVED t2 UNKNOWN NULL NULL NULL NULL 0 0.00
3 UNION t1 UNKNOWN NULL NULL NULL NULL 0 0.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `dt`.`a` AS `a` from (/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` natural full join `test`.`t2` union /* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1`) `dt`
select * from (select t1.a from t1 natural full outer join t2 union select * from t1) dt;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended select * from (select t1.a from t1 natural full outer join t2 union select * from t1) dt;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> UNKNOWN NULL NULL NULL NULL 0 0.00
2 DERIVED t1 UNKNOWN NULL NULL NULL NULL 0 0.00
2 DERIVED t2 UNKNOWN NULL NULL NULL NULL 0 0.00
3 UNION t1 UNKNOWN NULL NULL NULL NULL 0 0.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `dt`.`a` AS `a` from (/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` natural full join `test`.`t2` union /* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1`) `dt`
with cte as (select t1.a from t1 natural full join t2) select * from cte;
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
explain extended with cte as (select t1.a from t1 natural full join t2) select * from cte;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 UNKNOWN NULL NULL NULL NULL 0 0.00
1 SIMPLE t2 UNKNOWN NULL NULL NULL NULL 0 0.00
Warnings:
Note 1003 with cte as (select `test`.`t1`.`a` AS `a` from `test`.`t1` natural full join `test`.`t2`)select `test`.`t1`.`a` AS `a` from `test`.`t1` natural full join `test`.`t2`
select * from t1, t2 full join t3 on t2.c=t3.e and t3.f=t1.a;
ERROR 42S02: Table 'test.t3' doesn't exist
select * from t1, t2 full outer join t3 on t2.c=t3.e and t3.f=t1.a;
ERROR 42S02: Table 'test.t3' doesn't exist
select * from t1, t2 natural full join t3;
ERROR 42S02: Table 'test.t3' doesn't exist
select * from t1, t2 natural full outer join t3;
ERROR 42S02: Table 'test.t3' doesn't exist
drop table t1, t2;
# End of 12.3 tests
62 changes: 60 additions & 2 deletions mysql-test/main/join.test
Original file line number Diff line number Diff line change
Expand Up @@ -2055,21 +2055,79 @@ create table t1 (a int);
insert into t1 (a) values (1),(2),(3);
create table t2 (a int);
insert into t2 (a) values (1),(2),(3);
# This test only verifies syntax acceptance.
# TODO fix PS protocol before end of FULL OUTER JOIN development
--disable_ps_protocol
--error ER_NOT_SUPPORTED_YET
select * from t1 full join t2 on t1.a = t2.a;
explain extended select * from t1 full join t2 on t1.a = t2.a;

--error ER_NOT_SUPPORTED_YET
select * from t1 full outer join t2 on t1.a = t2.a;
explain extended select * from t1 full outer join t2 on t1.a = t2.a;

--error ER_NOT_SUPPORTED_YET
select * from t1 natural full outer join t2;
explain extended select * from t1 natural full outer join t2;

--error ER_NOT_SUPPORTED_YET
select * from t1 natural full join t2;
explain extended select * from t1 natural full join t2;

create view v1 as select * from t1 full join t2 on t1.a = t2.a;
--error ER_NOT_SUPPORTED_YET
select * from v1;
explain extended select * from v1;
drop view v1;

create view v1 as select * from t1 full outer join t2 on t1.a = t2.a;
--error ER_NOT_SUPPORTED_YET
select * from v1;
explain extended select * from v1;
drop view v1;

create view v1 as select * from t1 natural full join t2;
--error ER_NOT_SUPPORTED_YET
select * from v1;
explain extended select * from v1;
drop view v1;

create view v1 as select * from t1 natural full outer join t2;
--error ER_NOT_SUPPORTED_YET
select * from v1;
explain extended select * from v1;
drop view v1;

--error ER_BAD_FIELD_ERROR
select * from (select t1.a from t1 full join t2 on t1.a = t2.a union select * from t1) dt;

--error ER_BAD_FIELD_ERROR
select * from (select t1.a from t1 full outer join t2 on t1.a = t2.a union select * from t1) dt;

--error ER_NOT_SUPPORTED_YET
select * from (select t1.a from t1 natural full join t2 union select * from t1) dt;
explain extended select * from (select t1.a from t1 natural full join t2 union select * from t1) dt;

--error ER_NOT_SUPPORTED_YET
select * from (select t1.a from t1 natural full outer join t2 union select * from t1) dt;
explain extended select * from (select t1.a from t1 natural full outer join t2 union select * from t1) dt;

--error ER_NOT_SUPPORTED_YET
with cte as (select t1.a from t1 natural full join t2) select * from cte;
drop table t1, t2;
explain extended with cte as (select t1.a from t1 natural full join t2) select * from cte;

--error ER_NO_SUCH_TABLE
select * from t1, t2 full join t3 on t2.c=t3.e and t3.f=t1.a;

--error ER_NO_SUCH_TABLE
select * from t1, t2 full outer join t3 on t2.c=t3.e and t3.f=t1.a;

--error ER_NO_SUCH_TABLE
select * from t1, t2 natural full join t3;

--error ER_NO_SUCH_TABLE
select * from t1, t2 natural full outer join t3;

drop table t1, t2;
# TODO fix PS protocol before end of FULL OUTER JOIN development
--enable_ps_protocol
--echo # End of 12.3 tests
5 changes: 0 additions & 5 deletions sql/sql_parse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10305,11 +10305,6 @@ bool parse_sql(THD *thd, Parser_state *parser_state,
bool mysql_parse_status= thd->variables.sql_mode & MODE_ORACLE
? ORAparse(thd) : MYSQLparse(thd);

/* While we accept full join syntax, such joins are not yet supported. */
mysql_parse_status|= thd->lex->has_full_outer_join;
if (thd->lex->has_full_outer_join)
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "full join");

if (mysql_parse_status)
/*
Restore the original LEX if it was replaced when parsing
Expand Down
39 changes: 34 additions & 5 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,18 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
goto err;
prepared= true;

/*
This check gates FULL JOIN functionality while it is under
development. This check will be removed once FULL JOIN
has been completed and it allows some aspects of FULL JOIN
(see below) while exluding others, driven by whatever has
been implemented up to this point.
*/
if (thd->lex->has_full_outer_join && // FULL JOIN not yet supported...
!thd->lex->is_view_context_analysis() && // ...but allow VIEW creation...
!thd->lex->describe) // ...and limited EXPLAIN support during development
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "full join");

DBUG_RETURN(0); // All OK

err:
Expand Down Expand Up @@ -2767,7 +2779,13 @@ JOIN::optimize_inner()
with_two_phase_optimization= check_two_phase_optimization(thd);
if (with_two_phase_optimization)
optimization_state= JOIN::OPTIMIZATION_PHASE_1_DONE;
else
/*
Only during the FULL JOIN development cycle, disable second stage
optimization for FULL JOIN queries until the implementation is
mature enough to correctly execute the queries. But for now
this allows for some EXPLAIN EXTENDED support.
*/
else if (!thd->lex->has_full_outer_join)
{
if (optimize_stage2())
DBUG_RETURN(1);
Expand Down Expand Up @@ -31710,8 +31728,13 @@ static void print_table_array(THD *thd,
continue;
}

/* JOIN_TYPE_OUTER is just a marker unrelated to real join */
if (curr->outer_join & (JOIN_TYPE_LEFT|JOIN_TYPE_RIGHT))
if (curr->outer_join & JOIN_TYPE_FULL)
{
if (curr->outer_join & JOIN_TYPE_NATURAL)
str->append(STRING_WITH_LEN(" natural"));
str->append(STRING_WITH_LEN(" full join "));
}
else if (curr->outer_join & (JOIN_TYPE_LEFT|JOIN_TYPE_RIGHT))
{
/* MySQL converts right to left joins */
str->append(STRING_WITH_LEN(" left join "));
Expand All @@ -31722,9 +31745,15 @@ static void print_table_array(THD *thd,
str->append(STRING_WITH_LEN(" semi join "));
else
str->append(STRING_WITH_LEN(" join "));

curr->print(thd, eliminated_tables, str, query_type);
if (curr->on_expr)
/*
NATURAL JOINs don't expose explicit join columns, so don't
print them as they're considered invalid syntax (this is
important for VIEWs as when VIEWs are loaded, their SQL
syntax is parsed again and must be valid).
*/
if (curr->on_expr && !(curr->outer_join & JOIN_TYPE_NATURAL))
{
str->append(STRING_WITH_LEN(" on("));
curr->on_expr->print(str, query_type);
Expand Down
1 change: 1 addition & 0 deletions sql/sql_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *view_table_alias,
DBUG_ASSERT(view_query_lex == thd->lex);
thd->lex= parent_query_lex; // Needed for prepare_security
result= !view_table_alias->prelocking_placeholder && view_table_alias->prepare_security(thd);
parent_query_lex->has_full_outer_join|= view_query_lex->has_full_outer_join;

lex_end(view_query_lex);
end:
Expand Down
9 changes: 6 additions & 3 deletions sql/sql_yacc.yy
Original file line number Diff line number Diff line change
Expand Up @@ -12387,8 +12387,9 @@ join_table:
}
expr
{
add_join_on(thd, $1, $8);
add_join_on(thd, $5, $8);
$1->on_context= Lex->pop_context();
$5->on_context= $1->on_context;
Select->parsing_place= NO_MATTER;
$$= $1;
Lex->has_full_outer_join= true;
Expand All @@ -12415,11 +12416,13 @@ join_table:

Select->add_joined_table($1);
$1->outer_join|= (JOIN_TYPE_LEFT |
JOIN_TYPE_FULL);
JOIN_TYPE_FULL |
JOIN_TYPE_NATURAL);

Select->add_joined_table($6);
$6->outer_join|= (JOIN_TYPE_RIGHT |
JOIN_TYPE_FULL);
JOIN_TYPE_FULL |
JOIN_TYPE_NATURAL);

add_join_natural($6,$1,NULL,Select);
Lex->has_full_outer_join= true;
Expand Down
9 changes: 5 additions & 4 deletions sql/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -2212,10 +2212,11 @@ class IS_table_read_plan;
#define VIEW_ALGORITHM_MERGE_FRM 1U
#define VIEW_ALGORITHM_TMPTABLE_FRM 2U

#define JOIN_TYPE_LEFT 1U
#define JOIN_TYPE_RIGHT 2U
#define JOIN_TYPE_FULL 4U
#define JOIN_TYPE_OUTER 8U /* Marker that this is an outer join */
#define JOIN_TYPE_LEFT 1U
#define JOIN_TYPE_RIGHT 2U
#define JOIN_TYPE_FULL 4U
#define JOIN_TYPE_OUTER 8U /* Marker that this is an outer join */
#define JOIN_TYPE_NATURAL 16U

/* view WITH CHECK OPTION parameter options */
#define VIEW_CHECK_NONE 0
Expand Down
Loading