I would like to cast from ARGV[] which is text to int array in PostgreSQL where I marked the pseudocode by TODO in the code. Code in PostgreSQL 9.4.3 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit:
CREATE TABLE measurements (
measurement_id SERIAL PRIMARY KEY NOT NULL,
measurement_size_in_bytes INTEGER NOT NULL
);
CREATE TABLE events (
event_id SERIAL PRIMARY KEY NOT NULL,
measurement_id INTEGER NOT NULL,
event_index_start INTEGER NOT NULL,
event_index_end INTEGER NOT NULL
);
CREATE OR REPLACE FUNCTION insaft_function()
RETURNS TRIGGER AS
$func$
BEGIN
-- TODO Loop until TG_ARGV[0] empty
INSERT INTO events (measurement_id, event_index_start, event_index_end)
SELECT NEW.measurement_id, TG_ARGV[0]::int[], TG_ARGV[1]::int[];
-- END TODO
RETURN NULL; -- result ignored since this is an AFTER trigger
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER insaft_measurement_ids
AFTER INSERT ON measurements
FOR EACH ROW EXECUTE PROCEDURE insaft_function("{101, 111, 121}", "{101, 111, 121}");
which I can start by
INSERT INTO measurements (measurement_size_in_bytes) VALUES (888);
I know that the mistake is in casting here TG_ARGV[0]::int[]
into intarray which I would like loop through until the intarray is empty.
There may exists better way to do such loop inserts.
ErwinBrandstetter's code output
Code
DROP TABLE IF EXISTS measurements, events, file_headers;
CREATE TABLE measurements (
measurement_id SERIAL PRIMARY KEY NOT NULL,
measurement_size_in_bytes INTEGER NOT NULL
);
CREATE TABLE events (
event_id SERIAL PRIMARY KEY NOT NULL,
measurement_id INTEGER NOT NULL,
event_index_start INTEGER NOT NULL,
event_index_end INTEGER NOT NULL
);
DROP TRIGGER IF EXISTS insaft_ids ON measurements;
DROP FUNCTION IF EXISTS insaft_function();
CREATE OR REPLACE FUNCTION insaft_function()
RETURNS TRIGGER AS
$func$
DECLARE
m int[];
BEGIN
FOREACH m SLICE 1 IN ARRAY TG_ARGV::int[]
LOOP
INSERT INTO events (measurement_id, event_index_start, event_index_end)
SELECT NEW.measurement_id, m[1], m[2]; -- Postgres array starts with 1 !
END LOOP;
RETURN NULL; -- result ignored since this is an AFTER trigger
END
$func$ LANGUAGE plpgsql;
CREATE TRIGGER insaft_ids
AFTER INSERT ON measurements
FOR EACH ROW EXECUTE PROCEDURE insaft_function('{{101,201},{201,300}}');
Running
sudo -u postgres psql detector -c "INSERT INTO measurements (measurement_size_in_bytes) VALUES (77777);"
getting
ERROR: invalid input syntax for integer: "{{101,201},{201,300}}"
CONTEXT: PL/pgSQL function insaft_function() line 5 at FOREACH over array
How can you cast from ARGV[] which is text to int array in PostgreSQL?