Recently friend of mine sent me a funny picture:

IsEven on Java
IsEven on Java

Cool, ha?!

Challenge accepted
Challenge accepted

Then I thought about plpgsql and created IsEven function:

CREATE OR REPLACE FUNCTION IsEven(n integer) 
RETURNS boolean AS $$
DECLARE 
    maxint CONSTANT integer := 2147483647;
BEGIN
    IF n = maxint THEN
	RETURN false;
    END IF;	
    RETURN IsEven(n + 2);
EXCEPTION
    WHEN numeric_value_out_of_range THEN
        RETURN true;
END;
$$
LANGUAGE plpgsql;

This was my first working plpgsql function ever! OK, let’s try it:

vseprovse=# \timing
Timing is on.
vseprovse=# SELECT IsEven(2147483647);
 iseven
--------
 f
(1 row)

Time: 3,430 ms
vseprovse=# SELECT IsEven(2147483600);
 iseven
--------
 t
(1 row)

Time: 21,731 ms
vseprovse=# SELECT IsEven(2147483000);
 iseven
--------
 t
(1 row)

Time: 55,960 ms
vseprovse=# SELECT IsEven(2147480000);
ERROR:  stack depth limit exceeded
HINT:  Increase the configuration parameter 
"max_stack_depth" (currently 2048kB), after 
ensuring the platform's stack depth limit 
is adequate.
CONTEXT:  SQL statement "SELECT IsEven(n + 2)"
PL/pgSQL function iseven(integer) line 8 at RETURN
SQL statement "SELECT IsEven(n + 2)"
PL/pgSQL function iseven(integer) line 8 at RETURN
...(and a hundred lines of the same error string)

Oops! Not funny. Of course, I may increase “max_stack_depth”, but… I decided to rewrite function from scratch!

CREATE OR REPLACE FUNCTION IsEvenER(n integer) 
RETURNS boolean AS $$
DECLARE 
    maxint CONSTANT integer := 2147483647;
BEGIN
    LOOP
	IF n = maxint THEN
	    RETURN false;
	END IF;	
	n := n + 2;
    END LOOP;
EXCEPTION
    WHEN numeric_value_out_of_range THEN
        RETURN true;
END;
$$
LANGUAGE plpgsql;

Let’s try:

vseprovse=# SELECT IsEvenER(2147483647);
 isevener
----------
 f
(1 row)

Time: 2,250 ms
vseprovse=# SELECT IsEvenER(2147480000);
 isevener
----------
 t
(1 row)

Time: 5,753 ms
vseprovse=# SELECT IsEvenER(2100000000);
 isevener
----------
 t
(1 row)

Time: 59088,985 ms
vseprovse=# SELECT IsEvenER(0);
^CCancel request sent
ERROR:  canceling statement due to user request
CONTEXT:  PL/pgSQL function isevener(integer) line 6 at IF
Time: 1173804,198 ms

I waited for 20 minutes… almost. But then I killed it. What are your timings? 😉