Your function exhibits multiple problems. And the description has contradictions.
This might do what you are looking for:
CREATE OR REPLACE FUNCTION f_values_inc(_init_val int)
RETURNS integer
LANGUAGE sql AS
$INVAL$
INSERT INTO values (val_num)
SELECT COALESCE(MAX(val_num), _init_val, 0) + 1
FROM values
RETURNING val_num;
$INVAL$;
Call:
SELECT f_values_inc(7);
But that's just a proof of concept. I don't see the use case. The function cannot cope with concurrent writes on the table, as has been commented.
Consider a serial
or IDENTITY
column instead, both of which are designed not to break under concurrent write load. See:
Aside: Avoid using SQL keywords like values
as identifier. While this one is basically allowed in Postgres, it's reserved in standard SQL. Use legal, lower-case, unquoted identifiers exclusively to make your life in Postgres easier. See: