

CREATE FUNCTION plpgsql_call_handler () RETURNS OPAQUE AS
    '/usr/lib/pgsql/plpgsql.so' LANGUAGE 'C';

CREATE TRUSTED PROCEDURAL LANGUAGE 'plpgsql'
    HANDLER plpgsql_call_handler
    LANCOMPILER 'PL/pgSQL';


-- first the 'worker' function

DROP  FUNCTION intarray_compare(INT[],INT[]);

CREATE FUNCTION intarray_compare(INT[],INT[]) RETURNS INT AS '
DECLARE 
    I INTEGER := 1;
BEGIN
    LOOP
        IF ($1[I] > $2[I]) THEN
            RETURN 1;
        ELSE
            IF ($1[I] < $2[I]) THEN
                RETURN -1;
            END IF;
        END IF;
        IF ($1[I] IS NULL) THEN
            IF ($2[I] IS NULL) THEN RETURN 0; END IF;
            RETURN -1; 
        END IF;
        IF ($2[I] IS NULL) THEN RETURN 1; END IF;
        I := I + 1;
        EXIT WHEN I > 1000;
    END LOOP;
END;
' LANGUAGE 'plpgsql';


DROP FUNCTION intarray_gt(INT[],INT[]);
create FUNCTION intarray_gt(INT[],INT[]) RETURNS BOOLEAN AS '
BEGIN
    RETURN intarray_compare($1,$2) = 1;
END;
' LANGUAGE 'plpgsql';

DROP FUNCTION intarray_gte(INT[],INT[]);
create FUNCTION intarray_gte(INT[],INT[]) RETURNS BOOLEAN AS '
BEGIN
    RETURN intarray_compare($1,$2) >= 0;
END;
' LANGUAGE 'plpgsql';

DROP FUNCTION intarray_lt(INT[],INT[]);
create FUNCTION intarray_lt(INT[],INT[]) RETURNS BOOLEAN AS '
BEGIN
    RETURN intarray_compare($1,$2) = -1;
END;
' LANGUAGE 'plpgsql';

DROP FUNCTION intarray_lte(INT[],INT[]);
create FUNCTION intarray_lte(INT[],INT[]) RETURNS BOOLEAN AS '
BEGIN
    RETURN intarray_compare($1,$2) <= 0;
END;
' LANGUAGE 'plpgsql';

DROP FUNCTION intarray_eq(INT[],INT[]);
create FUNCTION intarray_eq(INT[],INT[]) RETURNS BOOLEAN AS '
BEGIN
    RETURN intarray_compare($1,$2) = 0;
END;
' LANGUAGE 'plpgsql';

DROP FUNCTION intarray_neq(INT[],INT[]);
create FUNCTION intarray_neq(INT[],INT[]) RETURNS BOOLEAN AS '
BEGIN
    RETURN intarray_compare($1,$2) != 0;
END;
' LANGUAGE 'plpgsql';


-- now greate the operators

CREATE OPERATOR < (
    leftarg = INT[],
    rightarg = INT[],
    procedure = intarray_lt,
    commutator = > ,
    negator = >=
);
   
CREATE OPERATOR <= (
    leftarg = INT[],
    rightarg = INT[],
    procedure = intarray_lte,
    commutator = >= ,
    negator = >
);

CREATE OPERATOR > (
    leftarg = INT[],
    rightarg = INT[],
    procedure = intarray_gt,
    commutator = < ,
    negator = <=
);

CREATE OPERATOR >= (
    leftarg = INT[],
    rightarg = INT[],
    procedure = intarray_gte,
    commutator = <= ,
    negator = <
);

CREATE OPERATOR = (
    leftarg = INT[],
    rightarg = INT[],
    procedure = intarray_eq,
    commutator = = ,
    negator = !=
);

CREATE OPERATOR != (
    leftarg = INT[],
    rightarg = INT[],
    procedure = intarray_neq,
    commutator = != ,
    negator = =
);











