Skip to content

Commit 556ba5b

Browse files
MDEV-37932: Parser support FULL OUTER JOIN syntax
Syntax support for FULL JOIN, FULL OUTER JOIN, NATURAL FULL JOIN, and NATURAL FULL OUTER JOIN in the parser. While we accept full join syntax, such joins are not yet supported. Queries specifying any of the above joins will fail with ER_NOT_SUPPORTED_YET.
1 parent 049ee29 commit 556ba5b

File tree

7 files changed

+131
-5
lines changed

7 files changed

+131
-5
lines changed

mysql-test/main/join.result

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3657,3 +3657,27 @@ DROP TABLE t1,t2,t3;
36573657
#
36583658
# End of 11.0 tests
36593659
#
3660+
#
3661+
# MDEV-37932: FULL OUTER JOIN: Make the parser support FULL OUTER JOIN
3662+
# syntax
3663+
#
3664+
create table t1 (a int);
3665+
insert into t1 (a) values (1),(2),(3);
3666+
create table t2 (a int);
3667+
insert into t2 (a) values (1),(2),(3);
3668+
select * from t1 full join t2 on t1.a = t2.a;
3669+
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
3670+
select * from t1 full outer join t2 on t1.a = t2.a;
3671+
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
3672+
select * from t1 natural full outer join t2;
3673+
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
3674+
select * from t1 natural full join t2;
3675+
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
3676+
create view v1 as select * from t1 full outer join t2 on t1.a = t2.a;
3677+
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
3678+
select * from (select t1.a from t1 full outer join t2 on t1.a = t2.a union select * from t1) dt;
3679+
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
3680+
with cte as (select t1.a from t1 natural full join t2) select * from cte;
3681+
ERROR 42000: This version of MariaDB doesn't yet support 'full join'
3682+
drop table t1, t2;
3683+
# End of 12.3 tests

mysql-test/main/join.test

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,3 +2046,30 @@ DROP TABLE t1,t2,t3;
20462046
--echo #
20472047
--echo # End of 11.0 tests
20482048
--echo #
2049+
2050+
--echo #
2051+
--echo # MDEV-37932: FULL OUTER JOIN: Make the parser support FULL OUTER JOIN
2052+
--echo # syntax
2053+
--echo #
2054+
create table t1 (a int);
2055+
insert into t1 (a) values (1),(2),(3);
2056+
create table t2 (a int);
2057+
insert into t2 (a) values (1),(2),(3);
2058+
# This test only verifies syntax acceptance.
2059+
--error ER_NOT_SUPPORTED_YET
2060+
select * from t1 full join t2 on t1.a = t2.a;
2061+
--error ER_NOT_SUPPORTED_YET
2062+
select * from t1 full outer join t2 on t1.a = t2.a;
2063+
--error ER_NOT_SUPPORTED_YET
2064+
select * from t1 natural full outer join t2;
2065+
--error ER_NOT_SUPPORTED_YET
2066+
select * from t1 natural full join t2;
2067+
--error ER_NOT_SUPPORTED_YET
2068+
create view v1 as select * from t1 full outer join t2 on t1.a = t2.a;
2069+
--error ER_NOT_SUPPORTED_YET
2070+
select * from (select t1.a from t1 full outer join t2 on t1.a = t2.a union select * from t1) dt;
2071+
--error ER_NOT_SUPPORTED_YET
2072+
with cte as (select t1.a from t1 natural full join t2) select * from cte;
2073+
drop table t1, t2;
2074+
2075+
--echo # End of 12.3 tests

sql/sql_lex.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,7 @@ void LEX::start(THD *thd_arg)
13431343

13441344
memset(&trg_chistics, 0, sizeof(trg_chistics));
13451345
selects_for_hint_resolution.empty();
1346+
has_full_outer_join= false;
13461347
DBUG_VOID_RETURN;
13471348
}
13481349

sql/sql_lex.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3593,6 +3593,9 @@ struct LEX: public Query_tables_list
35933593
vers_select_conds_t vers_conditions;
35943594
vers_select_conds_t period_conditions;
35953595

3596+
/* False by default, this will be true if the query has a full join. */
3597+
bool has_full_outer_join;
3598+
35963599
inline void free_set_stmt_mem_root()
35973600
{
35983601
DBUG_ASSERT(!is_arena_for_set_stmt());

sql/sql_parse.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10305,6 +10305,11 @@ bool parse_sql(THD *thd, Parser_state *parser_state,
1030510305
bool mysql_parse_status= thd->variables.sql_mode & MODE_ORACLE
1030610306
? ORAparse(thd) : MYSQLparse(thd);
1030710307

10308+
/* While we accept full join syntax, such joins are not yet supported. */
10309+
mysql_parse_status|= thd->lex->has_full_outer_join;
10310+
if (thd->lex->has_full_outer_join)
10311+
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "full join");
10312+
1030810313
if (mysql_parse_status)
1030910314
/*
1031010315
Restore the original LEX if it was replaced when parsing

sql/sql_yacc.yy

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,8 +1183,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
11831183
%token <kwd> ST_COLLECT_SYM
11841184
/* A dummy token to force the priority of table_ref production in a join. */
11851185
%left CONDITIONLESS_JOIN
1186-
%left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT ON_SYM USING
1187-
1186+
%left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT ON_SYM USING FULL
1187+
11881188
%left SET_VAR
11891189
%left OR_SYM OR2_SYM
11901190
%left XOR
@@ -12365,8 +12365,72 @@ join_table:
1236512365
if (unlikely(!($$= lex->current_select->convert_right_join())))
1236612366
MYSQL_YYABORT;
1236712367
}
12368-
;
1236912368

