Reputation: 733
I have this function, which for some reason is causing an issue with thw input parameter i pass to its execute statement.
DROP FUNCTION IF EXISTS ingoing_outgoing_reference_intigrity_breach(altered_table_name text, entity_ids bigint[]);
DROP TYPE IF EXISTS detection_intgrity_result;
CREATE or REPLACE AGGREGATE range_merge(anyrange)
(
sfunc = range_merge,
stype = anyrange
);
create type detection_intgrity_result
as (source_entity_id bigint,
source_valid tsrange,
causes_intigrity_breach boolean,
depending_entity_internal_name text,
depending_entity_id bigint,
depending_valid tsrange
);
CREATE OR REPLACE FUNCTION ingoing_outgoing_reference_intigrity_breach(altered_table_name text, entity_ids bigint[])
RETURNS setof detection_intgrity_result
AS $$
DECLARE
i record;
result_row detection_intgrity_result;
BEGIN
FOR i IN (
SELECT
tc.table_name, kcu.column_name,
ccu.table_name AS foreign_table_name
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.column_name != 'id' and
kcu.column_name != 'entity_id' and
ccu.table_name = altered_table_name OR tc.table_name = altered_table_name
and ccu.table_name != tc.table_name) LOOP
EXECUTE format('SELECT '||i.table_name||'.entity_id, '||i.table_name||'.'||i.column_name||',
range_merge('||i.foreign_table_name||'_registration.valid) @> range_merge('||i.table_name||'.valid) as lifespan,
range_merge('||i.foreign_table_name||'_registration.valid) <@ range_merge('||i.table_name||'.valid) as reverse_lifespan
from '||i.foreign_table_name||'_registration, '||i.table_name||'
where '||i.table_name||'.'||i.column_name||' in $2
and '||i.table_name||'_registration.registration @> now()::timestamp
GROUP BY '||i.table_name||'.'||i.column_name||', '||i.table_name||'_registration.entity_id') using entity_ids;
END LOOP;
END
$$ LANGUAGE plpgsql;
select * from ingoing_outgoing_reference_intigrity_breach('country', '{1,12,1}')
Am i not able to pass input parameters to a execute statement?
The function look up tables which have ingoing and outgoing refereneces and ensure that data between those two is still valid.
Upvotes: 0
Views: 109
Reputation: 247830
There are three problems with that EXECUTE
statement:
You use parameter $2
, which corresponds to the second argument, but there is only a single argument.
You are trying to pass an array as IN
list, which won't work. Use the equivalent, but correct
WHERE colname = ANY ($1)
You construct an SQL string with ||
, which makes the code vulnerable to SQL injection. Use the format
function with the %I
pattern to make the code safe and more readable.
Upvotes: 1