Change postgres_fdw to show casts as casts, not underlying function calls.

On reflection this method seems to be exposing an unreasonable amount of
implementation detail.  It wouldn't matter when talking to a remote server
of the identical Postgres version, but it seems likely to make things worse
not better if the remote is a different version with different casting
infrastructure.  Instead adopt ruleutils.c's policy of regurgitating the
cast as it was originally specified; including not showing it at all, if
it was implicit to start with.  (We must do that because for some datatypes
explicit and implicit casts have different semantics.)
pull/3/head
Tom Lane 13 years ago
parent 5fd386bb31
commit 211e157a51
  1. 42
      contrib/postgres_fdw/deparse.c
  2. 24
      contrib/postgres_fdw/expected/postgres_fdw.out

@ -855,10 +855,6 @@ deparseArrayRef(StringInfo buf, ArrayRef *node, PlannerInfo *root)
/*
* Deparse given node which represents a function call into buf.
*
* Here not only explicit function calls and explicit casts but also implicit
* casts are deparsed to avoid problems caused by different cast settings
* between local and remote.
*/
static void
deparseFuncExpr(StringInfo buf, FuncExpr *node, PlannerInfo *root)
@ -870,6 +866,37 @@ deparseFuncExpr(StringInfo buf, FuncExpr *node, PlannerInfo *root)
bool first;
ListCell *arg;
/*
* If the function call came from an implicit coercion, then just show the
* first argument.
*/
if (node->funcformat == COERCE_IMPLICIT_CAST)
{
deparseExpr(buf, (Expr *) linitial(node->args), root);
return;
}
/*
* If the function call came from a cast, then show the first argument
* plus an explicit cast operation.
*/
if (node->funcformat == COERCE_EXPLICIT_CAST)
{
Oid rettype = node->funcresulttype;
int32 coercedTypmod;
/* Get the typmod if this is a length-coercion function */
(void) exprIsLengthCoercion((Node *) node, &coercedTypmod);
deparseExpr(buf, (Expr *) linitial(node->args), root);
appendStringInfo(buf, "::%s",
format_type_with_typemod(rettype, coercedTypmod));
return;
}
/*
* Normal function: display as proname(args).
*/
proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(node->funcid));
if (!HeapTupleIsValid(proctup))
elog(ERROR, "cache lookup failed for function %u", node->funcid);
@ -1062,9 +1089,10 @@ static void
deparseRelabelType(StringInfo buf, RelabelType *node, PlannerInfo *root)
{
deparseExpr(buf, node->arg, root);
appendStringInfo(buf, "::%s",
format_type_with_typemod(node->resulttype,
node->resulttypmod));
if (node->relabelformat != COERCE_IMPLICIT_CAST)
appendStringInfo(buf, "::%s",
format_type_with_typemod(node->resulttype,
node->resulttypmod));
}
/*

@ -188,11 +188,11 @@ SELECT * FROM ft1 WHERE false;
-- with WHERE clause
EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1';
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------
Foreign Scan on public.ft1 t1
Output: c1, c2, c3, c4, c5, c6, c7, c8
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c7 >= '1'::bpchar)) AND (("C 1" = 101)) AND ((c6::text = '1'::text))
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c7 >= '1'::bpchar)) AND (("C 1" = 101)) AND ((c6 = '1'::text))
(3 rows)
SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1';
@ -353,11 +353,11 @@ EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL; --
(3 rows)
EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Foreign Scan on public.ft1 t1
Output: c1, c2, c3, c4, c5, c6, c7, c8
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((round("numeric"(abs("C 1")), 0) = 1::numeric))
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((round(abs("C 1"), 0) = 1::numeric))
(3 rows)
EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- OpExpr(l)
@ -369,11 +369,11 @@ EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 = -c1; --
(3 rows)
EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE 1 = c1!; -- OpExpr(r)
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------------------------------------------
Foreign Scan on public.ft1 t1
Output: c1, c2, c3, c4, c5, c6, c7, c8
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((1::numeric = (int8("C 1") !)))
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((1::numeric = ("C 1" !)))
(3 rows)
EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr
@ -401,11 +401,11 @@ EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[
(3 rows)
EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c6 = E'foo''s\\bar'; -- check special chars
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
QUERY PLAN
-------------------------------------------------------------------------------------------------------------
Foreign Scan on public.ft1 t1
Output: c1, c2, c3, c4, c5, c6, c7, c8
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c6::text = E'foo''s\\bar'::text))
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c6 = E'foo''s\\bar'::text))
(3 rows)
EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't be sent to remote

Loading…
Cancel
Save