Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8532677
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T09:46:11+00:00 2026-06-11T09:46:11+00:00

I am trying to replicate the IF function from MySQL into PostgreSQL. The syntax

  • 0

I am trying to replicate the IF function from MySQL into PostgreSQL.

The syntax of IF function is IF(condition, return_if_true, return_if_false)

I created following formula:

CREATE OR REPLACE FUNCTION if(boolean, anyelement, anyelement)
   RETURNS anyelement AS $$
BEGIN
    CASE WHEN ($1) THEN
    RETURN ($2);
    ELSE
    RETURN ($3);
    END CASE;
    EXCEPTION WHEN division_by_zero THEN
    RETURN ($3);
END;
$$ LANGUAGE plpgsql;

It works well with most of the things like if(2>1, 2, 1) but it raises an error for:

if( 5/0 > 0, 5, 0)

fatal error division by zero.

In my program I can’t check the denominator as the condition is provided by user.

Is there any way around? Maybe if we can replace first parameter from boolean to something else, as in that case the function will work as it will raise and return the exception.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T09:46:12+00:00Added an answer on June 11, 2026 at 9:46 am

    PostgreSQL is following the standard

    This behaviour appears to be specified by the SQL standard. This is the first time I’ve seen a case where it’s a real problem, though; you usually just use a CASE expression or a PL/PgSQL BEGIN ... EXCEPTION block to handle it.

    MySQL’s default behaviour is dangerous and wrong. It only works that way to support older code that relies on this behaviour. It has been fixed in newer versions when strict mode is active (which it absolutely always should be) but unfortunately has not yet been made the default. When using MySQL, always enable STRICT_TRANS_TABLES or STRICT_ALL_TABLES.

    ANSI-standard zero division is a pain sometimes, but it’ll also protect against mistakes causing data loss.

    SQL injection warning, consider re-design

    If you’re executing expressions from the user then you quite likely have SQL injection problems. Depending on your security requirements you might be able to live with that, but it’s pretty bad if you don’t totally trust all your users. Remember, your users could be tricked into entering the malicious code from elsewhere.

    Consider re-designing to expose an expression builder to the user and use a query builder to create the SQL from the user expressions. This would be much more complicated, but secure.

    If you can’t do that, see if you can parse the expressions the user enters into an abstract syntax, validate it before execution, and then produce new SQL expressions based on the parsed expression. That way you can at least limit what they can write, so they don’t slip any nasties into the expression. You can also rewrite the expression to add things like checks for zero division. Finding (or writing) parsers for algebraic expressions isn’t likely to be hard, but it’ll depend on what kinds of expressions you need to let users write.

    At minimum, the app needs to be using a role (“user”) that has only SELECT privileges on the tables, is not a superuser, and does not own the tables. That’ll minimise the harm any SQL injection will cause.

    CASE won’t solve this problem as written

    In any case, because you currently don’t validate and can’t inspect the expression from the user, you can’t use the SQL-standard CASE statement to solve this. For if( a/b > 0, a, b) you’d usually write something like:

    CASE
        WHEN b = 0 THEN b
        ELSE CASE 
            WHEN a/b=0 THEN a
            ELSE b
        END
    END
    

    This explicitly handles the zero denominator case, but is only possible when you can break the expression up.

    Ugly workaround #1

    An alternative solution would be to get Pg to return a placeholder instead of raising an exception for division by zero by defining a replacement division operator or function. This will only solve the divide-by-zero case, not others.

    I wanted to return 'NaN' as that’s the logical result. Unfortunately, ‘NaN’ is greater than numbers not less then, and you want a less-than or false-like result.

    regress=# SELECT NUMERIC 'NaN' > 0;
     ?column? 
    ----------
     t
    (1 row)
    

    This means we have to use the icky hack of returning NULL instead:

    CREATE OR REPLACE FUNCTION div_null_on_zero(numeric,numeric) returns numeric AS $$
    VALUES (CASE WHEN $2 = 0 THEN NULL ELSE $1/$2 END)
    $$ LANGUAGE 'SQL' IMMUTABLE;
    
    CREATE OPERATOR @/@ (
        PROCEDURE = div_null_on_zero(numeric,numeric),
        LEFTARG = numeric,
        RIGHTARG = numeric
    );
    

    with usage:

    regress=# SELECT 5 @/@ 0, 5 @/@ 0>0, CASE WHEN 5 @/@ 0 > 0 THEN 5 ELSE 0 END;
     ?column? | ?column? | case 
    ----------+----------+------
              |          |    0
    (1 row)
    

    Your app can rewrite ‘/’ in incoming expressions into @/@ or whatever operator name you choose pretty easily.

    There’s one pretty critical problem with this approach, and that’s that @/@ will have different precedence to / so expressions without explicit parentheses may not be evaluated as you expect. You might be able to get around this by creating a new schema, defining an operator named / in that schema that does your null-on-error trick, and then adding that schema to your search_path before executing user expressions. It’s probably a bad idea, though.

    Ugly workaround #2

    Since you can’t inspect the denominator, all I can think of is to wrap the whole thing in a DO block (Pg 9.0+) or PL/PgSQL function and catch any exceptions from the evaluation of the expression.

    Erwin’s answer provides a better example of this than I did, so I’ve removed this. In any case, this is an awful and dangerous thing to do, do not do it. Your app needs to be fixed.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Im trying to replicate the following sql in Nhibernate ICriteria SELECT DISTINCT AP.ID FROM
I'm trying to replicate CI's humanize() and underscore() function in Javascript. From the CI
I am trying to replicate a forum function by getting the last reply of
I'm trying to replicate a template I've used before with a member function, and
I'm trying to replicate something similar to the following map, where the polygonal area
I am trying to replicate a table produced from a sybase database, I dont
I have been trying to replicate the buffer overflow example3 from this article aleph
I'm trying to create a chaining function for working with strings that are returned
I'm trying to replicate the function seen here: http://en.wikipedia.org/wiki/Window_function#Blackman.E2.80.93Harris_window But I simply can't get
I am trying to replicate a functionality of a built-in function, as the built-in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.