diff --git a/contrib/dblink/Makefile b/contrib/dblink/Makefile
index b8d5157..f31b9f7 100644
*** a/contrib/dblink/Makefile
--- b/contrib/dblink/Makefile
*************** PG_CPPFLAGS = -I$(libpq_srcdir)
*** 6,12 ****
SHLIB_LINK = $(libpq)
EXTENSION = dblink
! DATA = dblink--1.1.sql dblink--1.0--1.1.sql dblink--unpackaged--1.0.sql
PGFILEDESC = "dblink - connect to other PostgreSQL databases"
REGRESS = paths dblink
--- 6,13 ----
SHLIB_LINK = $(libpq)
EXTENSION = dblink
! DATA = dblink--1.1.sql dblink--1.0--1.1.sql dblink--unpackaged--1.0.sql \
! dblink--1.2.sql dblink--1.1--1.2.sql
PGFILEDESC = "dblink - connect to other PostgreSQL databases"
REGRESS = paths dblink
diff --git a/contrib/dblink/dblink--1.1--1.2.sql b/contrib/dblink/dblink--1.1--1.2.sql
index ...128611d .
*** a/contrib/dblink/dblink--1.1--1.2.sql
--- b/contrib/dblink/dblink--1.1--1.2.sql
***************
*** 0 ****
--- 1,46 ----
+ /* contrib/dblink/dblink--1.1--1.2.sql */
+
+ -- complain if script is sourced in psql, rather than via ALTER EXTENSION
+ \echo Use "ALTER EXTENSION dblink UPDATE TO '1.2'" to load this file. \quit
+
+ CREATE FUNCTION dblink (text, text, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink (text, text, boolean, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink (text, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink (text, boolean, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_get_result(text, anyelement)
+ RETURNS SETOF anyelement
+ AS 'MODULE_PATHNAME', 'dblink_get_result'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_get_result(text, bool, anyelement)
+ RETURNS SETOF anyelement
+ AS 'MODULE_PATHNAME', 'dblink_get_result'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_fetch (text, int, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_fetch'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_fetch (text, int, boolean, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_fetch'
+ LANGUAGE C;
+
+
diff --git a/contrib/dblink/dblink--1.2.sql b/contrib/dblink/dblink--1.2.sql
index ...1d84df2 .
*** a/contrib/dblink/dblink--1.2.sql
--- b/contrib/dblink/dblink--1.2.sql
***************
*** 0 ****
--- 1,275 ----
+ /* contrib/dblink/dblink--1.2.sql */
+
+ -- complain if script is sourced in psql, rather than via CREATE EXTENSION
+ \echo Use "CREATE EXTENSION dblink" to load this file. \quit
+
+ -- dblink_connect now restricts non-superusers to password
+ -- authenticated connections
+ CREATE FUNCTION dblink_connect (text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_connect'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_connect (text, text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_connect'
+ LANGUAGE C STRICT;
+
+ -- dblink_connect_u allows non-superusers to use
+ -- non-password authenticated connections, but initially
+ -- privileges are revoked from public
+ CREATE FUNCTION dblink_connect_u (text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_connect'
+ LANGUAGE C STRICT SECURITY DEFINER;
+
+ CREATE FUNCTION dblink_connect_u (text, text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_connect'
+ LANGUAGE C STRICT SECURITY DEFINER;
+
+ REVOKE ALL ON FUNCTION dblink_connect_u (text) FROM public;
+ REVOKE ALL ON FUNCTION dblink_connect_u (text, text) FROM public;
+
+ CREATE FUNCTION dblink_disconnect ()
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_disconnect'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_disconnect (text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_disconnect'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_open (text, text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_open'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_open (text, text, boolean)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_open'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_open (text, text, text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_open'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_open (text, text, text, boolean)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_open'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_fetch (text, int)
+ RETURNS setof record
+ AS 'MODULE_PATHNAME','dblink_fetch'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_fetch (text, int, boolean)
+ RETURNS setof record
+ AS 'MODULE_PATHNAME','dblink_fetch'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_fetch (text, int, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_fetch'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_fetch (text, int, boolean, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_fetch'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_fetch (text, text, int)
+ RETURNS setof record
+ AS 'MODULE_PATHNAME','dblink_fetch'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_fetch (text, text, int, boolean)
+ RETURNS setof record
+ AS 'MODULE_PATHNAME','dblink_fetch'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_close (text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_close'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_close (text, boolean)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_close'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_close (text, text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_close'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_close (text, text, boolean)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_close'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink (text, text)
+ RETURNS setof record
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink (text, text, boolean)
+ RETURNS setof record
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink (text)
+ RETURNS setof record
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink (text, boolean)
+ RETURNS setof record
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink (text, text, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink (text, text, boolean, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink (text, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink (text, boolean, anyelement)
+ RETURNS setof anyelement
+ AS 'MODULE_PATHNAME','dblink_record'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_exec (text, text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_exec'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_exec (text, text, boolean)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_exec'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_exec (text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_exec'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_exec (text,boolean)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_exec'
+ LANGUAGE C STRICT;
+
+ CREATE TYPE dblink_pkey_results AS (position int, colname text);
+
+ CREATE FUNCTION dblink_get_pkey (text)
+ RETURNS setof dblink_pkey_results
+ AS 'MODULE_PATHNAME','dblink_get_pkey'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_build_sql_insert (text, int2vector, int, _text, _text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_build_sql_insert'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_build_sql_delete (text, int2vector, int, _text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_build_sql_delete'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_build_sql_update (text, int2vector, int, _text, _text)
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_build_sql_update'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_current_query ()
+ RETURNS text
+ AS 'MODULE_PATHNAME','dblink_current_query'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_send_query(text, text)
+ RETURNS int4
+ AS 'MODULE_PATHNAME', 'dblink_send_query'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_is_busy(text)
+ RETURNS int4
+ AS 'MODULE_PATHNAME', 'dblink_is_busy'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_get_result(text)
+ RETURNS SETOF record
+ AS 'MODULE_PATHNAME', 'dblink_get_result'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_get_result(text, bool)
+ RETURNS SETOF record
+ AS 'MODULE_PATHNAME', 'dblink_get_result'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_get_result(text, anyelement)
+ RETURNS SETOF anyelement
+ AS 'MODULE_PATHNAME', 'dblink_get_result'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_get_result(text, bool, anyelement)
+ RETURNS SETOF anyelement
+ AS 'MODULE_PATHNAME', 'dblink_get_result'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_get_connections()
+ RETURNS text[]
+ AS 'MODULE_PATHNAME', 'dblink_get_connections'
+ LANGUAGE C;
+
+ CREATE FUNCTION dblink_cancel_query(text)
+ RETURNS text
+ AS 'MODULE_PATHNAME', 'dblink_cancel_query'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_error_message(text)
+ RETURNS text
+ AS 'MODULE_PATHNAME', 'dblink_error_message'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_get_notify(
+ OUT notify_name TEXT,
+ OUT be_pid INT4,
+ OUT extra TEXT
+ )
+ RETURNS setof record
+ AS 'MODULE_PATHNAME', 'dblink_get_notify'
+ LANGUAGE C STRICT;
+
+ CREATE FUNCTION dblink_get_notify(
+ conname TEXT,
+ OUT notify_name TEXT,
+ OUT be_pid INT4,
+ OUT extra TEXT
+ )
+ RETURNS setof record
+ AS 'MODULE_PATHNAME', 'dblink_get_notify'
+ LANGUAGE C STRICT;
+
+ /* New stuff in 1.1 begins here */
+
+ CREATE FUNCTION dblink_fdw_validator(
+ options text[],
+ catalog oid
+ )
+ RETURNS void
+ AS 'MODULE_PATHNAME', 'dblink_fdw_validator'
+ LANGUAGE C STRICT;
+
+ CREATE FOREIGN DATA WRAPPER dblink_fdw VALIDATOR dblink_fdw_validator;
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index c5892d3..09c6d35 100644
*** a/contrib/dblink/dblink.c
--- b/contrib/dblink/dblink.c
*************** dblink_fetch(PG_FUNCTION_ARGS)
*** 537,588 ****
char *curname = NULL;
int howmany = 0;
bool fail = true; /* default to backward compatible */
prepTuplestoreResult(fcinfo);
DBLINK_INIT;
! if (PG_NARGS() == 4)
{
! /* text,text,int,bool */
conname = text_to_cstring(PG_GETARG_TEXT_PP(0));
curname = text_to_cstring(PG_GETARG_TEXT_PP(1));
howmany = PG_GETARG_INT32(2);
! fail = PG_GETARG_BOOL(3);
!
rconn = getConnectionByName(conname);
if (rconn)
conn = rconn->conn;
}
! else if (PG_NARGS() == 3)
! {
! /* text,text,int or text,int,bool */
! if (get_fn_expr_argtype(fcinfo->flinfo, 2) == BOOLOID)
! {
! curname = text_to_cstring(PG_GETARG_TEXT_PP(0));
! howmany = PG_GETARG_INT32(1);
! fail = PG_GETARG_BOOL(2);
! conn = pconn->conn;
! }
! else
! {
! conname = text_to_cstring(PG_GETARG_TEXT_PP(0));
! curname = text_to_cstring(PG_GETARG_TEXT_PP(1));
! howmany = PG_GETARG_INT32(2);
!
! rconn = getConnectionByName(conname);
! if (rconn)
! conn = rconn->conn;
! }
! }
! else if (PG_NARGS() == 2)
{
! /* text,int */
curname = text_to_cstring(PG_GETARG_TEXT_PP(0));
howmany = PG_GETARG_INT32(1);
conn = pconn->conn;
}
if (!conn)
DBLINK_CONN_NOT_AVAIL;
--- 537,575 ----
char *curname = NULL;
int howmany = 0;
bool fail = true; /* default to backward compatible */
+ int first_optarg;
prepTuplestoreResult(fcinfo);
DBLINK_INIT;
! if (get_fn_expr_argtype(fcinfo->flinfo,1) == TEXTOID)
{
! /* text,text,int,[bool],[anytype] */
conname = text_to_cstring(PG_GETARG_TEXT_PP(0));
curname = text_to_cstring(PG_GETARG_TEXT_PP(1));
howmany = PG_GETARG_INT32(2);
! first_optarg = 3;
rconn = getConnectionByName(conname);
if (rconn)
conn = rconn->conn;
}
! else
{
! /* text,int,[bool],[anytype] */
curname = text_to_cstring(PG_GETARG_TEXT_PP(0));
howmany = PG_GETARG_INT32(1);
+ first_optarg = 2;
conn = pconn->conn;
}
+ if ((first_optarg < PG_NARGS()) &&
+ (get_fn_expr_argtype(fcinfo->flinfo, first_optarg) == BOOLOID))
+ {
+ fail = PG_GETARG_BOOL(first_optarg);
+ }
+ /* ignore the last arg (if any) as it just provides a return rowtype */
+
if (!conn)
DBLINK_CONN_NOT_AVAIL;
*************** dblink_record_internal(FunctionCallInfo
*** 680,706 ****
if (!is_async)
{
! if (PG_NARGS() == 3)
{
! /* text,text,bool */
DBLINK_GET_CONN;
sql = text_to_cstring(PG_GETARG_TEXT_PP(1));
fail = PG_GETARG_BOOL(2);
}
else if (PG_NARGS() == 2)
{
! /* text,text or text,bool */
if (get_fn_expr_argtype(fcinfo->flinfo, 1) == BOOLOID)
{
conn = pconn->conn;
sql = text_to_cstring(PG_GETARG_TEXT_PP(0));
fail = PG_GETARG_BOOL(1);
}
! else
{
DBLINK_GET_CONN;
sql = text_to_cstring(PG_GETARG_TEXT_PP(1));
}
}
else if (PG_NARGS() == 1)
{
--- 667,734 ----
if (!is_async)
{
! if (PG_NARGS() == 4)
{
! /* text,text,bool,anyelement */
! if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2))
! PG_RETURN_NULL();
!
DBLINK_GET_CONN;
sql = text_to_cstring(PG_GETARG_TEXT_PP(1));
fail = PG_GETARG_BOOL(2);
+ /* ignore fourth arg as it just provides a return rowtype */
+ }
+ else if (PG_NARGS() == 3)
+ {
+ /* text,text,bool or text,text,anyelement or text,bool,anyelement */
+ if (get_fn_expr_argtype(fcinfo->flinfo, 2) == BOOLOID)
+ {
+ DBLINK_GET_CONN;
+ sql = text_to_cstring(PG_GETARG_TEXT_PP(1));
+ fail = PG_GETARG_BOOL(2);
+ }
+ else
+ {
+ if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
+ PG_RETURN_NULL();
+
+ if (get_fn_expr_argtype(fcinfo->flinfo, 1) == BOOLOID)
+ {
+ conn = pconn->conn;
+ sql = text_to_cstring(PG_GETARG_TEXT_PP(0));
+ fail = PG_GETARG_BOOL(1);
+ }
+ else
+ {
+ DBLINK_GET_CONN;
+ sql = text_to_cstring(PG_GETARG_TEXT_PP(1));
+ }
+ /* ignore third arg as it just provides a return rowtype */
+ }
}
else if (PG_NARGS() == 2)
{
! /* text,text or text,bool or text,anyelement */
if (get_fn_expr_argtype(fcinfo->flinfo, 1) == BOOLOID)
{
conn = pconn->conn;
sql = text_to_cstring(PG_GETARG_TEXT_PP(0));
fail = PG_GETARG_BOOL(1);
}
! else if (get_fn_expr_argtype(fcinfo->flinfo, 1) == TEXTOID)
{
DBLINK_GET_CONN;
sql = text_to_cstring(PG_GETARG_TEXT_PP(1));
}
+ else
+ {
+ if (PG_ARGISNULL(0))
+ PG_RETURN_NULL();
+
+ conn = pconn->conn;
+ sql = text_to_cstring(PG_GETARG_TEXT_PP(0));
+ /* ignore second arg as it just provides a return rowtype */
+ }
}
else if (PG_NARGS() == 1)
{
*************** dblink_record_internal(FunctionCallInfo
*** 715,725 ****
else /* is_async */
{
/* get async result */
! if (PG_NARGS() == 2)
{
! /* text,bool */
DBLINK_GET_NAMED_CONN;
fail = PG_GETARG_BOOL(1);
}
else if (PG_NARGS() == 1)
{
--- 743,774 ----
else /* is_async */
{
/* get async result */
! if (PG_NARGS() == 3)
{
! /* text,bool,anyelement */
! if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
! PG_RETURN_NULL();
!
DBLINK_GET_NAMED_CONN;
fail = PG_GETARG_BOOL(1);
+ /* ignore third arg as it just provides a return rowtype */
+ }
+ else if (PG_NARGS() == 2)
+ {
+ /* text,bool or text,anyelement */
+ if (get_fn_expr_argtype(fcinfo->flinfo, 1) == BOOLOID)
+ {
+ DBLINK_GET_NAMED_CONN;
+ fail = PG_GETARG_BOOL(1);
+ }
+ else
+ {
+ if (PG_ARGISNULL(0))
+ PG_RETURN_NULL();
+
+ DBLINK_GET_NAMED_CONN;
+ /* ignore second arg as it just provides a return rowtype */
+ }
}
else if (PG_NARGS() == 1)
{
diff --git a/contrib/dblink/dblink.control b/contrib/dblink/dblink.control
index 39f439a..bdd17d2 100644
*** a/contrib/dblink/dblink.control
--- b/contrib/dblink/dblink.control
***************
*** 1,5 ****
# dblink extension
comment = 'connect to other PostgreSQL databases from within a database'
! default_version = '1.1'
module_pathname = '$libdir/dblink'
relocatable = true
--- 1,5 ----
# dblink extension
comment = 'connect to other PostgreSQL databases from within a database'
! default_version = '1.2'
module_pathname = '$libdir/dblink'
relocatable = true
diff --git a/contrib/dblink/expected/dblink.out b/contrib/dblink/expected/dblink.out
index a49b562..290bb5b 100644
*** a/contrib/dblink/expected/dblink.out
--- b/contrib/dblink/expected/dblink.out
*************** WHERE t.a > 7;
*** 101,106 ****
--- 101,116 ----
9 | j | {a9,b9,c9}
(2 rows)
+ -- dblink with anyelement
+ SELECT *
+ FROM dblink('dbname=contrib_regression','SELECT * FROM foo',null::foo) as t
+ WHERE t.f1 > 7;
+ f1 | f2 | f3
+ ----+----+------------
+ 8 | i | {a8,b8,c8}
+ 9 | j | {a9,b9,c9}
+ (2 rows)
+
-- should generate "connection not available" error
SELECT *
FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
*************** FROM dblink_fetch('rmt_foo_cursor',4) AS
*** 198,211 ****
3 | d | {a3,b3,c3}
(4 rows)
SELECT *
! FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
! a | b | c
! ---+---+------------
! 4 | e | {a4,b4,c4}
! 5 | f | {a5,b5,c5}
! 6 | g | {a6,b6,c6}
! 7 | h | {a7,b7,c7}
(4 rows)
-- this one only finds two rows left
--- 208,222 ----
3 | d | {a3,b3,c3}
(4 rows)
+ -- fetch using anyelement, which will change the column names
SELECT *
! FROM dblink_fetch('rmt_foo_cursor',4,null::foo) AS t;
! f1 | f2 | f3
! ----+----+------------
! 4 | e | {a4,b4,c4}
! 5 | f | {a5,b5,c5}
! 6 | g | {a6,b6,c6}
! 7 | h | {a7,b7,c7}
(4 rows)
-- this one only finds two rows left
*************** UNION
*** 726,731 ****
--- 737,791 ----
UNION
(SELECT * from dblink_get_result('dtest3') as t3(f1 int, f2 text, f3 text[]))
ORDER by f1;
+ -- clear off the connections for the next query;
+ 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[]);
+ f1 | f2 | f3
+ ----+----+----
+ (0 rows)
+
+ SELECT * from
+ dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
+ t1
+ ----
+ 1
+ (1 row)
+
+ SELECT * from
+ dblink_send_query('dtest2', 'select * from foo where f1 > 2 and f1 < 7') as t1;
+ t1
+ ----
+ 1
+ (1 row)
+
+ SELECT * from
+ dblink_send_query('dtest3', 'select * from foo where f1 > 6') as t1;
+ t1
+ ----
+ 1
+ (1 row)
+
+ CREATE TEMPORARY TABLE result_anyelement AS
+ (SELECT * from dblink_get_result('dtest1',null::foo))
+ UNION
+ (SELECT * from dblink_get_result('dtest2',null::foo))
+ UNION
+ (SELECT * from dblink_get_result('dtest3',null::foo))
+ ORDER by f1;
+ -- result and result_anyelement should be identical
+ SELECT * FROM result EXCEPT SELECT * FROM result_anyelement;
+ f1 | f2 | f3
+ ----+----+----
+ (0 rows)
+
+ SELECT * FROM result_anyelement EXCEPT SELECT * FROM result;
+ f1 | f2 | f3
+ ----+----+----
+ (0 rows)
+
-- dblink_get_connections returns an array with elements in a machine-dependent
-- ordering, so we must resort to unnesting and sorting for a stable result
create function unnest(anyarray) returns setof anyelement
diff --git a/contrib/dblink/sql/dblink.sql b/contrib/dblink/sql/dblink.sql
index ea78cc2..9324b97 100644
*** a/contrib/dblink/sql/dblink.sql
--- b/contrib/dblink/sql/dblink.sql
*************** SELECT *
*** 64,69 ****
--- 64,74 ----
FROM dblink(connection_parameters(),'SELECT * FROM foo') AS t(a int, b text, c text[])
WHERE t.a > 7;
+ -- dblink with anyelement
+ SELECT *
+ FROM dblink('dbname=contrib_regression','SELECT * FROM foo',null::foo) as t
+ WHERE t.f1 > 7;
+
-- should generate "connection not available" error
SELECT *
FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
*************** SELECT dblink_open('rmt_foo_cursor','SEL
*** 124,131 ****
SELECT *
FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
SELECT *
! FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
-- this one only finds two rows left
SELECT *
--- 129,137 ----
SELECT *
FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
+ -- fetch using anyelement, which will change the column names
SELECT *
! FROM dblink_fetch('rmt_foo_cursor',4,null::foo) AS t;
-- this one only finds two rows left
SELECT *
*************** UNION
*** 365,370 ****
--- 371,402 ----
(SELECT * from dblink_get_result('dtest3') as t3(f1 int, f2 text, f3 text[]))
ORDER by f1;
+ -- clear off the connections for the next query;
+ 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[]);
+
+ SELECT * from
+ dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
+ SELECT * from
+ dblink_send_query('dtest2', 'select * from foo where f1 > 2 and f1 < 7') as t1;
+ SELECT * from
+ dblink_send_query('dtest3', 'select * from foo where f1 > 6') as t1;
+
+ CREATE TEMPORARY TABLE result_anyelement AS
+ (SELECT * from dblink_get_result('dtest1',null::foo))
+ UNION
+ (SELECT * from dblink_get_result('dtest2',null::foo))
+ UNION
+ (SELECT * from dblink_get_result('dtest3',null::foo))
+ ORDER by f1;
+
+ -- result and result_anyelement should be identical
+ SELECT * FROM result EXCEPT SELECT * FROM result_anyelement;
+ SELECT * FROM result_anyelement EXCEPT SELECT * FROM result;
+
-- dblink_get_connections returns an array with elements in a machine-dependent
-- ordering, so we must resort to unnesting and sorting for a stable result
create function unnest(anyarray) returns setof anyelement
diff --git a/doc/src/sgml/dblink.sgml b/doc/src/sgml/dblink.sgml
index b07ac48..4c472ab 100644
*** a/doc/src/sgml/dblink.sgml
--- b/doc/src/sgml/dblink.sgml
*************** SELECT dblink_disconnect('myconn');
*** 334,339 ****
--- 334,342 ----
dblink(text connname, text sql [, bool fail_on_error]) returns setof record
dblink(text connstr, text sql [, bool fail_on_error]) returns setof record
dblink(text sql [, bool fail_on_error]) returns setof record
+ dblink(text connname, text sql [, bool fail_on_error], anyelement rowtype) returns setof rowtype
+ dblink(text connstr, text sql [, bool fail_on_error], anyelement rowtype) returns setof rowtype
+ dblink(text sql [, bool fail_on_error], anyelement rowtype) returns setof rowtype
*************** dblink(text sql [, bool fail_on_error])
*** 399,404 ****
--- 402,420 ----
+
+
alias> had been used.