dblink surprise

From: Torsten Förtsch <tfoertsch123(at)gmail(dot)com>
To: pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: dblink surprise
Date: 2017-11-21 21:35:25
Message-ID: CAKkG4_=QNnScB+2z4JAS89X0TdWQCeU4OgQy=vjQ9=hnGvnvVw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Hi,

according to the documentation, dblink_send_query sends the query to be
executed asynchronously. I tried this out in the following function and it
works as expected:

CREATE OR REPLACE FUNCTION t_par () RETURNS TABLE (
tx_time TIMESTAMP,
end_time TIMESTAMP
) AS $def$
DECLARE
v_q RECORD;
BEGIN
FOR v_q IN
WITH jobs(cn) AS (
VALUES ('c1'), ('c2')
)
, conn AS (
SELECT *, 1/(dblink_connect(cn, 'dbname=postgres
port=5440')='OK')::INT AS connstatus
FROM jobs
)
SELECT conn.*, 1/q.status AS sendstatus
FROM conn
CROSS JOIN LATERAL dblink_send_query(conn.cn,
$$
select now(), pg_sleep(3), clock_timestamp()
$$) q(status)
LOOP
RETURN QUERY
SELECT tb.tx_time, tb.end_time
FROM dblink_get_result(v_q.cn) tb(
tx_time TIMESTAMP,
dummy TEXT,
end_time TIMESTAMP
);
PERFORM dblink_disconnect(v_q.cn);
END LOOP;
END
$def$ LANGUAGE plpgsql;

# select * from t_par();
tx_time | end_time
----------------------------+----------------------------
2017-11-21 21:14:35.593741 | 2017-11-21 21:14:38.597384
2017-11-21 21:14:35.595805 | 2017-11-21 21:14:38.599272

Both remote queries start at the same time and finish 3 seconds later.

Then I thought I can take it one step further and collect the results in
the same statement:

CREATE OR REPLACE FUNCTION t_seq () RETURNS TABLE (
tx_time TIMESTAMP,
end_time TIMESTAMP
) AS $def$
BEGIN
RETURN QUERY
WITH v_q AS (
WITH jobs(cn) AS (
VALUES ('c1'), ('c2')
)
, conn AS (
SELECT *, 1/(dblink_connect(cn, 'dbname=postgres
port=5440')='OK')::INT AS connstatus
FROM jobs
)
SELECT conn.*, 1/q.status AS sendstatus
FROM conn
CROSS JOIN LATERAL dblink_send_query(conn.cn,
$$
select now(), pg_sleep(3), clock_timestamp()
$$) q(status)
)
SELECT tb.tx_time, tb.end_time
FROM v_q
CROSS JOIN LATERAL dblink_get_result(v_q.cn) tb(
tx_time TIMESTAMP,
dummy TEXT,
end_time TIMESTAMP
);
PERFORM dblink_disconnect(jobs.cn)
FROM (VALUES ('c1'), ('c2')) jobs(cn);
END
$def$ LANGUAGE plpgsql;

regentmarkets=# select * from t_seq();
tx_time | end_time
----------------------------+----------------------------
2017-11-21 21:25:07.764467 | 2017-11-21 21:25:10.768032
2017-11-21 21:25:10.770409 | 2017-11-21 21:25:13.773907

Unfortunately, that does not work. The remote queries are started one after
the other.

Why?

This is PG 9.6.

BTW, is it somehow possible in plpgsql to catch a query cancellation or
backend termination request? That would be useful to propagate such
requests to remote queries.

Thanks,
Torsten

Browse pgsql-general by date

  From Date Subject
Next Message Tom Lane 2017-11-21 22:37:23 Re: [GENERAL] Query Using Massive Temp Space
Previous Message Thomas Munro 2017-11-21 21:18:40 Re: [GENERAL] Query Using Massive Temp Space