12369+
/* FULL OUTER JOIN variants */
12370+
| table_ref FULL opt_outer JOIN_SYM table_ref
12371+
ON
12372+
{
12373+
MYSQL_YYABORT_UNLESS($1 && $5);
12374+
12375+
Select->add_joined_table($1);
12376+
$1->outer_join|= (JOIN_TYPE_LEFT |
12377+
JOIN_TYPE_FULL |
12378+
JOIN_TYPE_OUTER);
12379+
12380+
Select->add_joined_table($5);
12381+
$5->outer_join|= (JOIN_TYPE_RIGHT |
12382+
JOIN_TYPE_FULL |
12383+
JOIN_TYPE_OUTER);
12384+
12385+
/* Change the current name resolution context to a local context. */
12386+
if (unlikely(push_new_name_resolution_context(thd, $1, $5)))
12387+
MYSQL_YYABORT;
12388+
Select->parsing_place= IN_ON;
12389+
}
12390+
expr
12391+
{
12392+
add_join_on(thd, $1, $8);
12393+
$1->on_context= Lex->pop_context();
12394+
Select->parsing_place= NO_MATTER;
12395+
$$= $1;
12396+
Lex->has_full_outer_join= true;
12397+
}
12398+
| table_ref FULL opt_outer JOIN_SYM table_factor
12399+
{
12400+
MYSQL_YYABORT_UNLESS($1 && $5);
12401+
Select->add_joined_table($1);
12402+
$1->outer_join|= (JOIN_TYPE_LEFT |
12403+
JOIN_TYPE_FULL |
12404+
JOIN_TYPE_OUTER);
12405+
12406+
Select->add_joined_table($5);
12407+
$5->outer_join|= (JOIN_TYPE_RIGHT |
12408+
JOIN_TYPE_FULL |
12409+
JOIN_TYPE_OUTER);
12410+
}
12411+
USING '(' using_list ')'
12412+
{
12413+
add_join_natural($1,$5,$9,Select);
12414+
Lex->has_full_outer_join= true;
12415+
}
12416+
| table_ref NATURAL FULL opt_outer JOIN_SYM table_factor
12417+
{
12418+
MYSQL_YYABORT_UNLESS($1 && $6);
12419+
12420+
Select->add_joined_table($1);
12421+
$1->outer_join|= (JOIN_TYPE_LEFT |
12422+
JOIN_TYPE_FULL |
12423+
JOIN_TYPE_OUTER);
12424+
12425+
Select->add_joined_table($6);
12426+
$6->outer_join|= (JOIN_TYPE_RIGHT |
12427+
JOIN_TYPE_FULL |
12428+
JOIN_TYPE_OUTER);
12429+
12430+
add_join_natural($6,$1,NULL,Select);
12431+
Lex->has_full_outer_join= true;
12432+
}
12433+
;
1237012434

1237112435
inner_join: /* $$ set if using STRAIGHT_JOIN, false otherwise */
1237212436
JOIN_SYM { $$ = 0; }
@@ -16691,7 +16755,6 @@ keyword_func_sp_var_and_label:
1669116755
| FILE_SYM
1669216756
| FIRST_SYM
1669316757
| FOUND_SYM
16694-
| FULL
1669516758
| GENERAL
1669616759
| GENERATED_SYM
1669716760
| GRANTS
@@ -17021,6 +17084,7 @@ reserved_keyword_udt_not_param_type:
1702117084
| FIRST_VALUE_SYM
1702217085
| FOREIGN
1702317086
| FROM
17087+
| FULL
1702417088
| FULLTEXT_SYM
1702517089
| GOTO_ORACLE_SYM
1702617090
| GRANT
@@ -17748,6 +17812,7 @@ set_expr_or_default:
1774817812
set_expr_misc:
1774917813
ON { $$= new (thd->mem_root) Item_string_sys(thd, "ON", 2); }
1775017814
| ALL { $$= new (thd->mem_root) Item_string_sys(thd, "ALL", 3); }
17815+
| FULL { $$= new (thd->mem_root) Item_string_sys(thd, "FULL", 4); }
1775117816
| BINARY { $$= new (thd->mem_root) Item_string_sys(thd, "binary", 6); }
1775217817
;
1775317818

sql/table.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2214,7 +2214,8 @@ class IS_table_read_plan;
22142214

22152215
#define JOIN_TYPE_LEFT 1U
22162216
#define JOIN_TYPE_RIGHT 2U
2217-
#define JOIN_TYPE_OUTER 4U /* Marker that this is an outer join */
2217+
#define JOIN_TYPE_FULL 4U
2218+
#define JOIN_TYPE_OUTER 8U /* Marker that this is an outer join */
22182219

22192220
/* view WITH CHECK OPTION parameter options */
22202221
#define VIEW_CHECK_NONE 0

0 commit comments

Comments
 (0)