From 4a5216b031806af46b35ab51d221c61efd396ae2 Mon Sep 17 00:00:00 2001 From: jian he Date: Wed, 24 Jun 2026 12:59:22 +0800 Subject: [PATCH v50 1/1] parse_func: minor cleanup in ParseRPRNavCall Remove the now-redundant block comment describing the decoration/modifier checks, as the function header comment already covers that context. Drop the extra parentheses around ereport() argument lists, less parentheses is always good. For the offset argument, always attempt coercion unconditionally rather than skipping it when the type is already INT8OID, letting coerce_to_target_type() handle the identity case. This also simplifies the surrounding control flow. Initialize navexpr->offset_arg to NULL eagerly and move the compound_offset_arg initialization next to the other navexpr field assignments, with a shortened comment. --- src/backend/parser/parse_func.c | 86 ++++++++++++++------------------- 1 file changed, 37 insertions(+), 49 deletions(-) diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index f3b37aa992..90930dd6d5 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -2137,44 +2137,34 @@ ParseRPRNavCall(ParseState *pstate, List *funcname, List *fargs, return NULL; } - /* - * Once the name matches we never fall back to function resolution, so any - * decoration that does not make sense for a navigation operation is a - * hard error. The aggregate/window decorations (agg_star, DISTINCT, - * WITHIN GROUP, ORDER BY, FILTER, OVER, RESPECT/IGNORE NULLS) are already - * rejected by the common path in ParseFuncOrColumn, which treated the - * recognized name as an ordinary function; what remains are the - * decorations that path accepts for a plain function but a navigation - * operation must still reject. - */ if (fn->func_variadic) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("cannot use VARIADIC with row pattern navigation function %s", - navname), - parser_errposition(pstate, location))); + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cannot use VARIADIC with row pattern navigation function %s", + navname), + parser_errposition(pstate, location)); if (argnames != NIL) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("row pattern navigation operations cannot use named arguments"), - parser_errposition(pstate, location))); + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("row pattern navigation operations cannot use named arguments"), + parser_errposition(pstate, location)); /* takes a value expression and an optional offset */ if (nargs == 0) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("too few arguments for row pattern navigation function %s", - navname), - errdetail("%s takes a value expression and an optional offset argument.", - navname), - parser_errposition(pstate, location))); + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("too few arguments for row pattern navigation function %s", + navname), + errdetail("%s takes a value expression and an optional offset argument.", + navname), + parser_errposition(pstate, location)); if (nargs > 2) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("too many arguments for row pattern navigation function %s", - navname), - errdetail("%s takes a value expression and an optional offset argument.", - navname), - parser_errposition(pstate, location))); + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("too many arguments for row pattern navigation function %s", + navname), + errdetail("%s takes a value expression and an optional offset argument.", + navname), + parser_errposition(pstate, location)); /* * Resolve a still-unknown first argument to text, the same way the @@ -2185,39 +2175,37 @@ ParseRPRNavCall(ParseState *pstate, List *funcname, List *fargs, */ arg = linitial(fargs); if (exprType(arg) == UNKNOWNOID) - arg = coerce_to_common_type(pstate, arg, TEXTOID, navname); + arg = coerce_to_target_type(pstate, arg, UNKNOWNOID, + TEXTOID, -1, COERCION_IMPLICIT, + COERCE_IMPLICIT_CAST, -1); navexpr = makeNode(RPRNavExpr); navexpr->kind = kind; navexpr->arg = (Expr *) arg; + navexpr->offset_arg = NULL; /* an explicit offset is coerced to int8, which the executor reads */ if (nargs == 2) { Node *offset = lsecond(fargs); - Oid offtype = exprType(offset); + Node *newoffset; - if (offtype != INT8OID) - { - Node *newoffset; + newoffset = coerce_to_target_type(pstate, offset, exprType(offset), + INT8OID, -1, COERCION_IMPLICIT, + COERCE_IMPLICIT_CAST, -1); + if (newoffset == NULL) + ereport(ERROR, + errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("offset argument of %s must be type %s, not type %s", + navname, "bigint", format_type_be(exprType(offset))), + parser_errposition(pstate, exprLocation(offset))); - newoffset = coerce_to_target_type(pstate, offset, offtype, - INT8OID, -1, COERCION_IMPLICIT, - COERCE_IMPLICIT_CAST, -1); - if (newoffset == NULL) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("offset argument of %s must be type %s, not type %s", - navname, "bigint", format_type_be(offtype)), - parser_errposition(pstate, exprLocation(offset)))); - offset = newoffset; - } - navexpr->offset_arg = (Expr *) offset; + navexpr->offset_arg = (Expr *) newoffset; } - else - navexpr->offset_arg = NULL; - /* compound_offset_arg stays NULL; define_walker flattening fills it in */ + /* define_walker flattening fills it in */ + navexpr->compound_offset_arg = NULL; + navexpr->resulttype = exprType(arg); /* resultcollid will be set by parse_collate.c */ navexpr->location = location; -- 2.34.1