/* * Transform the subscript expressions. */ foreach(idx, indirection) { A_Indices *ai = (A_Indices *) lfirst(idx); Node *subexpr; Assert(IsA(ai, A_Indices)); if (isSlice) { if (ai->lidx) { subexpr = transformExpr(pstate, ai->lidx); /* If it's not int4 already, try to coerce */ subexpr = coerce_to_target_type(pstate, subexpr, exprType(subexpr), INT4OID, -1, COERCION_ASSIGNMENT, COERCE_IMPLICIT_CAST, -1); if (subexpr == NULL) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("array subscript must have type integer"), parser_errposition(pstate, exprLocation(ai->lidx)))); } else { /* Make a constant 1 */ subexpr = (Node *) makeConst(INT4OID, -1, InvalidOid, sizeof(int32), Int32GetDatum(1), false, true); /* pass by value */ } lowerIndexpr = lappend(lowerIndexpr, subexpr); } subexpr = transformExpr(pstate, ai->uidx); /* If it's not int4 already, try to coerce */ subexpr = coerce_to_target_type(pstate, subexpr, exprType(subexpr), INT4OID, -1, COERCION_ASSIGNMENT, COERCE_IMPLICIT_CAST, -1); if (subexpr == NULL) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("array subscript must have type integer"), parser_errposition(pstate, exprLocation(ai->uidx)))); upperIndexpr = lappend(upperIndexpr, subexpr); }
/* * init_sexpr - initialize a SetExprState node during first use */ static void init_sexpr(Oid foid, Oid input_collation, Expr *node, SetExprState *sexpr, PlanState *parent, MemoryContext sexprCxt, bool allowSRF, bool needDescForSRF) { AclResult aclresult; /* Check permission to call function */ aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid)); InvokeFunctionExecuteHook(foid); /* * Safety check on nargs. Under normal circumstances this should never * fail, as parser should check sooner. But possibly it might fail if * server has been compiled with FUNC_MAX_ARGS smaller than some functions * declared in pg_proc? */ if (list_length(sexpr->args) > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), errmsg_plural("cannot pass more than %d argument to a function", "cannot pass more than %d arguments to a function", FUNC_MAX_ARGS, FUNC_MAX_ARGS))); /* Set up the primary fmgr lookup information */ fmgr_info_cxt(foid, &(sexpr->func), sexprCxt); fmgr_info_set_expr((Node *) sexpr->expr, &(sexpr->func)); /* Initialize the function call parameter struct as well */ InitFunctionCallInfoData(sexpr->fcinfo_data, &(sexpr->func), list_length(sexpr->args), input_collation, NULL, NULL); /* If function returns set, check if that's allowed by caller */ if (sexpr->func.fn_retset && !allowSRF) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("set-valued function called in context that cannot accept a set"), parent ? executor_errposition(parent->state, exprLocation((Node *) node)) : 0)); /* Otherwise, caller should have marked the sexpr correctly */ Assert(sexpr->func.fn_retset == sexpr->funcReturnsSet); /* If function returns set, prepare expected tuple descriptor */ if (sexpr->func.fn_retset && needDescForSRF) { TypeFuncClass functypclass; Oid funcrettype; TupleDesc tupdesc; MemoryContext oldcontext; functypclass = get_expr_result_type(sexpr->func.fn_expr, &funcrettype, &tupdesc); /* Must save tupdesc in sexpr's context */ oldcontext = MemoryContextSwitchTo(sexprCxt); if (functypclass == TYPEFUNC_COMPOSITE || functypclass == TYPEFUNC_COMPOSITE_DOMAIN) { /* Composite data type, e.g. a table's row type */ Assert(tupdesc); /* Must copy it out of typcache for safety */ sexpr->funcResultDesc = CreateTupleDescCopy(tupdesc); sexpr->funcReturnsTuple = true; } else if (functypclass == TYPEFUNC_SCALAR) { /* Base data type, i.e. scalar */ tupdesc = CreateTemplateTupleDesc(1, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, NULL, funcrettype, -1, 0); sexpr->funcResultDesc = tupdesc; sexpr->funcReturnsTuple = false; } else if (functypclass == TYPEFUNC_RECORD) { /* This will work if function doesn't need an expectedDesc */ sexpr->funcResultDesc = NULL; sexpr->funcReturnsTuple = true; } else { /* Else, we will fail if function needs an expectedDesc */ sexpr->funcResultDesc = NULL; } MemoryContextSwitchTo(oldcontext); } else sexpr->funcResultDesc = NULL; /* Initialize additional state */ sexpr->funcResultStore = NULL; sexpr->funcResultSlot = NULL; sexpr->shutdown_reg = false; }
if (strcmp(na->name, (char *) lfirst(lc)) == 0) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("argument name \"%s\" used more than once", na->name), parser_errposition(pstate, na->location))); } argnames = lappend(argnames, na->name); } else { if (argnames != NIL) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("positional argument cannot follow named argument"), parser_errposition(pstate, exprLocation(arg)))); } } if (fargs) { first_arg = linitial(fargs); Assert(first_arg != NULL); } /* * Check for column projection: if function has one argument, and that * argument is of complex type, and function name is not qualified, then * the "function call" could be a projection. We also check that there * wasn't any aggregate or variadic decoration, nor an argument name. */
/* * Transform the subscript expressions. */ foreach(idx, indirection) { A_Indices *ai = castNode(A_Indices, lfirst(idx)); Node *subexpr; if (isSlice) { if (ai->lidx) { subexpr = transformExpr(pstate, ai->lidx, pstate->p_expr_kind); /* If it's not int4 already, try to coerce */ subexpr = coerce_to_target_type(pstate, subexpr, exprType(subexpr), INT4OID, -1, COERCION_ASSIGNMENT, COERCE_IMPLICIT_CAST, -1); if (subexpr == NULL) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("array subscript must have type integer"), parser_errposition(pstate, exprLocation(ai->lidx)))); } else if (!ai->is_slice) { /* Make a constant 1 */ subexpr = (Node *) makeConst(INT4OID, -1, InvalidOid, sizeof(int32), Int32GetDatum(1), false, true); /* pass by value */ } else { /* Slice with omitted lower bound, put NULL into the list */ subexpr = NULL; } lowerIndexpr = lappend(lowerIndexpr, subexpr); } else Assert(ai->lidx == NULL && !ai->is_slice); if (ai->uidx) { subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind); /* If it's not int4 already, try to coerce */ subexpr = coerce_to_target_type(pstate, subexpr, exprType(subexpr), INT4OID, -1, COERCION_ASSIGNMENT, COERCE_IMPLICIT_CAST, -1); if (subexpr == NULL) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("array subscript must have type integer"), parser_errposition(pstate, exprLocation(ai->uidx)))); } else { /* Slice with omitted upper bound, put NULL into the list */ Assert(isSlice && ai->is_slice); subexpr = NULL; } upperIndexpr = lappend(upperIndexpr, subexpr); }