-/*
- * create_parameternames_array - build proargnames value from an array
- * of C strings. Returns a NULL pointer if no names provided.
- */
-static Datum
-create_parameternames_array(int parameterCount, const char *parameterNames[])
-{
- Datum elems[FUNC_MAX_ARGS];
- bool found = false;
- ArrayType *names;
- int i;
-
- if (!parameterNames)
- return PointerGetDatum(NULL);
-
- for (i = 0; i < parameterCount; i++)
- {
- const char *s = parameterNames[i];
-
- if (s && *s)
- found = true;
- else
- s = "";
-
- elems[i] = DirectFunctionCall1(textin, CStringGetDatum(s));
- }
-
- if (!found)
- return PointerGetDatum(NULL);
-
- names = construct_array(elems, parameterCount, TEXTOID, -1, false, 'i');
-
- return PointerGetDatum(names);
-}
-
-
-/*
- * check_sql_fn_retval() -- check return value of a list of sql parse trees.
- *
- * The return value of a sql function is the value returned by
- * the final query in the function. We do some ad-hoc type checking here
- * to be sure that the user is returning the type he claims.
- *
- * This is normally applied during function definition, but in the case
- * of a function with polymorphic arguments, we instead apply it during
- * function execution startup. The rettype is then the actual resolved
- * output type of the function, rather than the declared type. (Therefore,
- * we should never see ANYARRAY or ANYELEMENT as rettype.)
- *
- * The return value is true if the function returns the entire tuple result
- * of its final SELECT, and false otherwise. Note that because we allow
- * "SELECT rowtype_expression", this may be false even when the declared
- * function return type is a rowtype.
- */
-bool
-check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
-{
- Query *parse;
- int cmd;
- List *tlist;
- ListCell *tlistitem;
- int tlistlen;
- Oid typerelid;
- Oid restype;
- Relation reln;
- int relnatts; /* physical number of columns in rel */
- int rellogcols; /* # of nondeleted columns in rel */
- int colindex; /* physical column index */
-
- /* guard against empty function body; OK only if void return type */
- if (queryTreeList == NIL)
- {
- if (rettype != VOIDOID)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("return type mismatch in function declared to return %s",
- format_type_be(rettype)),
- errdetail("Function's final statement must be a SELECT.")));
- return false;
- }
-
- /* find the final query */
- parse = (Query *) lfirst(list_tail(queryTreeList));
-
- cmd = parse->commandType;
- tlist = parse->targetList;
-
- /*
- * The last query must be a SELECT if and only if return type isn't
- * VOID.
- */
- if (rettype == VOIDOID)
- {
- if (cmd == CMD_SELECT)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("return type mismatch in function declared to return %s",
- format_type_be(rettype)),
- errdetail("Function's final statement must not be a SELECT.")));
- return false;
- }
-
- /* by here, the function is declared to return some type */
- if (cmd != CMD_SELECT)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
- errmsg("return type mismatch in function declared to return %s",
- format_type_be(rettype)),
- errdetail("Function's final statement must be a SELECT.")));
-
- /*
- * Count the non-junk entries in the result targetlist.
- */
- tlistlen = ExecCleanTargetListLength(tlist);
-
- typerelid = typeidTypeRelid(rettype);