aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/clauses.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/clauses.c')
-rw-r--r--src/backend/optimizer/util/clauses.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index fa0952618b1..8503792df44 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1308,6 +1308,12 @@ find_nonnullable_rels_walker(Node *node, bool top_level)
result = find_nonnullable_rels_walker((Node *) expr->arg, top_level);
}
+ else if (IsA(node, CollateExpr))
+ {
+ CollateExpr *expr = (CollateExpr *) node;
+
+ result = find_nonnullable_rels_walker((Node *) expr->arg, top_level);
+ }
else if (IsA(node, NullTest))
{
/* IS NOT NULL can be considered strict, but only at top level */
@@ -1510,6 +1516,12 @@ find_nonnullable_vars_walker(Node *node, bool top_level)
result = find_nonnullable_vars_walker((Node *) expr->arg, top_level);
}
+ else if (IsA(node, CollateExpr))
+ {
+ CollateExpr *expr = (CollateExpr *) node;
+
+ result = find_nonnullable_vars_walker((Node *) expr->arg, top_level);
+ }
else if (IsA(node, NullTest))
{
/* IS NOT NULL can be considered strict, but only at top level */
@@ -2580,6 +2592,42 @@ eval_const_expressions_mutator(Node *node,
/* Else we must return the partially-simplified node */
return (Node *) newexpr;
}
+ if (IsA(node, CollateExpr))
+ {
+ /*
+ * If we can simplify the input to a constant, then we don't need the
+ * CollateExpr node anymore: just change the constcollid field of the
+ * Const node. Otherwise, must copy the CollateExpr node.
+ */
+ CollateExpr *collate = (CollateExpr *) node;
+ Node *arg;
+
+ arg = eval_const_expressions_mutator((Node *) collate->arg,
+ context);
+
+ /*
+ * If we find stacked CollateExprs, we can discard all but the top one.
+ */
+ while (arg && IsA(arg, CollateExpr))
+ arg = (Node *) ((CollateExpr *) arg)->arg;
+
+ if (arg && IsA(arg, Const))
+ {
+ Const *con = (Const *) arg;
+
+ con->constcollid = collate->collOid;
+ return (Node *) con;
+ }
+ else
+ {
+ CollateExpr *newcollate = makeNode(CollateExpr);
+
+ newcollate->arg = (Expr *) arg;
+ newcollate->collOid = collate->collOid;
+ newcollate->location = collate->location;
+ return (Node *) newcollate;
+ }
+ }
if (IsA(node, CaseExpr))
{
/*----------