Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simplify the function parsing regex #358

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions postgresql/model_pg_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,10 @@ func (pgFunction *PGFunction) FromResourceData(d *schema.ResourceData) error {
return nil
}

func (pgFunction *PGFunction) Parse(functionDefinition string) error {
func (pgFunction *PGFunction) Parse(functionDefinition string, securityDefiner bool, strict bool, parallelSafety string, volatility string, language string) error {

pgFunctionData := findStringSubmatchMap(
`(?si)CREATE\sOR\sREPLACE\sFUNCTION\s(?P<Schema>[^.]+)\.(?P<Name>[^(]+)\((?P<Args>.*)\).*RETURNS\s(?P<Returns>[^\n]+).*LANGUAGE\s(?P<Language>[^\n\s]+)\s*(?P<Volatility>(STABLE|IMMUTABLE)?)\s*(?P<Parallel>(PARALLEL (SAFE|RESTRICTED))?)\s*(?P<Strict>(STRICT)?)\s*(?P<Security>(SECURITY DEFINER)?).*\$[a-zA-Z]*\$(?P<Body>.*)\$[a-zA-Z]*\$`,
`(?si)CREATE\sOR\sREPLACE\sFUNCTION\s(?P<Schema>[^.]+)\.(?P<Name>[^(]+)\((?P<Args>.*)\).*RETURNS\s(?P<Returns>[^\n]+).*\$[a-zA-Z]*\$(?P<Body>.*)\$[a-zA-Z]*\$`,
functionDefinition,
)

Expand All @@ -135,20 +135,23 @@ func (pgFunction *PGFunction) Parse(functionDefinition string) error {
pgFunction.Schema = pgFunctionData["Schema"]
pgFunction.Name = pgFunctionData["Name"]
pgFunction.Returns = pgFunctionData["Returns"]
pgFunction.Language = pgFunctionData["Language"]
pgFunction.Language = language
pgFunction.Body = pgFunctionData["Body"]
pgFunction.Args = args
pgFunction.SecurityDefiner = len(pgFunctionData["Security"]) > 0
pgFunction.Strict = len(pgFunctionData["Strict"]) > 0
if len(pgFunctionData["Volatility"]) == 0 {
pgFunction.Volatility = defaultFunctionVolatility
} else {
pgFunction.Volatility = pgFunctionData["Volatility"]
pgFunction.SecurityDefiner = securityDefiner
pgFunction.Strict = strict
pgFunction.Volatility = defaultFunctionVolatility
if volatility == "i" {
pgFunction.Volatility = "IMMUTABLE"
} else if volatility == "s" {
pgFunction.Volatility = "STABLE"
}
if len(pgFunctionData["Parallel"]) == 0 {
pgFunction.Parallel = defaultFunctionParallel
} else {
pgFunction.Parallel = strings.TrimPrefix(pgFunctionData["Parallel"], "PARALLEL ")

pgFunction.Parallel = defaultFunctionParallel
if parallelSafety == "r" {
pgFunction.Parallel = "RESTRICTED"
} else if parallelSafety == "s" {
pgFunction.Parallel = "SAFE"
}

return nil
Expand Down
6 changes: 3 additions & 3 deletions postgresql/model_pg_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ func TestPGFunctionParseWithArguments(t *testing.T) {
CREATE OR REPLACE FUNCTION public.pg_func_test(showtext boolean, OUT userid oid, default_null integer DEFAULT NULL::integer, simple_default integer DEFAULT 42, long_default character varying DEFAULT 'foo'::character varying)
RETURNS SETOF record
LANGUAGE c
STABLE PARALLEL SAFE STRICT SECURITY DEFINER
SECURITY DEFINER STABLE STRICT PARALLEL SAFE
AS $function$pg_func_test_body$function$
`

var pgFunction PGFunction

err := pgFunction.Parse(functionDefinition)
err := pgFunction.Parse(functionDefinition, true, true, "s", "s", "c")
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -179,7 +179,7 @@ $function$

var pgFunction PGFunction

err := pgFunction.Parse(functionDefinition)
err := pgFunction.Parse(functionDefinition, false, false, "u", "v", "plpgsql")
if err != nil {
t.Fatal(err)
}
Expand Down
26 changes: 18 additions & 8 deletions postgresql/resource_postgresql_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,20 +259,30 @@ func resourcePostgreSQLFunctionReadImpl(db *DBConnection, d *schema.ResourceData
return expandErr
}

var funcDefinition string

query := `SELECT pg_get_functiondef(p.oid::regproc) funcDefinition ` +
`FROM pg_proc p ` +
`LEFT JOIN pg_namespace n ON p.pronamespace = n.oid ` +
`WHERE p.oid = to_regprocedure($1)`
var funcDefinition, parallelSafety, volatility, language string
var securityDefiner, strict bool

query := `SELECT
pg_get_functiondef(p.oid::regproc),
p.prosecdef,
p.proisstrict,
p.proparallel,
p.provolatile,
l.lanname
FROM pg_proc p
LEFT JOIN pg_namespace n ON p.pronamespace = n.oid
LEFT JOIN pg_language l ON p.prolang = l.oid
WHERE p.oid = to_regprocedure($1)`

txn, err := startTransaction(db.client, databaseName)
if err != nil {
return err
}
defer deferredRollback(txn)

err = txn.QueryRow(query, functionSignature).Scan(&funcDefinition)
err = txn.QueryRow(query, functionSignature).Scan(
&funcDefinition, &securityDefiner, &strict, &parallelSafety, &volatility, &language,
)
switch {
case err == sql.ErrNoRows:
log.Printf("[WARN] PostgreSQL function: %s", functionId)
Expand All @@ -288,7 +298,7 @@ func resourcePostgreSQLFunctionReadImpl(db *DBConnection, d *schema.ResourceData

var pgFunction PGFunction

err = pgFunction.Parse(funcDefinition)
err = pgFunction.Parse(funcDefinition, securityDefiner, strict, parallelSafety, volatility, language)
if err != nil {
return err
}
Expand Down
Loading