-- -- pl-sql.sql -- -- created by philg on 11/18/98 -- -- useful pl/sql utility procedures -- -- MSB for some reason the top if isn't working -- doesn't look like it is needed by this -- function, so i commented it out create function logical_negation(varchar) returns varchar as ' declare true_or_false alias for $1; BEGIN -- IF true_or_false is null THEN -- return null; IF true_or_false = ''f'' THEN return ''t''; ELSE return ''f''; END IF; END; ' language 'plpgsql'; -- these come originally from the classified ads system -- DRB: Ben's attempt didn't work, but this does. Weird. create function expired_p(datetime) returns boolean as ' declare expiration_date alias for $1; begin return expiration_date <= current_timestamp; end; ' language 'plpgsql'; -- DRB: These exploit the fact that subtracting dates returns -- the number of days separating them as an integer. Subtracting -- datetimes returns a reltime of the form "'n days'", not what -- the calling scripts expect. create function days_since_posted(date) returns integer as ' declare posted alias for $1; begin return current_timestamp::date - posted; end; ' language 'plpgsql'; -- useful for ecommerce and other situations where you want to -- know whether something happened within last N days (assumes query_date -- is in the past) create function one_if_within_n_days (datetime, integer) returns integer as ' declare query_date alias for $1; n_days alias for $2; begin IF current_timestamp::date - query_date::date <= n_days THEN return 1; ELSE return 0; END IF; end; ' language 'plpgsql'; --drop function pseudo_contains( varchar, varchar) ; create function pseudo_contains (varchar, varchar) returns integer as ' declare indexed_stuff alias for $1; space_sep_list_untrimmed alias for $2; space_sep_list text; upper_indexed_stuff text; -- if you call this var START you get hosed royally first_space integer; score integer; BEGIN space_sep_list := upper(ltrim(rtrim(space_sep_list_untrimmed))); upper_indexed_stuff := upper(indexed_stuff); score := 0; IF space_sep_list is null or indexed_stuff is null THEN RETURN score; END IF; LOOP first_space := position('' '' in space_sep_list); IF first_space = 0 THEN -- one token or maybe end of list IF position(space_sep_list in upper_indexed_stuff) <> 0 THEN RETURN score+10; END IF; RETURN score; ELSE -- first_space <> 0 IF position(substring(space_sep_list from 1 to first_space-1) in upper_indexed_stuff) <> 0 THEN score := score + 10; END IF; END IF; space_sep_list := substring(space_sep_list from first_space+1); END LOOP; END; ' language 'plpgsql'; --drop function add_months (datetime, integer) ; create function add_months (datetime, integer) returns datetime as ' declare base alias for $1; months alias for $2; begin return base + (months || ''months'')::timespan; end; ' language 'plpgsql'; -- Returns the interval in fractional days between two dates. -- Useful especially in ecommerce where there are checks for -- 0.95 parts of a day, etc. create function date_interval(datetime, datetime) returns float as ' declare later alias for $1; earlier alias for $2; begin return (date_part(''epoch'', later)-date_part(''epoch'', earlier))/86400.0; end; ' language 'plpgsql'; -- useful for working around outer joins involving users email. -- ticket tracker needed it, decided to make it non-specific as -- other modules probably do, too. create function email_or_null(integer) returns varchar as ' begin return email from users where user_id = $1; end; ' language 'plpgsql'; create function to_date_or_null(datetime) returns date as ' begin if $1 is null then return null; end if; return $1::date; end; ' language 'plpgsql';