aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/nodes/equalfuncs.c81
-rw-r--r--src/backend/optimizer/util/clauses.c42
-rw-r--r--src/backend/optimizer/util/plancat.c6
-rw-r--r--src/backend/utils/cache/relcache.c12
-rw-r--r--src/include/nodes/primnodes.h6
-rw-r--r--src/include/optimizer/clauses.h2
6 files changed, 17 insertions, 132 deletions
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 226b99a1d27..95a95f477be 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -83,6 +83,10 @@
#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
@@ -235,16 +239,7 @@ _equalFuncExpr(const FuncExpr *a, const FuncExpr *b)
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);
@@ -448,16 +443,7 @@ _equalRelabelType(const RelabelType *a, const RelabelType *b)
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;
@@ -469,16 +455,7 @@ _equalCoerceViaIO(const CoerceViaIO *a, const CoerceViaIO *b)
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;
@@ -493,16 +470,7 @@ _equalArrayCoerceExpr(const ArrayCoerceExpr *a, const ArrayCoerceExpr *b)
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;
@@ -513,16 +481,7 @@ _equalConvertRowtypeExpr(const ConvertRowtypeExpr *a, const ConvertRowtypeExpr *
{
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;
@@ -589,16 +548,7 @@ _equalRowExpr(const RowExpr *a, const RowExpr *b)
{
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);
@@ -684,16 +634,7 @@ _equalCoerceToDomain(const CoerceToDomain *a, const CoerceToDomain *b)
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;
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index fa6817c9148..5894dd39c17 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -98,7 +98,6 @@ static bool contain_leaky_functions_walker(Node *node, void *context);
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,
@@ -2115,47 +2114,6 @@ strip_implicit_coercions(Node *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
* guard against improper simplification after ALTER COLUMN TYPE. (XXX we
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 25f8785b639..abcd0ee574c 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -665,12 +665,6 @@ get_relation_constraints(PlannerInfo *root,
cexpr = (Node *) canonicalize_qual((Expr *) cexpr);
- /*
- * Also mark any coercion format fields as "don't care", so that
- * we can match to both explicit and implicit coercions.
- */
- set_coercionform_dontcare(cexpr);
-
/* Fix Vars to have the desired varno */
if (varno != 1)
ChangeVarNodes(cexpr, 1, varno, 0);
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0cdd30d15b1..8c9ebe0f6f8 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -3549,12 +3549,6 @@ RelationGetIndexExpressions(Relation relation)
*/
result = (List *) eval_const_expressions(NULL, (Node *) result);
- /*
- * Also mark any coercion format fields as "don't care", so that the
- * planner can match to both explicit and implicit coercions.
- */
- set_coercionform_dontcare((Node *) result);
-
/* May as well fix opfuncids too */
fix_opfuncids((Node *) result);
@@ -3621,12 +3615,6 @@ RelationGetIndexPredicate(Relation relation)
result = (List *) canonicalize_qual((Expr *) result);
- /*
- * Also mark any coercion format fields as "don't care", so that the
- * planner can match to both explicit and implicit coercions.
- */
- set_coercionform_dontcare((Node *) result);
-
/* Also convert to implicit-AND format */
result = make_ands_implicit((Expr *) result);
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index cd4561dcf49..daabcb6cf9a 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -317,6 +317,12 @@ typedef enum CoercionContext
/*
* CoercionForm - information showing how to display a function-call node
+ *
+ * NB: equal() ignores CoercionForm fields, therefore this *must* not carry
+ * any semantically significant information. We need that behavior so that
+ * the planner will consider equivalent implicit and explicit casts to be
+ * equivalent. In cases where those actually behave differently, the coercion
+ * function's arguments will be different.
*/
typedef enum CoercionForm
{
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index ac75bd4d6ea..acff7ba1b79 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -79,8 +79,6 @@ extern void CommuteRowCompareExpr(RowCompareExpr *clause);
extern Node *strip_implicit_coercions(Node *node);
-extern void set_coercionform_dontcare(Node *node);
-
extern Node *eval_const_expressions(PlannerInfo *root, Node *node);
extern Node *estimate_expression_value(PlannerInfo *root, Node *node);