fix-planner-coercion-issues-1.patch
text/x-diff
Filename: fix-planner-coercion-issues-1.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/util/clauses.c | 12 | 3 |
| src/backend/optimizer/util/predtest.c | 9 | 0 |
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 3737166..501b0e9 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1172,6 +1172,16 @@ contain_nonstrict_functions_walker(Node *node, void *context)
return true;
if (IsA(node, FieldStore))
return true;
+ if (IsA(node, CoerceViaIO))
+ {
+ /*
+ * CoerceViaIO is strict regardless of whether the I/O functions are,
+ * so just go look at its argument; asking check_functions_in_node is
+ * useless expense and could deliver the wrong answer.
+ */
+ return contain_nonstrict_functions_walker((Node *) ((CoerceViaIO *) node)->arg,
+ context);
+ }
if (IsA(node, ArrayCoerceExpr))
{
/*
@@ -1179,9 +1189,8 @@ contain_nonstrict_functions_walker(Node *node, void *context)
* the per-element expression is; so we should ignore elemexpr and
* recurse only into the arg.
*/
- return expression_tree_walker((Node *) ((ArrayCoerceExpr *) node)->arg,
- contain_nonstrict_functions_walker,
- context);
+ return contain_nonstrict_functions_walker((Node *) ((ArrayCoerceExpr *) node)->arg,
+ context);
}
if (IsA(node, CaseExpr))
return true;
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index 01f64ee..179b9aa 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -1352,6 +1352,15 @@ clause_is_strict_for(Node *clause, Node *subexpr)
return false;
}
+ /*
+ * CoerceViaIO is strict (whether or not the I/O functions it calls are).
+ * This is worth checking mainly because it saves us having to explain to
+ * users why some type coercions are known strict and others aren't.
+ */
+ if (IsA(clause, CoerceViaIO))
+ return clause_is_strict_for((Node *) ((CoerceViaIO *) clause)->arg,
+ subexpr);
+
return false;
}