Commit 52a3ed9f authored by Joe Conway's avatar Joe Conway

Added async query capability. Original patch by

Kai Londenberg, modified by Joe Conway
parent 1cc9299a
......@@ -7,6 +7,7 @@
* And contributors:
* Darko Prenosil <Darko.Prenosil@finteh.hr>
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
* Kai Londenberg (K.Londenberg@librics.de)
*
* Copyright (c) 2001-2006, PostgreSQL Global Development Group
* ALL RIGHTS RESERVED;
......@@ -31,6 +32,9 @@
*/
Release Notes:
27 August 2006
- Added async query capability. Original patch by
Kai Londenberg (K.Londenberg@librics.de), modified by Joe Conway
Version 0.7 (as of 25 Feb, 2004)
- Added new version of dblink, dblink_exec, dblink_open, dblink_close,
and, dblink_fetch -- allows ERROR on remote side of connection to
......@@ -85,75 +89,7 @@ Installation:
psql template1 < dblink.sql
installs following functions into database template1:
connection
------------
dblink_connect(text) RETURNS text
- opens an unnamed connection that will persist for duration of
current backend or until it is disconnected
dblink_connect(text,text) RETURNS text
- opens a named connection that will persist for duration of current
backend or until it is disconnected
dblink_disconnect() RETURNS text
- disconnects the unnamed persistent connection
dblink_disconnect(text) RETURNS text
- disconnects a named persistent connection
cursor
------------
dblink_open(text,text [, bool fail_on_error]) RETURNS text
- opens a cursor using unnamed connection already opened with
dblink_connect() that will persist for duration of current backend
or until it is closed
dblink_open(text,text,text [, bool fail_on_error]) RETURNS text
- opens a cursor using a named connection already opened with
dblink_connect() that will persist for duration of current backend
or until it is closed
dblink_fetch(text, int [, bool fail_on_error]) RETURNS setof record
- fetches data from an already opened cursor on the unnamed connection
dblink_fetch(text, text, int [, bool fail_on_error]) RETURNS setof record
- fetches data from an already opened cursor on a named connection
dblink_close(text [, bool fail_on_error]) RETURNS text
- closes a cursor on the unnamed connection
dblink_close(text,text [, bool fail_on_error]) RETURNS text
- closes a cursor on a named connection
query
------------
dblink(text,text [, bool fail_on_error]) RETURNS setof record
- returns a set of results from remote SELECT query; the first argument
is either a connection string, or the name of an already opened
persistant connection
dblink(text [, bool fail_on_error]) RETURNS setof record
- returns a set of results from remote SELECT query, using the unnamed
connection already opened with dblink_connect()
execute
------------
dblink_exec(text, text [, bool fail_on_error]) RETURNS text
- executes an INSERT/UPDATE/DELETE query remotely; the first argument
is either a connection string, or the name of an already opened
persistant connection
dblink_exec(text [, bool fail_on_error]) RETURNS text
- executes an INSERT/UPDATE/DELETE query remotely, using connection
already opened with dblink_connect()
misc
------------
dblink_current_query() RETURNS text
- returns the current query string
dblink_get_pkey(text) RETURNS setof text
- returns the field names of a relation's primary key fields
dblink_build_sql_insert(text,int2vector,int2,_text,_text) RETURNS text
- builds an insert statement using a local tuple, replacing the
selection key field values with alternate supplied values
dblink_build_sql_delete(text,int2vector,int2,_text) RETURNS text
- builds a delete statement using supplied values for selection
key field values
dblink_build_sql_update(text,int2vector,int2,_text,_text) RETURNS text
- builds an update statement using a local tuple, replacing the
selection key field values with alternate supplied values
installs dblink functions into database template1
Documentation:
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
* Darko Prenosil <Darko.Prenosil@finteh.hr>
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
*
* $PostgreSQL: pgsql/contrib/dblink/dblink.h,v 1.16 2006/07/10 18:40:16 momjian Exp $
* $PostgreSQL: pgsql/contrib/dblink/dblink.h,v 1.17 2006/09/02 21:11:15 joe Exp $
* Copyright (c) 2001-2006, PostgreSQL Global Development Group
* ALL RIGHTS RESERVED;
*
......@@ -45,6 +45,12 @@ extern Datum dblink_open(PG_FUNCTION_ARGS);
extern Datum dblink_close(PG_FUNCTION_ARGS);
extern Datum dblink_fetch(PG_FUNCTION_ARGS);
extern Datum dblink_record(PG_FUNCTION_ARGS);
extern Datum dblink_send_query(PG_FUNCTION_ARGS);
extern Datum dblink_get_result(PG_FUNCTION_ARGS);
extern Datum dblink_get_connections(PG_FUNCTION_ARGS);
extern Datum dblink_is_busy(PG_FUNCTION_ARGS);
extern Datum dblink_cancel_query(PG_FUNCTION_ARGS);
extern Datum dblink_error_message(PG_FUNCTION_ARGS);
extern Datum dblink_exec(PG_FUNCTION_ARGS);
extern Datum dblink_get_pkey(PG_FUNCTION_ARGS);
extern Datum dblink_build_sql_insert(PG_FUNCTION_ARGS);
......
......@@ -144,3 +144,38 @@ CREATE OR REPLACE FUNCTION dblink_current_query ()
RETURNS text
AS 'MODULE_PATHNAME','dblink_current_query'
LANGUAGE C;
CREATE OR REPLACE FUNCTION dblink_send_query(text, text)
RETURNS int4
AS 'MODULE_PATHNAME', 'dblink_send_query'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION dblink_is_busy(text)
RETURNS int4
AS 'MODULE_PATHNAME', 'dblink_is_busy'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION dblink_get_result(text)
RETURNS SETOF record
AS 'MODULE_PATHNAME', 'dblink_get_result'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION dblink_get_result(text, bool)
RETURNS SETOF record
AS 'MODULE_PATHNAME', 'dblink_get_result'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION dblink_get_connections()
RETURNS text[]
AS 'MODULE_PATHNAME', 'dblink_get_connections'
LANGUAGE C;
CREATE OR REPLACE FUNCTION dblink_cancel_query(text)
RETURNS text
AS 'MODULE_PATHNAME', 'dblink_cancel_query'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION dblink_error_message(text)
RETURNS text
AS 'MODULE_PATHNAME', 'dblink_error_message'
LANGUAGE C STRICT;
$PostgreSQL: pgsql/contrib/dblink/doc/misc,v 1.3 2006/03/11 04:38:29 momjian Exp $
$PostgreSQL: pgsql/contrib/dblink/doc/misc,v 1.4 2006/09/02 21:11:15 joe Exp $
==================================================================
Name
......@@ -139,3 +139,94 @@ test=# select dblink_build_sql_update('foo','1 2',2,'{"1", "a"}','{"1", "b"}');
UPDATE foo SET f1='1',f2='b',f3='1' WHERE f1='1' AND f2='b'
(1 row)
==================================================================
Name
dblink_get_connections -- returns a text array of all active named
dblink connections
Synopsis
dblink_get_connections() RETURNS text[]
Inputs
none
Outputs
Returns text array of all active named dblink connections
Example usage
SELECT dblink_get_connections();
==================================================================
Name
dblink_is_busy -- checks to see if named connection is busy
with an async query
Synopsis
dblink_is_busy(text connname) RETURNS int
Inputs
connname
The specific connection name to use.
Outputs
Returns 1 if connection is busy, 0 if it is not busy.
If this function returns 0, it is guaranteed that dblink_get_result
will not block.
Example usage
SELECT dblink_is_busy('dtest1');
==================================================================
Name
dblink_cancel_query -- cancels any active query on the named connection
Synopsis
dblink_cancel_query(text connname) RETURNS text
Inputs
connname
The specific connection name to use.
Outputs
Returns "OK" on success, or an error message on failure.
Example usage
SELECT dblink_cancel_query('dtest1');
==================================================================
Name
dblink_error_message -- gets last error message on the named connection
Synopsis
dblink_error_message(text connname) RETURNS text
Inputs
connname
The specific connection name to use.
Outputs
Returns last error message.
Example usage
SELECT dblink_error_message('dtest1');
......@@ -118,3 +118,125 @@ Then you can simply write:
select * from myremote_pg_proc where proname like 'bytea%';
==================================================================
Name
dblink_send_query -- Sends an async query to a remote database
Synopsis
dblink_send_query(text connname, text sql)
Inputs
connname
The specific connection name to use.
sql
sql statement that you wish to execute on the remote host
e.g. "select * from pg_class"
Outputs
Returns int. A return value of 1 if the query was successfully dispatched,
0 otherwise. If 1, results must be fetched by dblink_get_result(connname).
A running query may be cancelled by dblink_cancel_query(connname).
Example usage
SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
SELECT * from
dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
==================================================================
Name
dblink_get_result -- Gets an async query result
Synopsis
dblink_get_result(text connname [, bool fail_on_error])
Inputs
connname
The specific connection name to use. An asynchronous query must
have already been sent using dblink_send_query()
fail_on_error
If true (default when not present) then an ERROR thrown on the remote side
of the connection causes an ERROR to also be thrown locally. If false, the
remote ERROR is locally treated as a NOTICE, and no rows are returned.
Outputs
Returns setof record
Notes
Blocks until a result gets available.
This function *must* be called if dblink_send_query returned
a 1, even on cancelled queries - otherwise the connection
can't be used anymore. It must be called once for each query
sent, and one additional time to obtain an empty set result,
prior to using the connection again.
Example usage
contrib_regression=# SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
dblink_connect
----------------
OK
(1 row)
contrib_regression=# SELECT * from
contrib_regression-# dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
t1
----
1
(1 row)
contrib_regression=# SELECT * from dblink_get_result('dtest1') as t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+------------
0 | a | {a0,b0,c0}
1 | b | {a1,b1,c1}
2 | c | {a2,b2,c2}
(3 rows)
contrib_regression=# SELECT * from dblink_get_result('dtest1') as t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+----
(0 rows)
contrib_regression=# SELECT * from
dblink_send_query('dtest1', 'select * from foo where f1 < 3; select * from foo where f1 > 6') as t1;
t1
----
1
(1 row)
contrib_regression=# SELECT * from dblink_get_result('dtest1') as t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+------------
0 | a | {a0,b0,c0}
1 | b | {a1,b1,c1}
2 | c | {a2,b2,c2}
(3 rows)
contrib_regression=# SELECT * from dblink_get_result('dtest1') as t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+---------------
7 | h | {a7,b7,c7}
8 | i | {a8,b8,c8}
9 | j | {a9,b9,c9}
10 | k | {a10,b10,c10}
(4 rows)
contrib_regression=# SELECT * from dblink_get_result('dtest1') as t1(f1 int, f2 text, f3 text[]);
f1 | f2 | f3
----+----+----
(0 rows)
......@@ -669,3 +669,90 @@ SELECT dblink_disconnect('myconn');
-- should get 'connection "myconn" not available' error
SELECT dblink_disconnect('myconn');
ERROR: connection "myconn" not available
-- test asynchronous queries
SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
dblink_connect
----------------
OK
(1 row)
SELECT * from
dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
t1
----
1
(1 row)
SELECT dblink_connect('dtest2', 'dbname=contrib_regression');
dblink_connect
----------------
OK
(1 row)
SELECT * from
dblink_send_query('dtest2', 'select * from foo where f1 > 2 and f1 < 7') as t1;
t1
----
1
(1 row)
SELECT dblink_connect('dtest3', 'dbname=contrib_regression');
dblink_connect
----------------
OK
(1 row)
SELECT * from
dblink_send_query('dtest3', 'select * from foo where f1 > 6') as t1;
t1
----
1
(1 row)
CREATE TEMPORARY TABLE result AS
(SELECT * from dblink_get_result('dtest1') as t1(f1 int, f2 text, f3 text[]))
UNION
(SELECT * from dblink_get_result('dtest2') as t2(f1 int, f2 text, f3 text[]))
UNION
(SELECT * from dblink_get_result('dtest3') as t3(f1 int, f2 text, f3 text[]))
ORDER by f1;
SELECT dblink_get_connections();
dblink_get_connections
------------------------
{dtest1,dtest2,dtest3}
(1 row)
SELECT dblink_disconnect('dtest1');
dblink_disconnect
-------------------
OK
(1 row)
SELECT dblink_disconnect('dtest2');
dblink_disconnect
-------------------
OK
(1 row)
SELECT dblink_disconnect('dtest3');
dblink_disconnect
-------------------
OK
(1 row)
SELECT * from result;
f1 | f2 | f3
----+----+---------------
0 | a | {a0,b0,c0}
1 | b | {a1,b1,c1}
2 | c | {a2,b2,c2}
3 | d | {a3,b3,c3}
4 | e | {a4,b4,c4}
5 | f | {a5,b5,c5}
6 | g | {a6,b6,c6}
7 | h | {a7,b7,c7}
8 | i | {a8,b8,c8}
9 | j | {a9,b9,c9}
10 | k | {a10,b10,c10}
(11 rows)
......@@ -319,3 +319,32 @@ SELECT dblink_disconnect('myconn');
-- close the named persistent connection again
-- should get 'connection "myconn" not available' error
SELECT dblink_disconnect('myconn');
-- test asynchronous queries
SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
SELECT * from
dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
SELECT dblink_connect('dtest2', 'dbname=contrib_regression');
SELECT * from
dblink_send_query('dtest2', 'select * from foo where f1 > 2 and f1 < 7') as t1;
SELECT dblink_connect('dtest3', 'dbname=contrib_regression');
SELECT * from
dblink_send_query('dtest3', 'select * from foo where f1 > 6') as t1;
CREATE TEMPORARY TABLE result AS
(SELECT * from dblink_get_result('dtest1') as t1(f1 int, f2 text, f3 text[]))
UNION
(SELECT * from dblink_get_result('dtest2') as t2(f1 int, f2 text, f3 text[]))
UNION
(SELECT * from dblink_get_result('dtest3') as t3(f1 int, f2 text, f3 text[]))
ORDER by f1;
SELECT dblink_get_connections();
SELECT dblink_disconnect('dtest1');
SELECT dblink_disconnect('dtest2');
SELECT dblink_disconnect('dtest3');
SELECT * from result;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment