diff --git a/contrib/b_sql_plugin/Makefile b/contrib/b_sql_plugin/Makefile index 0fe899fb310c854266accce19ef9ef2b5e8ea5b3..0237b9ea800a667bac915aa5df48d878b96007f0 100644 --- a/contrib/b_sql_plugin/Makefile +++ b/contrib/b_sql_plugin/Makefile @@ -59,7 +59,7 @@ OBJS += pg_builtin_proc.o pg_builtin_proc.o: pg_builtin_proc.cpp utils EXTENSION = b_sql_plugin DATA = b_sql_plugin--1.0.sql -REGRESS = regexp +REGRESS = regexp join_without_on REGRESS_OPTS = --dlpath=$(top_builddir)/src/test/regress -c 0 -d 1 --single_node override CPPFLAGS :=$(filter-out -fPIE, $(CPPFLAGS)) -fPIC -I$(top_builddir)/$(subdir)/include -fvisibility=hidden -I. diff --git a/contrib/b_sql_plugin/expected/join_without_on.out b/contrib/b_sql_plugin/expected/join_without_on.out new file mode 100755 index 0000000000000000000000000000000000000000..d71c3d6cf540082997bf14627a186aa23c9ffc3a --- /dev/null +++ b/contrib/b_sql_plugin/expected/join_without_on.out @@ -0,0 +1,174 @@ +drop database if exists mysql; +create database mysql dbcompatibility 'b'; +\c mysql +create extension b_sql_plugin; +CREATE TABLE J1_TBL ( + i integer, + j integer, + t text +); +CREATE TABLE J2_TBL ( + i integer, + k integer +); +CREATE TABLE J3_TBL ( + i integer, + k integer +); +CREATE TABLE J4_TBL ( + i integer, + k integer +); +INSERT INTO J1_TBL VALUES (1, 4, 'one'); +INSERT INTO J1_TBL VALUES (2, 3, 'two');; +INSERT INTO J1_TBL VALUES (0, NULL, 'zero'); +INSERT INTO J2_TBL VALUES (1, -1); +INSERT INTO J2_TBL VALUES (NULL, 0); +INSERT INTO J3_TBL VALUES (1, -1); +INSERT INTO J3_TBL VALUES (2, 2); +INSERT INTO J4_TBL VALUES (1, -1); +INSERT INTO J4_TBL VALUES (NULL, 0); +--JOIN +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL; + xxx | i | j | t | i | k +-----+---+---+------+---+---- + | 1 | 4 | one | 1 | -1 + | 2 | 3 | two | 1 | -1 + | 0 | | zero | 1 | -1 + | 1 | 4 | one | | 0 + | 2 | 3 | two | | 0 + | 0 | | zero | | 0 +(6 rows) + + xxx | i | j | t | i | k +-----+---+---+------+---+---- + | 1 | 4 | one | 1 | -1 + | 2 | 3 | two | 1 | -1 + | 0 | | zero | 1 | -1 + | 1 | 4 | one | | 0 + | 2 | 3 | two | | 0 + | 0 | | zero | | 0 +(6 rows) + +--INNER JOIN +SELECT '' AS "xxx", * + FROM J1_TBL INNER JOIN J2_TBL; +ERROR: syntax error at or near "xxx" +LINE 1: xxx | i | j | t | i | k + ^ + xxx | i | j | t | i | k +-----+---+---+------+---+---- + | 1 | 4 | one | 1 | -1 + | 2 | 3 | two | 1 | -1 + | 0 | | zero | 1 | -1 + | 1 | 4 | one | | 0 + | 2 | 3 | two | | 0 + | 0 | | zero | | 0 +(6 rows) + +-- THREE JOIN +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL JOIN J3_TBL; +ERROR: syntax error at or near "xxx" +LINE 1: xxx | i | j | t | i | k + ^ + xxx | i | j | t | i | k | i | k +-----+---+---+------+---+----+---+---- + | 1 | 4 | one | 1 | -1 | 1 | -1 + | 1 | 4 | one | 1 | -1 | 2 | 2 + | 2 | 3 | two | 1 | -1 | 1 | -1 + | 2 | 3 | two | 1 | -1 | 2 | 2 + | 0 | | zero | 1 | -1 | 1 | -1 + | 0 | | zero | 1 | -1 | 2 | 2 + | 1 | 4 | one | | 0 | 1 | -1 + | 1 | 4 | one | | 0 | 2 | 2 + | 2 | 3 | two | | 0 | 1 | -1 + | 2 | 3 | two | | 0 | 2 | 2 + | 0 | | zero | | 0 | 1 | -1 + | 0 | | zero | | 0 | 2 | 2 +(12 rows) + +--THREE INNER JOIN +SELECT '' AS "xxx", * + FROM J1_TBL INNER JOIN J2_TBL INNER JOIN J3_TBL; +ERROR: syntax error at or near "xxx" +LINE 1: xxx | i | j | t | i | k | i | k + ^ + xxx | i | j | t | i | k | i | k +-----+---+---+------+---+----+---+---- + | 1 | 4 | one | 1 | -1 | 1 | -1 + | 1 | 4 | one | 1 | -1 | 2 | 2 + | 2 | 3 | two | 1 | -1 | 1 | -1 + | 2 | 3 | two | 1 | -1 | 2 | 2 + | 0 | | zero | 1 | -1 | 1 | -1 + | 0 | | zero | 1 | -1 | 2 | 2 + | 1 | 4 | one | | 0 | 1 | -1 + | 1 | 4 | one | | 0 | 2 | 2 + | 2 | 3 | two | | 0 | 1 | -1 + | 2 | 3 | two | | 0 | 2 | 2 + | 0 | | zero | | 0 | 1 | -1 + | 0 | | zero | | 0 | 2 | 2 +(12 rows) + +--THREE JOIN WITH ONE ON +SELECT * FROM J1_TBL JOIN (J2_TBL JOIN J3_TBL) ON J1_TBL.i = J2_TBL.i; +ERROR: syntax error at or near "xxx" +LINE 1: xxx | i | j | t | i | k | i | k + ^ + i | j | t | i | k | i | k +---+---+-----+---+----+---+---- + 1 | 4 | one | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 2 | 2 +(2 rows) + +SELECT * FROM J1_TBL INNER JOIN J2_TBL JOIN J3_TBL ON J2_TBL.i = J3_TBL.i; +ERROR: syntax error at or near "i" +LINE 1: i | j | t | i | k | i | k + ^ + i | j | t | i | k | i | k +---+---+------+---+----+---+---- + 1 | 4 | one | 1 | -1 | 1 | -1 + 2 | 3 | two | 1 | -1 | 1 | -1 + 0 | | zero | 1 | -1 | 1 | -1 +(3 rows) + +SELECT * FROM J1_TBL JOIN J2_TBL JOIN J3_TBL ON J1_TBL.i = J3_TBL.i; +ERROR: syntax error at or near "i" +LINE 1: i | j | t | i | k | i | k + ^ + i | j | t | i | k | i | k +---+---+-----+---+----+---+---- + 1 | 4 | one | 1 | -1 | 1 | -1 + 1 | 4 | one | | 0 | 1 | -1 + 2 | 3 | two | 1 | -1 | 2 | 2 + 2 | 3 | two | | 0 | 2 | 2 +(4 rows) + +--FOUR JOIN WITH ON +SELECT * FROM J1_TBL JOIN J2_TBL JOIN J3_TBL JOIN J4_TBL ON J1_TBL.i = J4_TBL.i; +ERROR: syntax error at or near "i" +LINE 1: i | j | t | i | k | i | k + ^ + i | j | t | i | k | i | k | i | k +---+---+-----+---+----+---+----+---+---- + 1 | 4 | one | | 0 | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 1 | -1 | 1 | -1 + 1 | 4 | one | | 0 | 2 | 2 | 1 | -1 + 1 | 4 | one | 1 | -1 | 2 | 2 | 1 | -1 +(4 rows) + +SELECT * FROM J1_TBL JOIN J2_TBL INNER JOIN J3_TBL INNER JOIN J4_TBL ON J1_TBL.i = J4_TBL.i; +ERROR: syntax error at or near "i" +LINE 1: i | j | t | i | k | i | k | i | k + ^ + i | j | t | i | k | i | k | i | k +---+---+-----+---+----+---+----+---+---- + 1 | 4 | one | | 0 | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 1 | -1 | 1 | -1 + 1 | 4 | one | | 0 | 2 | 2 | 1 | -1 + 1 | 4 | one | 1 | -1 | 2 | 2 | 1 | -1 +(4 rows) +ERROR: syntax error at or near "i" +LINE 1: i | j | t | i | k | i | k | i | k + ^ diff --git a/contrib/b_sql_plugin/plugin_parser/gram.y b/contrib/b_sql_plugin/plugin_parser/gram.y index 7ad58522313b3314891f0ea7f9f2abcc83226919..ba975b2317862d8c3b222c9f83cf5b8c39530dfc 100644 --- a/contrib/b_sql_plugin/plugin_parser/gram.y +++ b/contrib/b_sql_plugin/plugin_parser/gram.y @@ -901,6 +901,8 @@ static int errstate; START_WITH CONNECT_BY /* Precedence: lowest to highest */ +%nonassoc lower_than_on +%left ON USING %nonassoc PARTIAL_EMPTY_PREC %nonassoc CLUSTER %nonassoc SET /* see relation_expr_opt_alias */ @@ -19979,6 +19981,26 @@ joined_table: n->quals = $4; /* ON clause */ $$ = n; } + | table_ref JOIN table_ref + %prec lower_than_on + { + JoinExpr *n = makeNode(JoinExpr); + n->jointype = JOIN_INNER; + n->isNatural = FALSE; + n->larg = $1; + n->rarg = $3; + n->usingClause = NIL; + n->quals = NULL; + if (IsA($3, JoinExpr)) + { + JoinExpr* join = (JoinExpr*)$3; + n->rarg = join->larg; + join->larg = (Node *)n; + $$ = join; + } + else + $$ = n; + } | table_ref NATURAL join_type JOIN table_ref { JoinExpr *n = makeNode(JoinExpr); @@ -20002,6 +20024,50 @@ joined_table: n->quals = NULL; /* fill later */ $$ = n; } + | table_ref INNER_P JOIN table_ref join_qual + { + JoinExpr *n = makeNode(JoinExpr); + n->jointype = JOIN_INNER; + n->isNatural = FALSE; + n->larg = $1; + n->rarg = $4; + if ($5 != NULL && IsA($5, List)) + n->usingClause = (List *) $5; /* USING clause */ + else + n->quals = $5; /* ON clause */ + $$ = n; + } + | table_ref INNER_P JOIN table_ref + %prec lower_than_on + { + JoinExpr *n = makeNode(JoinExpr); + n->jointype = JOIN_INNER; + n->isNatural = FALSE; + n->larg = $1; + n->rarg = $4; + n->usingClause = NIL; + n->quals = NULL; + if (IsA($4, JoinExpr)) + { + JoinExpr* join = (JoinExpr*)$4; + n->rarg = join->larg; + join->larg = (Node *)n; + $$ = join; + } + else + $$ = n; + } + | table_ref NATURAL INNER_P JOIN table_ref + { + JoinExpr *n = makeNode(JoinExpr); + n->jointype = JOIN_INNER; + n->isNatural = TRUE; + n->larg = $1; + n->rarg = $5; + n->usingClause = NIL; /* figure out which columns later... */ + n->quals = NULL; /* fill later */ + $$ = n; + } ; alias_clause: @@ -20036,7 +20102,6 @@ opt_alias_clause: alias_clause { $$ = $1; } join_type: FULL join_outer { $$ = JOIN_FULL; } | LEFT join_outer { $$ = JOIN_LEFT; } | RIGHT join_outer { $$ = JOIN_RIGHT; } - | INNER_P { $$ = JOIN_INNER; } ; /* OUTER is just noise... */ diff --git a/contrib/b_sql_plugin/sql/join_without_on.sql b/contrib/b_sql_plugin/sql/join_without_on.sql new file mode 100755 index 0000000000000000000000000000000000000000..1c42f9984a1bf8d2127c3416a87dcdbfd0bf0c8b --- /dev/null +++ b/contrib/b_sql_plugin/sql/join_without_on.sql @@ -0,0 +1,137 @@ +drop database if exists mysql; +create database mysql dbcompatibility 'b'; +\c mysql +create extension b_sql_plugin; +CREATE TABLE J1_TBL ( + i integer, + j integer, + t text +); +CREATE TABLE J2_TBL ( + i integer, + k integer +); +CREATE TABLE J3_TBL ( + i integer, + k integer +); +CREATE TABLE J4_TBL ( + i integer, + k integer +); +INSERT INTO J1_TBL VALUES (1, 4, 'one'); +INSERT INTO J1_TBL VALUES (2, 3, 'two');; +INSERT INTO J1_TBL VALUES (0, NULL, 'zero'); +INSERT INTO J2_TBL VALUES (1, -1); +INSERT INTO J2_TBL VALUES (NULL, 0); +INSERT INTO J3_TBL VALUES (1, -1); +INSERT INTO J3_TBL VALUES (2, 2); +INSERT INTO J4_TBL VALUES (1, -1); +INSERT INTO J4_TBL VALUES (NULL, 0); +--JOIN +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL; + xxx | i | j | t | i | k +-----+---+---+------+---+---- + | 1 | 4 | one | 1 | -1 + | 2 | 3 | two | 1 | -1 + | 0 | | zero | 1 | -1 + | 1 | 4 | one | | 0 + | 2 | 3 | two | | 0 + | 0 | | zero | | 0 +(6 rows) + +--INNER JOIN +SELECT '' AS "xxx", * + FROM J1_TBL INNER JOIN J2_TBL; + xxx | i | j | t | i | k +-----+---+---+------+---+---- + | 1 | 4 | one | 1 | -1 + | 2 | 3 | two | 1 | -1 + | 0 | | zero | 1 | -1 + | 1 | 4 | one | | 0 + | 2 | 3 | two | | 0 + | 0 | | zero | | 0 +(6 rows) + +-- THREE JOIN +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL JOIN J3_TBL; + xxx | i | j | t | i | k | i | k +-----+---+---+------+---+----+---+---- + | 1 | 4 | one | 1 | -1 | 1 | -1 + | 1 | 4 | one | 1 | -1 | 2 | 2 + | 2 | 3 | two | 1 | -1 | 1 | -1 + | 2 | 3 | two | 1 | -1 | 2 | 2 + | 0 | | zero | 1 | -1 | 1 | -1 + | 0 | | zero | 1 | -1 | 2 | 2 + | 1 | 4 | one | | 0 | 1 | -1 + | 1 | 4 | one | | 0 | 2 | 2 + | 2 | 3 | two | | 0 | 1 | -1 + | 2 | 3 | two | | 0 | 2 | 2 + | 0 | | zero | | 0 | 1 | -1 + | 0 | | zero | | 0 | 2 | 2 +(12 rows) + +--THREE INNER JOIN +SELECT '' AS "xxx", * + FROM J1_TBL INNER JOIN J2_TBL INNER JOIN J3_TBL; + xxx | i | j | t | i | k | i | k +-----+---+---+------+---+----+---+---- + | 1 | 4 | one | 1 | -1 | 1 | -1 + | 1 | 4 | one | 1 | -1 | 2 | 2 + | 2 | 3 | two | 1 | -1 | 1 | -1 + | 2 | 3 | two | 1 | -1 | 2 | 2 + | 0 | | zero | 1 | -1 | 1 | -1 + | 0 | | zero | 1 | -1 | 2 | 2 + | 1 | 4 | one | | 0 | 1 | -1 + | 1 | 4 | one | | 0 | 2 | 2 + | 2 | 3 | two | | 0 | 1 | -1 + | 2 | 3 | two | | 0 | 2 | 2 + | 0 | | zero | | 0 | 1 | -1 + | 0 | | zero | | 0 | 2 | 2 +(12 rows) + +--THREE JOIN WITH ONE ON +SELECT * FROM J1_TBL JOIN (J2_TBL JOIN J3_TBL) ON J1_TBL.i = J2_TBL.i; + i | j | t | i | k | i | k +---+---+-----+---+----+---+---- + 1 | 4 | one | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 2 | 2 +(2 rows) + +SELECT * FROM J1_TBL INNER JOIN J2_TBL JOIN J3_TBL ON J2_TBL.i = J3_TBL.i; + i | j | t | i | k | i | k +---+---+------+---+----+---+---- + 1 | 4 | one | 1 | -1 | 1 | -1 + 2 | 3 | two | 1 | -1 | 1 | -1 + 0 | | zero | 1 | -1 | 1 | -1 +(3 rows) + +SELECT * FROM J1_TBL JOIN J2_TBL JOIN J3_TBL ON J1_TBL.i = J3_TBL.i; + i | j | t | i | k | i | k +---+---+-----+---+----+---+---- + 1 | 4 | one | 1 | -1 | 1 | -1 + 1 | 4 | one | | 0 | 1 | -1 + 2 | 3 | two | 1 | -1 | 2 | 2 + 2 | 3 | two | | 0 | 2 | 2 +(4 rows) + +--FOUR JOIN WITH ON +SELECT * FROM J1_TBL JOIN J2_TBL JOIN J3_TBL JOIN J4_TBL ON J1_TBL.i = J4_TBL.i; + i | j | t | i | k | i | k | i | k +---+---+-----+---+----+---+----+---+---- + 1 | 4 | one | | 0 | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 1 | -1 | 1 | -1 + 1 | 4 | one | | 0 | 2 | 2 | 1 | -1 + 1 | 4 | one | 1 | -1 | 2 | 2 | 1 | -1 +(4 rows) + +SELECT * FROM J1_TBL JOIN J2_TBL INNER JOIN J3_TBL INNER JOIN J4_TBL ON J1_TBL.i = J4_TBL.i; + i | j | t | i | k | i | k | i | k +---+---+-----+---+----+---+----+---+---- + 1 | 4 | one | | 0 | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 1 | -1 | 1 | -1 + 1 | 4 | one | | 0 | 2 | 2 | 1 | -1 + 1 | 4 | one | 1 | -1 | 2 | 2 | 1 | -1 +(4 rows) \ No newline at end of file