Commit 9e9c38e1 authored by Robert Haas's avatar Robert Haas

postgres_fdw: Fix incorrect NULL handling in join pushdown.

something.* IS NOT NULL means that every attribute of the row is not
NULL, not that the row itself is non-NULL (e.g. because it's coming
from below an outer join.  Use (somevar.*)::pg_catalog.text IS NOT
NULL instead.

Ashutosh Bapat, per a report by Rushabh Lathia.  Reviewed by
Amit Langote and Etsuro Fujita.  Schema-qualification added by me.
parent 267569b2
...@@ -1599,9 +1599,9 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, ...@@ -1599,9 +1599,9 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root,
if (qualify_col) if (qualify_col)
{ {
appendStringInfoString(buf, "CASE WHEN "); appendStringInfoString(buf, "CASE WHEN (");
ADD_REL_QUALIFIER(buf, varno); ADD_REL_QUALIFIER(buf, varno);
appendStringInfo(buf, "* IS NOT NULL THEN %u END", fetchval); appendStringInfo(buf, "*)::pg_catalog.text IS NOT NULL THEN %u END", fetchval);
} }
else else
appendStringInfo(buf, "%u", fetchval); appendStringInfo(buf, "%u", fetchval);
...@@ -1643,9 +1643,9 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, ...@@ -1643,9 +1643,9 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root,
*/ */
if (qualify_col) if (qualify_col)
{ {
appendStringInfoString(buf, "CASE WHEN "); appendStringInfoString(buf, "CASE WHEN (");
ADD_REL_QUALIFIER(buf, varno); ADD_REL_QUALIFIER(buf, varno);
appendStringInfo(buf, "* IS NOT NULL THEN "); appendStringInfo(buf, "*)::pg_catalog.text IS NOT NULL THEN ");
} }
appendStringInfoString(buf, "ROW("); appendStringInfoString(buf, "ROW(");
......
...@@ -543,6 +543,11 @@ SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT ...@@ -543,6 +543,11 @@ SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT
CREATE USER MAPPING FOR CURRENT_USER SERVER loopback; CREATE USER MAPPING FOR CURRENT_USER SERVER loopback;
DROP USER MAPPING FOR PUBLIC SERVER loopback; DROP USER MAPPING FOR PUBLIC SERVER loopback;
-- join with nullable side with some columns with null values
UPDATE ft5 SET c3 = null where c1 % 9 = 0;
EXPLAIN VERBOSE SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1;
SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1;
-- =================================================================== -- ===================================================================
-- parameterized queries -- parameterized queries
-- =================================================================== -- ===================================================================
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment