aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r--src/backend/parser/parse_expr.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 34ac17868b5..1c1c86aa3e9 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -4617,6 +4617,40 @@ coerceJsonExprOutput(ParseState *pstate, JsonExpr *jsexpr)
}
/*
+ * Recursively checks if the given expression, or its sub-node in some cases,
+ * is valid for using as an ON ERROR / ON EMPTY DEFAULT expression.
+ */
+static bool
+ValidJsonBehaviorDefaultExpr(Node *expr, void *context)
+{
+ if (expr == NULL)
+ return false;
+
+ switch (nodeTag(expr))
+ {
+ /* Acceptable expression nodes */
+ case T_Const:
+ case T_FuncExpr:
+ case T_OpExpr:
+ return true;
+
+ /* Acceptable iff arg of the following nodes is one of the above */
+ case T_CoerceViaIO:
+ case T_CoerceToDomain:
+ case T_ArrayCoerceExpr:
+ case T_ConvertRowtypeExpr:
+ case T_RelabelType:
+ case T_CollateExpr:
+ return expression_tree_walker(expr, ValidJsonBehaviorDefaultExpr,
+ context);
+ default:
+ break;
+ }
+
+ return false;
+}
+
+/*
* Transform a JSON BEHAVIOR clause.
*/
static JsonBehavior *
@@ -4636,8 +4670,7 @@ transformJsonBehavior(ParseState *pstate, JsonBehavior *behavior,
if (btype == JSON_BEHAVIOR_DEFAULT)
{
expr = transformExprRecurse(pstate, behavior->expr);
- if (!IsA(expr, Const) && !IsA(expr, FuncExpr) &&
- !IsA(expr, OpExpr))
+ if (!ValidJsonBehaviorDefaultExpr(expr, NULL))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("can only specify a constant, non-aggregate function, or operator expression for DEFAULT"),