I am trying to make a check function which checks whether a tsrange is contained within an another one. Consider the complete example in this fiddle.
The last section is doing the "magic", here is an MVP of the functions. An actual execution can be found above in the example.
-- Setting up init stuff
CREATE TABLE country(entity_id BIGSERIAL PRIMARY KEY, valid tsrange, registration tsrange);
CREATE TABLE airport(entity_id BIGSERIAL PRIMARY KEY, valid tsrange, registration tsrange,
country_key bigint references country (entity_id));
-- persisting data into tables
INSERT INTO country 
VALUES(1,'[2016-06-22 19:10:25-07, 2019-01-01 00:00:00)', tsrange(now()::timestamp, '9999-01-01 00:00:00'));
INSERT INTO airport VALUES(1,'[2018-06-22 19:10:25-07, 2020-01-01 00:00:00)', tsrange(now()::timestamp, '9999-01-01 00:00:00'), 1);
-- range_merge wrapper
CREATE OR REPLACE AGGREGATE range_merge(anyrange)
(
    sfunc = range_merge,
    stype = anyrange
);
-- Aggregate function for aggregating all validity periods from select statement. 
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 %I where entity_id = %s', entity_name, entry) into result;
   return result;
END
$$ LANGUAGE plpgsql;
- Detect integrity breach function 
CREATE OR REPLACE FUNCTION ingoing_outgoing_reference_integrity_breach(altered_table_name text, entity_ids bigint[])  
RETURNS TABLE(
       source_entity text,
       source_entry_id bigint,
       source_entry_validity tsrange,
       is_included_in_timeline boolean,
       aggregated_foreing_entry_validity tsrange,
       foreing_entry_id bigint,
       foreing_entity text,
       is_reference_ingoing boolean
      )
AS $$
DECLARE
    foreign_key  record;
    is_reference_ingoing boolean;
BEGIN
    FOR foreign_key  IN (
        --  Using the information schema from postgres, all constraints of type 
        --  FOREIGN_KEY, is extracted. For each of the foreing key constraint, the 
        --  source_table and foreing_table which is linked by this constraint is then extracted.  
        --  to ensure both ingoing references and outgoing references are extracted from this query, is
        --  condition provided as such that either the source_table = altered_table_name OR foreing_table_name = altered_table_name||'_registration'
        SELECT
            tc.table_name AS source_table, 
            kcu.column_name as column_attribute,
            ccu.table_name AS foreign_table
        FROM 
            information_schema.table_constraints AS tc 
            JOIN information_schema.key_column_usage AS kcu
            ON tc.constraint_name = kcu.constraint_name
            JOIN information_schema.constraint_column_usage AS ccu
            ON ccu.constraint_name = tc.constraint_name
        WHERE 
            constraint_type = 'FOREIGN KEY' and 
            (ccu.table_name = altered_table_name OR tc.table_name = altered_table_name) and
            ccu.column_name != 'row_id' and 
            kcu.column_name != 'entity_id') 
    LOOP
        DROP TABLE IF EXISTS lookup_breach;
        EXECUTE format('CREATE TEMP TABLE lookup_breach ON COMMIT DROP AS
                       SELECT '||foreign_key.source_table||'.entity_id AS source_entry_id, -- The Id of the source entry
                    '||foreign_key.source_table||'.'||foreign_key.column_attribute||' AS foreing_entry_id, -- The id of the foreing entry
                    '||foreign_key.source_table||'.valid AS source_entry_valid, -- the validity period of the source entry
                    aggregate_validity('||foreign_key.foreign_table||', '||foreign_key.source_table||'.'||foreign_key.column_attribute||') AS foreing_entry_valid, -- the validity period of the foreing entry
                    aggregate_validity('||foreign_key.foreign_table||', '||foreign_key.source_table||'.'||foreign_key.column_attribute||') <@ '||foreign_key.source_table||'.valid as in_lifespan
                    FROM '||foreign_key.foreign_table||', '||foreign_key.source_table||'
                    WHERE '||foreign_key.source_table||'.'||foreign_key.column_attribute||' = ANY($1)
                    AND '||foreign_key.source_table||'.'||foreign_key.column_attribute||' = '||foreign_key.foreign_table||'_registration.entity_id
                    AND '||foreign_key.source_table||'.registration @> now()::timestamp
                    GROUP BY '||foreign_key.source_table||'.'||foreign_key.column_attribute||', 
                    '||foreign_key.source_table||'.entity_id,'||foreign_key.source_table||'.valid,
                    '||foreign_key.foreign_table||'.valid' ) using entity_ids;
        RETURN QUERY SELECT foreign_key.source_table::text, lookup_breach.source_entry_id, lookup_breach.source_entry_valid, lookup_breach.in_lifespan , lookup_breach.foreing_entry_valid,
        lookup_breach.foreing_entry_id, foreign_key.foreign_table::text, foreign_key.foreign_table::text= altered_table_name AS is_reference_ingoing
        FROM lookup_breach;
    END LOOP;
END
$$ LANGUAGE plpgsql;
I get this error when I call the function:
select * from ingoing_outgoing_reference_integrity_breach('country'::text, '{1}')
ERROR:  function aggregate_validity(country, bigint) does not exist
LINE 5:      aggregate_validity(country, airport.country_key) AS for...
             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
QUERY:  CREATE TEMP TABLE lookup_breach ON COMMIT DROP AS
                       SELECT airport.entity_id AS source_entry_id, -- The Id of the source entry
                    airport.country_key AS foreing_entry_id, -- The id of the foreing entry
                    airport.valid AS source_entry_valid, -- the validity period of the source entry
                    aggregate_validity(country, airport.country_key) AS foreing_entry_valid, -- the validity period of the foreing entry
                    aggregate_validity(country, airport.country_key) <@ airport.valid as in_lifespan
                    FROM country, airport
                    WHERE airport.country_key = ANY($1)
                    AND airport.country_key = country_registration.entity_id
                    AND airport.registration @> now()::timestamp
                    GROUP BY airport.country_key, 
                    airport.entity_id,airport.valid,
                    country.valid
CONTEXT:  PL/pgSQL function ingoing_outgoing_reference_integrity_breach(text,bigint[]) line 33 at EXECUTE
Seems like I need some sort of casting? But I can't figure out how to do it.
 
     
    