Skip to content

Functions

The Function class in Weasel.Postgresql.Functions represents a PL/pgSQL (or SQL) function as a schema object with full delta detection support.

Creating a Function

The simplest way to define a function is with Function.ForSql(), which parses the identifier from the SQL body:

cs
var function = Function.ForSql(@"
CREATE OR REPLACE FUNCTION public.calculate_tax(amount decimal, rate decimal)
RETURNS decimal
LANGUAGE sql
AS $$
SELECT amount * rate;
$$;
");

snippet source | anchor

Or construct directly with an identifier and body:

cs
var function = new Function(
    new DbObjectName("public", "calculate_tax"),
    @"CREATE OR REPLACE FUNCTION public.calculate_tax(amount decimal, rate decimal)
RETURNS decimal
LANGUAGE sql
AS $$
SELECT amount * rate;
$$;"
);

snippet source | anchor

Function Delta Detection

Weasel compares the expected function body against the actual definition stored in pg_proc to detect changes.

cs
var dataSource = new NpgsqlDataSourceBuilder("Host=localhost;Database=mydb").Build();
var function = Function.ForSql(@"
CREATE OR REPLACE FUNCTION public.calculate_tax(amount decimal, rate decimal)
RETURNS decimal
LANGUAGE sql
AS $$
SELECT amount * rate;
$$;
");

await using var conn = dataSource.CreateConnection();
await conn.OpenAsync();

// Fetch the existing function from the database
var existing = await function.FetchExistingAsync(conn);

// Compute the delta
var delta = await function.FindDeltaAsync(conn);
// delta.Difference: None, Create, or Update

snippet source | anchor

The FunctionDelta class handles body comparison and generates the appropriate CREATE or DROP statements.

Removing a Function

Mark a function for removal during migration:

cs
var removed = Function.ForRemoval("public.old_function");

snippet source | anchor

Generating DDL

cs
var function = Function.ForSql(@"
CREATE OR REPLACE FUNCTION public.calculate_tax(amount decimal, rate decimal)
RETURNS decimal
LANGUAGE sql
AS $$
SELECT amount * rate;
$$;
");

var migrator = new PostgresqlMigrator();
var writer = new StringWriter();

// CREATE FUNCTION statement
function.WriteCreateStatement(migrator, writer);

// DROP FUNCTION statement
function.WriteDropStatement(migrator, writer);

snippet source | anchor

The drop statement is generated automatically from the function signature, including parameter types for proper overload resolution.

SQL Templates

Functions support template substitution for schema, function name, and signature placeholders:

cs
var function = Function.ForSql(@"
CREATE OR REPLACE FUNCTION public.calculate_tax(amount decimal, rate decimal)
RETURNS decimal
LANGUAGE sql
AS $$
SELECT amount * rate;
$$;
");

string result = function.BuildTemplate(
    "GRANT EXECUTE ON FUNCTION {SIGNATURE} TO app_user;");

snippet source | anchor

Available placeholders: {SCHEMA}, {FUNCTION}, {SIGNATURE}.

Released under the MIT License.