By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
Help with an interesting Postgres question: Why isn't an Index Only Scan used on a partition accessed via the parent table?.
CREATE TABLE pipes (id int, geom geometry(multilinestring),node_id_dwn_str int, node_id_up_str int);
CREATE TABLE structures (node_id int, geom geometry(multipoint));
INSERT INTO structures VALUES
(1,'0104000020950B00000100000001010000001026FA48113B07410D6A8412CF1D3D41'),
(2,'0104000020950B0000010000000101000000BA1BF246E6DD0741D064CB58C2E43C41');
2 rows affected
CREATE OR REPLACE FUNCTION insert_pipe() RETURNS TRIGGER AS $$
BEGIN
SELECT
j.node_id,
i.node_id
INTO NEW.dwn_str, NEW.up_str
FROM ST_Dump(ST_SetSRID(NEW.geom,2346)) dump_line,
LATERAL (SELECT s.node_id,(ST_SetSRID(s.geom,2346))
FROM structures s
ORDER BY ST_EndPoint((dump_line).geom)<->(ST_SetSRID(s.geom,2346))
LIMIT 1) j (node_id,geom_closest_downstream),
LATERAL (SELECT s.node_id,(ST_SetSRID(s.geom,2346))
FROM structures s
ORDER BY ST_StartPoint((dump_line).geom)<->(ST_SetSRID(s.geom,2346))
LIMIT 1) i (node_id,geom_closest_upstream);
RETURN NEW;
END; $$ LANGUAGE plpgsql;
CREATE TRIGGER t_insert_pipe
BEFORE INSERT OR UPDATE ON pipes FOR EACH ROW EXECUTE PROCEDURE insert_pipe();
INSERT INTO pipes VALUES
(1,'0105000020950B00000100000001020000000200000046243EC3282608418D28242D6C1B3D4128531BE88A2608418284B3EF561B3D41'),
(2,'0105000020950B0000010000000102000000020000004ABF2CBC86B108413B93650696323D413C487924CCB10841925D490495323D41');
ERROR: record "new" has no field "dwn_str"
CONTEXT: PL/pgSQL function insert_pipe() line 3 at SQL statement
SELECT * FROM pipes;