-- directory paths and dlsuffix are passed to us in environment variables
\getenv abs_srcdir PG_ABS_SRCDIR
\getenv libdir PG_LIBDIR
\getenv dlsuffix PG_DLSUFFIX
\set regresslib :libdir '/regress' :dlsuffix
-- create some functions needed for tests CREATE FUNCTION setenv(text, text)
RETURNS void AS :'regresslib', 'regress_setenv'
LANGUAGE C STRICT;
CREATE FUNCTION wait_pid(int)
RETURNS void AS :'regresslib'
LANGUAGE C STRICT;
\set path :abs_srcdir '/'
\set fnbody 'SELECT setenv(''PGSERVICEFILE'', ' :'path'' || $1)' CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL AS :'fnbody';
-- want context for notices
\set SHOW_CONTEXT always
-- list the primary key fields SELECT * FROM dblink_get_pkey('foo');
-- build an insert statement based on a local tuple, -- replacing the primary key values with new ones SELECT dblink_build_sql_insert('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}'); -- too many pk fields, should fail SELECT dblink_build_sql_insert('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
-- build an update statement based on a local tuple, -- replacing the primary key values with new ones SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}'); -- too many pk fields, should fail SELECT dblink_build_sql_update('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
-- build a delete statement based on a local tuple, SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}'); -- too many pk fields, should fail SELECT dblink_build_sql_delete('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
-- repeat the test for table with primary key index with included columns CREATETABLE foo_1(f1 int, f2 text, f3 text[], primarykey (f1,f2) include (f3)); INSERTINTO foo_1 VALUES (0,'a','{"a0","b0","c0"}'); INSERTINTO foo_1 VALUES (1,'b','{"a1","b1","c1"}'); INSERTINTO foo_1 VALUES (2,'c','{"a2","b2","c2"}'); INSERTINTO foo_1 VALUES (3,'d','{"a3","b3","c3"}'); INSERTINTO foo_1 VALUES (4,'e','{"a4","b4","c4"}'); INSERTINTO foo_1 VALUES (5,'f','{"a5","b5","c5"}'); INSERTINTO foo_1 VALUES (6,'g','{"a6","b6","c6"}'); INSERTINTO foo_1 VALUES (7,'h','{"a7","b7","c7"}'); INSERTINTO foo_1 VALUES (8,'i','{"a8","b8","c8"}'); INSERTINTO foo_1 VALUES (9,'j','{"a9","b9","c9"}');
-- misc utilities
-- list the primary key fields SELECT * FROM dblink_get_pkey('foo_1');
-- build an insert statement based on a local tuple, -- replacing the primary key values with new ones SELECT dblink_build_sql_insert('foo_1','1 2',2,'{"0", "a"}','{"99", "xyz"}'); -- too many pk fields, should fail SELECT dblink_build_sql_insert('foo_1','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
-- build an update statement based on a local tuple, -- replacing the primary key values with new ones SELECT dblink_build_sql_update('foo_1','1 2',2,'{"0", "a"}','{"99", "xyz"}'); -- too many pk fields, should fail SELECT dblink_build_sql_update('foo_1','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
-- build a delete statement based on a local tuple, SELECT dblink_build_sql_delete('foo_1','1 2',2,'{"0", "a"}'); -- too many pk fields, should fail SELECT dblink_build_sql_delete('foo_1','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
DROPTABLE foo_1;
-- retest using a quoted and schema qualified table CREATESCHEMA"MySchema"; CREATETABLE"MySchema"."Foo"(f1 int, f2 text, f3 text[], primarykey (f1,f2)); INSERTINTO"MySchema"."Foo"VALUES (0,'a','{"a0","b0","c0"}');
-- list the primary key fields SELECT * FROM dblink_get_pkey('"MySchema"."Foo"');
-- build an insert statement based on a local tuple, -- replacing the primary key values with new ones SELECT dblink_build_sql_insert('"MySchema"."Foo"','1 2',2,'{"0", "a"}','{"99", "xyz"}');
-- build an update statement based on a local tuple, -- replacing the primary key values with new ones SELECT dblink_build_sql_update('"MySchema"."Foo"','1 2',2,'{"0", "a"}','{"99", "xyz"}');
-- build a delete statement based on a local tuple, SELECT dblink_build_sql_delete('"MySchema"."Foo"','1 2',2,'{"0", "a"}');
CREATE FUNCTION connection_parameters() RETURNS text LANGUAGE SQLAS $f$ SELECT $$dbname='$$||current_database()||$$' port=$$||current_setting('port');
$f$;
-- regular old dblink SELECT * FROM dblink(connection_parameters(),'SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE t.a > 7;
-- should generate "connection not available" error SELECT * FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE t.a > 7;
-- The first-level connection's backend will crash on exit given OpenLDAP -- [2.4.24, 2.4.31]. We won't see evidence of any crash until the victim -- process terminates and the postmaster responds. If process termination -- entails writing a core dump, that can take awhile. Wait for the process to -- vanish. At that point, the postmaster has called waitpid() on the crashed -- process, and it will accept no new connections until it has reinitialized -- the cluster. (We can't exploit pg_stat_activity, because the crash happens -- after the backend updates shared memory to reflect its impending exit.)
DO $pl$ DECLARE
detail text;
BEGIN
PERFORM wait_pid(crash_pid) FROM dblink(connection_parameters(), $$ SELECT pg_backend_pid() FROM dblink( 'service=test_ldap '||connection_parameters(), -- This string concatenation is a hack to shoehorn a -- set_pgservicefile call into the SQL statement. 'SELECT 1' || set_pgservicefile('pg_service.conf')
) t(c int)
$$) AS t(crash_pid int);
EXCEPTION WHEN OTHERS THEN
GET STACKED DIAGNOSTICS detail = PG_EXCEPTION_DETAIL; -- Expected error in a non-LDAP build. IFNOT detail LIKE'syntax error in service file%'THEN RAISE; END IF;
END
$pl$;
-- create a persistent connection SELECT dblink_connect(connection_parameters());
-- use the persistent connection SELECT * FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE t.a > 7;
-- open a cursor with bad SQL and fail_on_error set to false SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foobar',false);
-- reset remote transaction state SELECT dblink_exec('ABORT');
-- open a cursor SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foo');
-- close the cursor SELECT dblink_close('rmt_foo_cursor',false);
-- open the cursor again SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foo');
-- fetch some data 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 * FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
-- intentionally botch a fetch SELECT * FROM dblink_fetch('rmt_foobar_cursor',4,false) AS t(a int, b text, c text[]);
-- reset remote transaction state SELECT dblink_exec('ABORT');
-- close the wrong cursor SELECT dblink_close('rmt_foobar_cursor',false);
-- should generate 'cursor "rmt_foo_cursor" not found' error SELECT * FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
-- this time, 'cursor "rmt_foo_cursor" not found' as a notice SELECT * FROM dblink_fetch('rmt_foo_cursor',4,false) AS t(a int, b text, c text[]);
-- close the persistent connection SELECT dblink_disconnect();
-- should generate "connection not available" error SELECT * FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE t.a > 7;
-- put more data into our table, first using arbitrary connection syntax -- but truncate the actual return value so we can use diff to check for success SELECT substr(dblink_exec(connection_parameters(),'INSERT INTO foo VALUES(10,''k'',''{"a10","b10","c10"}'')'),1,6);
-- create a persistent connection SELECT dblink_connect(connection_parameters());
-- put more data into our table, using persistent connection syntax -- but truncate the actual return value so we can use diff to check for success SELECT substr(dblink_exec('INSERT INTO foo VALUES(11,''l'',''{"a11","b11","c11"}'')'),1,6);
-- let's see it SELECT * FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]);
-- bad remote select SELECT * FROM dblink('SELECT * FROM foobar',false) AS t(a int, b text, c text[]);
-- change some data SELECT dblink_exec('UPDATE foo SET f3[2] = ''b99'' WHERE f1 = 11');
-- let's see it SELECT * FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE a = 11;
-- botch a change to some other data SELECT dblink_exec('UPDATE foobar SET f3[2] = ''b99'' WHERE f1 = 11',false);
-- delete some data SELECT dblink_exec('DELETE FROM foo WHERE f1 = 11');
-- let's see it SELECT * FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE a = 11;
-- close the persistent connection SELECT dblink_disconnect();
-- -- tests for the new named persistent connection syntax --
-- should generate "missing "=" after "myconn" in connection info string" error SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE t.a > 7;
-- create a named persistent connection SELECT dblink_connect('myconn',connection_parameters());
-- use the named persistent connection SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE t.a > 7;
-- use the named persistent connection, but get it wrong SELECT * FROM dblink('myconn','SELECT * FROM foobar',false) AS t(a int, b text, c text[]) WHERE t.a > 7;
-- create a second named persistent connection -- should error with "duplicate connection name" SELECT dblink_connect('myconn',connection_parameters());
-- create a second named persistent connection with a new name SELECT dblink_connect('myconn2',connection_parameters());
-- use the second named persistent connection SELECT * FROM dblink('myconn2','SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE t.a > 7;
-- close the second named persistent connection SELECT dblink_disconnect('myconn2');
-- open a cursor incorrectly SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foobar',false);
-- reset remote transaction state SELECT dblink_exec('myconn','ABORT');
-- test opening cursor in a transaction SELECT dblink_exec('myconn','BEGIN');
-- an open transaction will prevent dblink_open() from opening its own SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foo');
-- this should not commit the transaction because the client opened it SELECT dblink_close('myconn','rmt_foo_cursor');
-- this should succeed because we have an open transaction SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
-- test automatic transactions for multiple cursor opens SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foo');
-- the second cursor SELECT dblink_open('myconn','rmt_foo_cursor2','SELECT * FROM foo');
-- this should not commit the transaction SELECT dblink_close('myconn','rmt_foo_cursor2');
-- this should succeed because we have an open transaction SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
-- this should commit the transaction SELECT dblink_close('myconn','rmt_foo_cursor');
-- this should fail because there is no open transaction SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
-- reset remote transaction state SELECT dblink_exec('myconn','ABORT');
-- open a cursor SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foo');
-- fetch some data SELECT * FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
SELECT * FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
-- this one only finds three rows left SELECT * FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
-- fetch some data incorrectly SELECT * FROM dblink_fetch('myconn','rmt_foobar_cursor',4,false) AS t(a int, b text, c text[]);
-- reset remote transaction state SELECT dblink_exec('myconn','ABORT');
-- should generate 'cursor "rmt_foo_cursor" not found' error SELECT * FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
-- close the named persistent connection SELECT dblink_disconnect('myconn');
-- should generate "missing "=" after "myconn" in connection info string" error SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE t.a > 7;
-- create a named persistent connection SELECT dblink_connect('myconn',connection_parameters());
-- put more data into our table, using named persistent connection syntax -- but truncate the actual return value so we can use diff to check for success SELECT substr(dblink_exec('myconn','INSERT INTO foo VALUES(11,''l'',''{"a11","b11","c11"}'')'),1,6);
-- let's see it SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]);
-- change some data SELECT dblink_exec('myconn','UPDATE foo SET f3[2] = ''b99'' WHERE f1 = 11');
-- let's see it SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE a = 11;
-- delete some data SELECT dblink_exec('myconn','DELETE FROM foo WHERE f1 = 11');
-- let's see it SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]) WHERE a = 11;
-- close the named persistent connection 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', connection_parameters()); SELECT * from
dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
SELECT dblink_connect('dtest2', connection_parameters()); SELECT * from
dblink_send_query('dtest2', 'select * from foo where f1 > 2 and f1 < 7') as t1;
SELECT dblink_connect('dtest3', connection_parameters()); 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[])) ORDERby f1;
-- 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
language sql strict immutable as $$ select $1[i] from generate_series(array_lower($1,1), array_upper($1,1)) as i
$$;
SELECT * FROM unnest(dblink_get_connections()) ORDERBY1;
-- test foreign data wrapper functionality CREATE ROLE regress_dblink_user;
DO $d$
BEGIN
EXECUTE $$CREATE SERVER fdtest FOREIGN DATA WRAPPER dblink_fdw
OPTIONS (dbname '$$||current_database()||$$',
port '$$||current_setting('port')||$$'
)$$;
END;
$d$;
CREATE USER MAPPING FOR public SERVER fdtest
OPTIONS (server 'localhost'); -- fail, can't specify server here CREATE USER MAPPING FOR public SERVER fdtest OPTIONS (user :'USER');
-- OAuth options are not allowed in either context ALTER SERVER fdtest OPTIONS (ADD oauth_issuer 'https://example.com'); ALTER SERVER fdtest OPTIONS (ADD oauth_client_id 'myID'); ALTER USER MAPPING FOR public SERVER fdtest
OPTIONS (ADD oauth_issuer 'https://example.com'); ALTER USER MAPPING FOR public SERVER fdtest
OPTIONS (ADD oauth_client_id 'myID');
GRANTUSAGEONFOREIGN SERVER fdtest TO regress_dblink_user; GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO regress_dblink_user;
SET SESSION AUTHORIZATION regress_dblink_user; -- should fail SELECT dblink_connect('myconn', 'fdtest'); -- should succeed SELECT dblink_connect_u('myconn', 'fdtest'); SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]);
\c - - REVOKEUSAGEONFOREIGN SERVER fdtest FROM regress_dblink_user; REVOKE EXECUTE ON FUNCTION dblink_connect_u(text, text) FROM regress_dblink_user; DROP USER regress_dblink_user; DROP USER MAPPING FOR public SERVER fdtest; DROP SERVER fdtest;
-- should fail ALTERFOREIGN DATA WRAPPER dblink_fdw OPTIONS (nonexistent 'fdw');
-- test repeated calls to dblink_connect SELECT dblink_connect(connection_parameters()); SELECT dblink_connect(connection_parameters()); SELECT dblink_disconnect();
-- test asynchronous notifications SELECT dblink_connect(connection_parameters());
SELECT notify_name, be_pid = (select t.be_pid from dblink('select pg_backend_pid()') as t(be_pid int)) AS is_self_notify, extra from dblink_get_notify();
SELECT * from dblink_get_notify();
SELECT dblink_disconnect();
-- test dropped columns in dblink_build_sql_insert, dblink_build_sql_update CREATE TEMP TABLE test_dropped
(
col1 INTNOTNULLDEFAULT111,
id SERIAL PRIMARYKEY,
col2 INTNOTNULLDEFAULT112,
col2b INTNOTNULLDEFAULT113
);
-- test local mimicry of remote GUC values that affect datatype I/O SET datestyle = ISO, MDY; SET intervalstyle = postgres; SET timezone = UTC; SELECT dblink_connect('myconn',connection_parameters()); SELECT dblink_exec('myconn', 'SET datestyle = GERMAN, DMY;');
-- single row synchronous case SELECT * FROM dblink('myconn', 'SELECT * FROM (VALUES (''12.03.2013 00:00:00+00'')) t') AS t(a timestamptz);
-- multi-row synchronous case SELECT * FROM dblink('myconn', 'SELECT * FROM
(VALUES (''12.03.201300:00:00+00''),
(''12.03.201300:00:00+00'')) t') AS t(a timestamptz);
-- single-row asynchronous case SELECT * FROM dblink_send_query('myconn', 'SELECT * FROM
(VALUES (''12.03.201300:00:00+00'')) t'); CREATE TEMPORARY TABLE result AS
(SELECT * from dblink_get_result('myconn') as t(t timestamptz)) UNIONALL
(SELECT * from dblink_get_result('myconn') as t(t timestamptz)); SELECT * FROM result; DROPTABLE result;
-- multi-row asynchronous case SELECT * FROM dblink_send_query('myconn', 'SELECT * FROM
(VALUES (''12.03.201300:00:00+00''),
(''12.03.201300:00:00+00'')) t'); CREATE TEMPORARY TABLE result AS
(SELECT * from dblink_get_result('myconn') as t(t timestamptz)) UNIONALL
(SELECT * from dblink_get_result('myconn') as t(t timestamptz)) UNIONALL
(SELECT * from dblink_get_result('myconn') as t(t timestamptz)); SELECT * FROM result; DROPTABLE result;
-- Try an ambiguous interval SELECT dblink_exec('myconn', 'SET intervalstyle = sql_standard;'); SELECT * FROM dblink('myconn', 'SELECT * FROM (VALUES (''-1 2:03:04'')) i') AS i(i interval);
-- Try swapping to another format to ensure the GUCs are tracked -- properly through a change. CREATE TEMPORARY TABLE result (t timestamptz);
SELECT dblink_exec('myconn', 'SET datestyle = ISO, MDY;'); INSERTINTO result SELECT * FROM dblink('myconn', 'SELECT * FROM (VALUES (''03.12.2013 00:00:00+00'')) t') AS t(a timestamptz);
SELECT dblink_exec('myconn', 'SET datestyle = GERMAN, DMY;'); INSERTINTO result SELECT * FROM dblink('myconn', 'SELECT * FROM (VALUES (''12.03.2013 00:00:00+00'')) t') AS t(a timestamptz);
SELECT * FROM result;
DROPTABLE result;
-- Check error throwing in dblink_fetch SELECT dblink_open('myconn','error_cursor', 'SELECT * FROM (VALUES (''1''), (''not an int'')) AS t(text);'); SELECT * FROM dblink_fetch('myconn','error_cursor', 1) AS t(i int); SELECT * FROM dblink_fetch('myconn','error_cursor', 1) AS t(i int);
-- Make sure that the local settings have retained their values in spite -- of shenanigans on the connection. SHOW datestyle; SHOW intervalstyle;
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.21Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.