]> granicus.if.org Git - postgresql/commitdiff
Change postgres_fdw to show casts as casts, not underlying function calls.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 22 Feb 2013 12:30:21 +0000 (07:30 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 22 Feb 2013 12:30:21 +0000 (07:30 -0500)
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.)

contrib/postgres_fdw/deparse.c
contrib/postgres_fdw/expected/postgres_fdw.out

index 1f4b2449be7e7cf18b62f529e7c845e5e1dcef59..93f2541cfc18e38b73af5ec19fccccf08e5667c8 100644 (file)
@@ -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));
 }
 
 /*
index 9a2c8e83cc4489b9e5aee6b3182fd87834fc621d..8af496a54679e1722086753767231381961e041d 100644 (file)
@@ -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