]> granicus.if.org Git - postgresql/commitdiff
Fix dumping of outer joins with empty qual lists.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 20 Jul 2017 15:29:36 +0000 (11:29 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 20 Jul 2017 15:29:36 +0000 (11:29 -0400)
Normally, a JoinExpr would have empty "quals" only if it came from CROSS
JOIN syntax.  However, it's possible to get to this state by specifying
NATURAL JOIN between two tables with no common column names, and there
might be other ways too.  The code previously printed no ON clause if
"quals" was empty; that's right for CROSS JOIN but syntactically invalid
if it's some type of outer join.  Fix by printing ON TRUE in that case.

This got broken by commit 2ffa740be, which stopped using NATURAL JOIN
syntax in ruleutils output due to its brittleness in the face of
column renamings.  Back-patch to 9.3 where that commit appeared.

Per report from Tushar Ahuja.

Discussion: https://postgr.es/m/98b283cd-6dda-5d3f-f8ac-87db8c76a3da@enterprisedb.com

src/backend/utils/adt/ruleutils.c
src/test/regress/expected/create_view.out
src/test/regress/sql/create_view.sql

index d2fb20d5649bbd7365a2dc9e26eccdf83975ad3d..23000281bbe92586c04e76d7c65273ceeafac579 100644 (file)
@@ -10082,6 +10082,11 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
                        if (!PRETTY_PAREN(context))
                                appendStringInfoChar(buf, ')');
                }
+               else if (j->jointype != JOIN_INNER)
+               {
+                       /* If we didn't say CROSS JOIN above, we must provide an ON */
+                       appendStringInfoString(buf, " ON TRUE");
+               }
 
                if (!PRETTY_PAREN(context) || j->alias != NULL)
                        appendStringInfoChar(buf, ')');
index 79f5dba55fc98109ff2ff2c9e171f8829b22acce..c2da9add97e304281f433f2134ffb34b5107bbeb 100644 (file)
@@ -1648,6 +1648,35 @@ select pg_get_viewdef('tt20v', true);
      CAST((1 + 2)::bigint AS bigint) i8(i8);
 (1 row)
 
+-- corner cases with empty join conditions
+create view tt21v as
+select * from tt5 natural inner join tt6;
+select pg_get_viewdef('tt21v', true);
+    pg_get_viewdef    
+----------------------
+  SELECT tt5.a,      +
+     tt5.b,          +
+     tt5.cc,         +
+     tt6.c,          +
+     tt6.d           +
+    FROM tt5         +
+      CROSS JOIN tt6;
+(1 row)
+
+create view tt22v as
+select * from tt5 natural left join tt6;
+select pg_get_viewdef('tt22v', true);
+       pg_get_viewdef        
+-----------------------------
+  SELECT tt5.a,             +
+     tt5.b,                 +
+     tt5.cc,                +
+     tt6.c,                 +
+     tt6.d                  +
+    FROM tt5                +
+      LEFT JOIN tt6 ON TRUE;
+(1 row)
+
 -- clean up all the random objects we made above
 set client_min_messages = warning;
 DROP SCHEMA temp_view_test CASCADE;
index 85c2959d3fd30fe239d9dacb0437f02da7fe3623..6e7463cf14ec7ddcf6cf2ed44f38d3f2b1653b98 100644 (file)
@@ -559,6 +559,16 @@ select * from
   cast(1+2 as int8) as i8;
 select pg_get_viewdef('tt20v', true);
 
+-- corner cases with empty join conditions
+
+create view tt21v as
+select * from tt5 natural inner join tt6;
+select pg_get_viewdef('tt21v', true);
+
+create view tt22v as
+select * from tt5 natural left join tt6;
+select pg_get_viewdef('tt22v', true);
+
 -- clean up all the random objects we made above
 set client_min_messages = warning;
 DROP SCHEMA temp_view_test CASCADE;