Riptide
Riptide

Reputation: 516

Return boolean from Hasura PostgreSQL function

I have a subscription table and I want to add a field called is_subscription_active as a computed field on that table. I wrote a function to return a boolean from the PostgreSQL function after looking at some examples, but I can't seem to figure out the issue here.

CREATE OR REPLACE FUNCTION public.is_subscription_active(sub subscriptions)
 RETURNS BOOLEAN
 LANGUAGE sql
 STABLE
AS $function$
    IF (sub.subscription_status = 'active') THEN
        RETURN true;
    ELSE
        IF (sub.subscription_status != 'cancelled') THEN
            RETURN false;
        ELSE
            IF sub.ending_date > now() THEN
                RETURN true;
            ELSE
                RETURN false;
            END IF;
        END IF;
    END IF;
$function$

My logic here is that, I get sub (which will be a row of subscriptions table), and I just check if status is active then return true, else if it's cancelled, then check if the ending date is greater than now, and if it is return true, else false.

I get this error from Hasura.

{
    "statement": "CREATE OR REPLACE FUNCTION public.is_subscription_active(sub subscriptions)\n RETURNS BOOLEAN\n LANGUAGE sql\n STABLE\nAS $function$\n    IF (sub.subscription_status = 'active') THEN\n        RETURN true;\n    ELSE\n        IF (sub.subscription_status != 'canceled') THEN\n            RETURN false;\n        ELSE\n            IF sub.ending_date > now() THEN\n                RETURN true;\n            ELSE\n                RETURN false;\n            END IF;\n        END IF;\n    END IF;\n$function$;",
    "prepared": false,
    "error": {
        "exec_status": "FatalError",
        "hint": null,
        "message": "syntax error at or near \"IF\"",
        "status_code": "42601",
        "description": null
    },
    "arguments": []
}

I've also tried wrapping the function body in a BEGIN ... END block, but I still get the same error.

Clearly, I'm missing something fundamental here, but I can't figure out what

Upvotes: 0

Views: 406

Answers (1)

Jesse Carter
Jesse Carter

Reputation: 21147

The main issue here is that you're specifying the function language is sql instead of plpgsql. plpgsql is a procedural language specific to postgres that actually allows you to work with procedural coding patterns like conditional statements and loops. These are not supported by regular sql.

The following should work for you:

CREATE OR REPLACE FUNCTION public.is_subscription_active(sub subscriptions)
 RETURNS BOOLEAN
 LANGUAGE plpgsql
 STABLE
AS $function$
    BEGIN
        IF (sub.subscription_status = 'active') THEN
            RETURN true;
        ELSE
            IF (sub.subscription_status != 'cancelled') THEN
                RETURN false;
            ELSE
                IF sub.ending_date > now() THEN
                    RETURN true;
                ELSE
                    RETURN false;
                END IF;
            END IF;
        END IF;
    END;
$function$

Upvotes: 1

Related Questions