Search Postgresql Archives

Early binding of CURRENT_SCHEMA (Was: CREATE FUNCTION ... SEARCH {, DEFAULT | SYSTEM | SESSION })

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi there!

I followed the discussion about the schema resolution, and I really think there is need for an early bound (at function definition time) version of CURRENT_SCHEMA (the first member of search_path)

Avoiding hard-coding of schema names, (and avoiding polluting the actual users schema) is hard.

My current code generates some plpgsql functions, which need some helper functions to construct fcolumn lists, query fragments, etc.

These helpers should live in the same schema, IMHO


It is not impossible: I ended up with the following kludge to refer to functions in the same schema as the calling function.

It involves an extra layer of dynamic SQL, which self-destructs after use. It is not pretty, but it works.

Example of such a nested dynamic function is attached. (the helper functions are not included, but they live in the same "compilation unit")

Cheers,

Adriaan van Kessel
	-- -------------------------------------------------
CREATE OR REPLACE FUNCTION disposable_factory ()
RETURNS text
VOLATILE
LANGUAGE plpgsql
AS
$WTF$
DECLARE
 _fmt text;
 _sql text;
BEGIN

_fmt = $FMT$
	-- "Factory function"
	-- Create a table-returning function for table "_fqn"
	-- with the same columns.
	-- But: restricted to the most recent, upto (and including)  asof_date.
	-- The function name is the table name, with '_asof' appended,
	-- and it is created in the same schema as the table.
	-- The generated function takes one argument _datum
	-- , with the same type as tbl.asof_date
	-- --------------------------------------------------------------------
CREATE OR REPLACE FUNCTION create_asof (_fqn text, asof_date text )
RETURNS text
VOLATILE
SECURITY INVOKER
LANGUAGE plpgsql
AS
$func$
DECLARE sql text;
	basepair text[];
	funcpair text[];
	fnc_name text;
	org_name text;
	allkeys text[];
	keys text[];
BEGIN

basepair := %1$s.split_name (_fqn);

funcpair[1] = basepair[1];
funcpair[2] = concat(basepair[2] , '_asof' );

org_name := %1$s.format_pair(basepair);
fnc_name := %1$s.format_pair(funcpair);

allkeys := %1$s.fetch_pk_array (basepair[1] , basepair[2] , asof_date );
keys := array_remove (allkeys, asof_date);

-- RAISE NOTICE 'Allkeys=%%' , all_keys[1];
-- RAISE NOTICE 'Keys=%%' , keys[1];

-- CREATE OR REPLACE FUNCTION %%1$s (IN _datum DATE DEFAULT now() ) -- name
sql := format ('
CREATE OR REPLACE FUNCTION %%1$s (IN _datum %%2$s DEFAULT now() ) -- fnc_name dtype
RETURNS SETOF %%3$s	-- orgtable
STABLE SECURITY INVOKER ROWS 300000
LANGUAGE sql
AS
$omg$
SELECT *		-- all columns
FROM %%3$s src 		-- org table
WHERE %%4$s		-- date treshold
AND NOT EXISTS (
	SELECT * 
	FROM %%3$s nx	-- org table
	WHERE %%5$s	-- key fields
	AND %%6$s	-- date treshold
	AND %%7$s	-- gap
	)
	;
$omg$ 
	;'
	, fnc_name 						-- 1 Function name
	, %1$s.fetch_typename(basepair[1], basepair[2], asof_date)		-- 2 typeof Date field argument
	, org_name 						-- 3 table name
	, %1$s.format_reference ('src', asof_date) || ' <= $1'	-- 4 source Date treshold
	, %1$s.format_equal_and_list ('nx', 'src', keys)		-- 5 Same Keys
	, %1$s.format_reference ('nx', asof_date) || ' <= $1'	-- 6 nx Date treshold
	, %1$s.format_reference ('nx', asof_date) || ' > ' || %1$s.format_reference( 'src', asof_date)	-- 7 Gap Date
	);

-- RAISE NOTICE 'Pair= [%%,%%]' , basepair[1], basepair[2];
-- RAISE NOTICE 'Fnc=%%' , fnc_name;
-- RAISE NOTICE 'Sql=%%' , sql;
EXECUTE sql;
-- RETURN sql ;
RETURN fnc_name ;
END;
$func$;
$FMT$ ;

-- RAISE NOTICE '_Fmt=%' , _fmt;
_sql = format (_fmt, quote_ident(current_schema) );
-- RAISE NOTICE '_Sql=%', _sql;

EXECUTE _sql;
DROP FUNCTION disposable_factory (); -- suicide
-- return _sql;
return 'create_asof';
END;
$WTF$ ;

\echo SELECT disposable_factory();
SELECT disposable_factory();
-- \df create_asof

-- EOF

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]

  Powered by Linux