Search code examples
sqlpostgresqldynamic-programmingdynamic-sqlrange-types

Compute an aggregated tsrange from a set of entries?


I am trying to compute a aggregated tsrange from a set of row that I extract from an SQL query. Problem is that I keep getting errors that the input parameter is not being passed in.

CREATE OR REPLACE AGGREGATE range_merge(anyrange)
(
    sfunc = range_merge,
    stype = anyrange
);

DROP FUNCTION IF EXISTS aggregate_validity(entity_name regclass, entry bigint);

CREATE OR REPLACE FUNCTION aggregate_validity(entity_name regclass, entry bigint) returns tsrange AS
$$
DECLARE
    result tsrange;
BEGIN
   EXECUTE format('select range_merge(valid) from %s where entity_id = %U', entity_name, entry) into result;
   return result;
END
$$ LANGUAGE plpgsql;

When I do:

select * from aggregate_validity(country, 1);

I get an error stating that the entity name and entry do not exist. It does not seem to parameterize the input into the statement properly.


Solution

  • Function:

    EXECUTE format('select range_merge(valid) from %s where entity_id=%U',entity_name, entry) 
    into result;
    =>
    EXECUTE format('select range_merge(valid) from %I where entity_id=%s',entity_name, entry) 
    into result;
    --%I for identifier, %s for value
    

    Call:

    select * from aggregate_validity(country, 1)
    =>
    select * from aggregate_validity('country', 1);
    

    db<>fiddle demo