From 86437ddf8c8da6fff49bdf08a22af3460e078eeb Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 1 Jul 2016 11:29:25 -0400 Subject: [PATCH] postgres_fdw: Fix cache lookup failure while creating error context. This is fallout from join pushdown; get_relid_attribute_name can't handle an attribute number of 0, indicating a whole-row reference, and shouldn't be called in that case. Etsuro Fujita, reviewed by Ashutosh Bapat --- contrib/postgres_fdw/expected/postgres_fdw.out | 3 +++ contrib/postgres_fdw/postgres_fdw.c | 17 ++++++++++++++--- contrib/postgres_fdw/sql/postgres_fdw.sql | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 15642e43aa..107f0b7371 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -2591,6 +2591,9 @@ CONTEXT: column "c8" of foreign table "ft1" SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR ERROR: invalid input syntax for integer: "foo" CONTEXT: column "c8" of foreign table "ft1" +SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR +ERROR: invalid input syntax for integer: "foo" +CONTEXT: whole-row reference to foreign table "ft1" ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum; -- =================================================================== -- subtransaction diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index ccfad1b82a..93ebd8cab6 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -4528,6 +4528,7 @@ conversion_error_callback(void *arg) { const char *attname = NULL; const char *relname = NULL; + bool is_wholerow = false; ConversionLocation *errpos = (ConversionLocation *) arg; if (errpos->rel) @@ -4560,12 +4561,22 @@ conversion_error_callback(void *arg) Assert(IsA(var, Var)); rte = rt_fetch(var->varno, estate->es_range_table); + + if (var->varattno == 0) + is_wholerow = true; + else + attname = get_relid_attribute_name(rte->relid, var->varattno); + relname = get_rel_name(rte->relid); - attname = get_relid_attribute_name(rte->relid, var->varattno); } - if (attname && relname) - errcontext("column \"%s\" of foreign table \"%s\"", attname, relname); + if (relname) + { + if (is_wholerow) + errcontext("whole-row reference to foreign table \"%s\"", relname); + else if (attname) + errcontext("column \"%s\" of foreign table \"%s\"", attname, relname); + } } /* diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index df4060d57d..58c55a4d89 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -627,6 +627,7 @@ DROP FUNCTION f_test(int); ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int; SELECT * FROM ft1 WHERE c1 = 1; -- ERROR SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR +SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum; -- =================================================================== -- 2.40.0