diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/parser/parse_expr.c | 126 | ||||
-rw-r--r-- | src/backend/parser/parse_jsontable.c | 2 |
2 files changed, 119 insertions, 9 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 00cd7358ebb..233b7b1cc99 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -4300,14 +4300,124 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func) } /* OMIT QUOTES is meaningless when strings are wrapped. */ - if (func->op == JSON_QUERY_OP && - func->quotes == JS_QUOTES_OMIT && - (func->wrapper == JSW_CONDITIONAL || - func->wrapper == JSW_UNCONDITIONAL)) - ereport(ERROR, - errcode(ERRCODE_SYNTAX_ERROR), - errmsg("SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is used"), - parser_errposition(pstate, func->location)); + if (func->op == JSON_QUERY_OP) + { + if (func->quotes == JS_QUOTES_OMIT && + (func->wrapper == JSW_CONDITIONAL || + func->wrapper == JSW_UNCONDITIONAL)) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("SQL/JSON QUOTES behavior must not be specified when WITH WRAPPER is used"), + parser_errposition(pstate, func->location)); + if (func->on_empty != NULL && + func->on_empty->btype != JSON_BEHAVIOR_ERROR && + func->on_empty->btype != JSON_BEHAVIOR_NULL && + func->on_empty->btype != JSON_BEHAVIOR_EMPTY && + func->on_empty->btype != JSON_BEHAVIOR_EMPTY_ARRAY && + func->on_empty->btype != JSON_BEHAVIOR_EMPTY_OBJECT && + func->on_empty->btype != JSON_BEHAVIOR_DEFAULT) + { + if (func->column_name == NULL) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON EMPTY behavior"), + errdetail("Only ERROR, NULL, EMPTY [ ARRAY ], EMPTY OBJECT, or DEFAULT expression is allowed in ON EMPTY for JSON_QUERY()."), + parser_errposition(pstate, func->on_empty->location)); + else + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON EMPTY behavior for column \"%s\"", + func->column_name), + errdetail("Only ERROR, NULL, EMPTY [ ARRAY ], EMPTY OBJECT, or DEFAULT expression is allowed in ON EMPTY for formatted columns."), + parser_errposition(pstate, func->on_empty->location)); + } + if (func->on_error != NULL && + func->on_error->btype != JSON_BEHAVIOR_ERROR && + func->on_error->btype != JSON_BEHAVIOR_NULL && + func->on_error->btype != JSON_BEHAVIOR_EMPTY && + func->on_error->btype != JSON_BEHAVIOR_EMPTY_ARRAY && + func->on_error->btype != JSON_BEHAVIOR_EMPTY_OBJECT && + func->on_error->btype != JSON_BEHAVIOR_DEFAULT) + { + if (func->column_name == NULL) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON ERROR behavior"), + errdetail("Only ERROR, NULL, EMPTY [ ARRAY ], EMPTY OBJECT, or DEFAULT expression is allowed in ON ERROR for JSON_QUERY()."), + parser_errposition(pstate, func->on_error->location)); + else + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON ERROR behavior for column \"%s\"", + func->column_name), + errdetail("Only ERROR, NULL, EMPTY [ ARRAY ], EMPTY OBJECT, or DEFAULT expression is allowed in ON ERROR for formatted columns."), + parser_errposition(pstate, func->on_error->location)); + } + } + + /* Check that ON ERROR/EMPTY behavior values are valid for the function. */ + if (func->op == JSON_EXISTS_OP && + func->on_error != NULL && + func->on_error->btype != JSON_BEHAVIOR_ERROR && + func->on_error->btype != JSON_BEHAVIOR_TRUE && + func->on_error->btype != JSON_BEHAVIOR_FALSE && + func->on_error->btype != JSON_BEHAVIOR_UNKNOWN) + { + if (func->column_name == NULL) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON ERROR behavior"), + errdetail("Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in ON ERROR for JSON_EXISTS()."), + parser_errposition(pstate, func->on_error->location)); + else + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON ERROR behavior for column \"%s\"", + func->column_name), + errdetail("Only ERROR, TRUE, FALSE, or UNKNOWN is allowed in ON ERROR for EXISTS columns."), + parser_errposition(pstate, func->on_error->location)); + } + if (func->op == JSON_VALUE_OP) + { + if (func->on_empty != NULL && + func->on_empty->btype != JSON_BEHAVIOR_ERROR && + func->on_empty->btype != JSON_BEHAVIOR_NULL && + func->on_empty->btype != JSON_BEHAVIOR_DEFAULT) + { + if (func->column_name == NULL) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON EMPTY behavior"), + errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in ON EMPTY for JSON_VALUE()."), + parser_errposition(pstate, func->on_empty->location)); + else + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON EMPTY behavior for column \"%s\"", + func->column_name), + errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in ON EMPTY for scalar columns."), + parser_errposition(pstate, func->on_empty->location)); + } + if (func->on_error != NULL && + func->on_error->btype != JSON_BEHAVIOR_ERROR && + func->on_error->btype != JSON_BEHAVIOR_NULL && + func->on_error->btype != JSON_BEHAVIOR_DEFAULT) + { + if (func->column_name == NULL) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON ERROR behavior"), + errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in ON ERROR for JSON_VALUE()."), + parser_errposition(pstate, func->on_error->location)); + else + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid ON ERROR behavior for column \"%s\"", + func->column_name), + errdetail("Only ERROR, NULL, or DEFAULT expression is allowed in ON ERROR for scalar columns."), + parser_errposition(pstate, func->on_error->location)); + } + } jsexpr = makeNode(JsonExpr); jsexpr->location = func->location; diff --git a/src/backend/parser/parse_jsontable.c b/src/backend/parser/parse_jsontable.c index b2519c2f329..8a72e498e89 100644 --- a/src/backend/parser/parse_jsontable.c +++ b/src/backend/parser/parse_jsontable.c @@ -92,7 +92,7 @@ transformJsonTable(ParseState *pstate, JsonTable *jt) ereport(ERROR, errcode(ERRCODE_SYNTAX_ERROR), errmsg("invalid ON ERROR behavior"), - errdetail("Only EMPTY or ERROR is allowed in the top-level ON ERROR clause."), + errdetail("Only EMPTY [ ARRAY ] or ERROR is allowed in the top-level ON ERROR clause."), parser_errposition(pstate, jt->on_error->location)); cxt.pathNameId = 0; |