Last active
December 31, 2015 21:39
-
-
Save decibel/f232d9788b531f4ee3f8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CREATE OR REPLACE FUNCTION lambda( | |
code text | |
, VARIADIC inputs anyarray | |
) RETURNS anyelement LANGUAGE plpgsql AS $body$ | |
DECLARE | |
c_prefix CONSTANT text := 'lambda_function_'; | |
c_pattern CONSTANT text := '^' || c_prefix || '([0-9]+)$'; | |
fname text; | |
foid regprocedure; | |
fargs regtype[]; | |
call_args text[]; | |
i int; | |
sql text; | |
out text; | |
BEGIN | |
RAISE DEBUG 'c_prefix = %, c_pattern = %', c_prefix, c_pattern; | |
-- Get highest defined number. Need to do this in case stuff is nested | |
SELECT INTO i | |
coalesce( | |
max( substring(proname from c_pattern)::int ) + 1 | |
,0 | |
) | |
FROM pg_proc | |
WHERE pronamespace=pg_my_temp_schema() | |
AND proname ~ c_pattern | |
; | |
fname := 'pg_temp.' || quote_ident( c_prefix || i ); | |
sql := format( | |
'CREATE FUNCTION %s%s;' | |
, fname | |
, code | |
); | |
RAISE DEBUG 'sql = %', sql; | |
EXECUTE sql; | |
-- This will return an error if the function is overloaded, which is what we want | |
foid := fname::regproc::oid; | |
SELECT INTO fargs | |
proargtypes::regtype[] | |
FROM pg_proc | |
WHERE oid = foid | |
; | |
-- TODO: Verify # of fargs matches # of inputs | |
-- Build call arguments by iterating through fargs and casting our inputs appropriately. | |
call_args := array( | |
SELECT format( '%L::%s', input, argtype ) | |
FROM unnest( inputs, fargs ) u( input, argtype ) | |
); | |
sql := format( | |
E'SELECT %s(\n%s\n)' | |
, foid::oid::regproc | |
, array_to_string( call_args, E'\n , ' ) | |
); | |
RAISE DEBUG 'sql = %', sql; | |
EXECUTE sql INTO out USING inputs; | |
sql := 'DROP FUNCTION ' || foid::text; | |
RAISE DEBUG 'sql = %', sql; | |
EXECUTE sql; | |
RETURN out; | |
END | |
$body$; | |
--SELECT pg_sleep(5); | |
SELECT lambda( $L1$(float,float) RETURNS float LANGUAGE sql AS $$SELECT $1 + $2$$$L1$, 1.0, 2.1); | |
-- vi: expandtab ts=2 sw=2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment