#define COMPARE_LOCATION_FIELD(fldname) \
    ((void) 0)
 
+/* Compare a CoercionForm field (also a no-op, per comment in primnodes.h) */
+#define COMPARE_COERCIONFORM_FIELD(fldname) \
+   ((void) 0)
+
 
 /*
  * Stuff from primnodes.h
    COMPARE_SCALAR_FIELD(funcid);
    COMPARE_SCALAR_FIELD(funcresulttype);
    COMPARE_SCALAR_FIELD(funcretset);
-
-   /*
-    * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
-    * that are equal() to both explicit and implicit coercions.
-    */
-   if (a->funcformat != b->funcformat &&
-       a->funcformat != COERCE_DONTCARE &&
-       b->funcformat != COERCE_DONTCARE)
-       return false;
-
+   COMPARE_COERCIONFORM_FIELD(funcformat);
    COMPARE_SCALAR_FIELD(funccollid);
    COMPARE_SCALAR_FIELD(inputcollid);
    COMPARE_NODE_FIELD(args);
    COMPARE_SCALAR_FIELD(resulttype);
    COMPARE_SCALAR_FIELD(resulttypmod);
    COMPARE_SCALAR_FIELD(resultcollid);
-
-   /*
-    * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
-    * that are equal() to both explicit and implicit coercions.
-    */
-   if (a->relabelformat != b->relabelformat &&
-       a->relabelformat != COERCE_DONTCARE &&
-       b->relabelformat != COERCE_DONTCARE)
-       return false;
-
+   COMPARE_COERCIONFORM_FIELD(relabelformat);
    COMPARE_LOCATION_FIELD(location);
 
    return true;
    COMPARE_NODE_FIELD(arg);
    COMPARE_SCALAR_FIELD(resulttype);
    COMPARE_SCALAR_FIELD(resultcollid);
-
-   /*
-    * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
-    * that are equal() to both explicit and implicit coercions.
-    */
-   if (a->coerceformat != b->coerceformat &&
-       a->coerceformat != COERCE_DONTCARE &&
-       b->coerceformat != COERCE_DONTCARE)
-       return false;
-
+   COMPARE_COERCIONFORM_FIELD(coerceformat);
    COMPARE_LOCATION_FIELD(location);
 
    return true;
    COMPARE_SCALAR_FIELD(resulttypmod);
    COMPARE_SCALAR_FIELD(resultcollid);
    COMPARE_SCALAR_FIELD(isExplicit);
-
-   /*
-    * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
-    * that are equal() to both explicit and implicit coercions.
-    */
-   if (a->coerceformat != b->coerceformat &&
-       a->coerceformat != COERCE_DONTCARE &&
-       b->coerceformat != COERCE_DONTCARE)
-       return false;
-
+   COMPARE_COERCIONFORM_FIELD(coerceformat);
    COMPARE_LOCATION_FIELD(location);
 
    return true;
 {
    COMPARE_NODE_FIELD(arg);
    COMPARE_SCALAR_FIELD(resulttype);
-
-   /*
-    * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
-    * that are equal() to both explicit and implicit coercions.
-    */
-   if (a->convertformat != b->convertformat &&
-       a->convertformat != COERCE_DONTCARE &&
-       b->convertformat != COERCE_DONTCARE)
-       return false;
-
+   COMPARE_COERCIONFORM_FIELD(convertformat);
    COMPARE_LOCATION_FIELD(location);
 
    return true;
 {
    COMPARE_NODE_FIELD(args);
    COMPARE_SCALAR_FIELD(row_typeid);
-
-   /*
-    * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
-    * that are equal() to both explicit and implicit coercions.
-    */
-   if (a->row_format != b->row_format &&
-       a->row_format != COERCE_DONTCARE &&
-       b->row_format != COERCE_DONTCARE)
-       return false;
-
+   COMPARE_COERCIONFORM_FIELD(row_format);
    COMPARE_NODE_FIELD(colnames);
    COMPARE_LOCATION_FIELD(location);
 
    COMPARE_SCALAR_FIELD(resulttype);
    COMPARE_SCALAR_FIELD(resulttypmod);
    COMPARE_SCALAR_FIELD(resultcollid);
-
-   /*
-    * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
-    * that are equal() to both explicit and implicit coercions.
-    */
-   if (a->coercionformat != b->coercionformat &&
-       a->coercionformat != COERCE_DONTCARE &&
-       b->coercionformat != COERCE_DONTCARE)
-       return false;
-
+   COMPARE_COERCIONFORM_FIELD(coercionformat);
    COMPARE_LOCATION_FIELD(location);
 
    return true;
 
 static Relids find_nonnullable_rels_walker(Node *node, bool top_level);
 static List *find_nonnullable_vars_walker(Node *node, bool top_level);
 static bool is_strict_saop(ScalarArrayOpExpr *expr, bool falseOK);
-static bool set_coercionform_dontcare_walker(Node *node, void *context);
 static Node *eval_const_expressions_mutator(Node *node,
                               eval_const_expressions_context *context);
 static List *simplify_or_arguments(List *args,
    return node;
 }
 
-/*
- * set_coercionform_dontcare: set all CoercionForm fields to COERCE_DONTCARE
- *
- * This is used to make index expressions and index predicates more easily
- * comparable to clauses of queries.  CoercionForm is not semantically
- * significant (for cases where it does matter, the significant info is
- * coded into the coercion function arguments) so we can ignore it during
- * comparisons.  Thus, for example, an index on "foo::int4" can match an
- * implicit coercion to int4.
- *
- * Caution: the passed expression tree is modified in-place.
- */
-void
-set_coercionform_dontcare(Node *node)
-{
-   (void) set_coercionform_dontcare_walker(node, NULL);
-}
-
-static bool
-set_coercionform_dontcare_walker(Node *node, void *context)
-{
-   if (node == NULL)
-       return false;
-   if (IsA(node, FuncExpr))
-       ((FuncExpr *) node)->funcformat = COERCE_DONTCARE;
-   else if (IsA(node, RelabelType))
-       ((RelabelType *) node)->relabelformat = COERCE_DONTCARE;
-   else if (IsA(node, CoerceViaIO))
-       ((CoerceViaIO *) node)->coerceformat = COERCE_DONTCARE;
-   else if (IsA(node, ArrayCoerceExpr))
-       ((ArrayCoerceExpr *) node)->coerceformat = COERCE_DONTCARE;
-   else if (IsA(node, ConvertRowtypeExpr))
-       ((ConvertRowtypeExpr *) node)->convertformat = COERCE_DONTCARE;
-   else if (IsA(node, RowExpr))
-       ((RowExpr *) node)->row_format = COERCE_DONTCARE;
-   else if (IsA(node, CoerceToDomain))
-       ((CoerceToDomain *) node)->coercionformat = COERCE_DONTCARE;
-   return expression_tree_walker(node, set_coercionform_dontcare_walker,
-                                 context);
-}
-
 /*
  * Helper for eval_const_expressions: check that datatype of an attribute
  * is still what it was when the expression was parsed.  This is needed to