In the case that I have the same example data as in this question and additionally declare the following two functions:
CREATE OR REPLACE FUNCTION example.markout_666_example_666_price_table_666_price(_symbol text, _time_of timestamptz, _start interval, _duration interval)
RETURNS float8
LANGUAGE sql STABLE STRICT PARALLEL SAFE AS -- !
$func$
SELECT p.price
FROM example.price_table p
WHERE p.symbol = _symbol
AND p.time_of >= _time_of + _start
AND p.time_of <= _time_of + _start + _duration
ORDER BY p.time_of
LIMIT 1;
$func$;
CREATE OR REPLACE FUNCTION example.markout_666_example_666_price_table_666_volume(_symbol text, _time_of timestamptz, _start interval, _duration interval)
RETURNS float8
LANGUAGE sql STABLE STRICT PARALLEL SAFE AS -- !
$func$
SELECT p.volume
FROM example.price_table p
WHERE p.symbol = _symbol
AND p.time_of >= _time_of + _start
AND p.time_of <= _time_of + _start + _duration
ORDER BY p.time_of
LIMIT 1;
$func$;
These two functions are similar but reference different columns. In a more general case they might also reference different tables. I state two different functions however as inputting a column name (or a different table name) to a function seems to be regarded as an anti-pattern in writing postgres functions.
I can use both of these functions in a query like:
SELECT symbol, time_of, example.markout_666_example_666_price_table_666_price(symbol, time_of, '3 hours', '24 hours') as markout_price,
example.markout_666_example_666_price_table_666_price(symbol, time_of, '25 hours', '24 hours') as markout_price_2,
example.markout_666_example_666_price_table_666_volume(symbol, time_of, '3 hours', '24 hours') as markout_volume
from example.interesting_times it;
This is quite verbose however and we need to write symbol and time_of several times. If we have functions declared for more tables and more functions of these tables the queries can get quite complex.
Is it possible to instead write something like:
SELECT symbol, time_of, example.markout('example.price_table', 'price', '3 hours', '24 hours') as markout_price,
example.markout('example.price_table', 'price', '25 hours', '24 hours') as markout_price_2,
example.markout('example.price_table', 'volume', '3 hours', '24 hours') as markout_volume
from example.interesting_times it;
where example.markout
is a macro/metaprogramming type construct and have this function be evaluated the same as if we used the more vebose syntax? Is there any metaprogramming-like technique that can be used here?
All I can find searching is sql_macro in oracle database and this page on “macro commands” in an out of date version of postgres which is no longer in the postgres manual.