1CREATE EXTENSION dblink;
2
3-- want context for notices
4\set SHOW_CONTEXT always
5
6CREATE TABLE foo(f1 int, f2 text, f3 text[], primary key (f1,f2));
7INSERT INTO foo VALUES (0,'a','{"a0","b0","c0"}');
8INSERT INTO foo VALUES (1,'b','{"a1","b1","c1"}');
9INSERT INTO foo VALUES (2,'c','{"a2","b2","c2"}');
10INSERT INTO foo VALUES (3,'d','{"a3","b3","c3"}');
11INSERT INTO foo VALUES (4,'e','{"a4","b4","c4"}');
12INSERT INTO foo VALUES (5,'f','{"a5","b5","c5"}');
13INSERT INTO foo VALUES (6,'g','{"a6","b6","c6"}');
14INSERT INTO foo VALUES (7,'h','{"a7","b7","c7"}');
15INSERT INTO foo VALUES (8,'i','{"a8","b8","c8"}');
16INSERT INTO foo VALUES (9,'j','{"a9","b9","c9"}');
17
18-- misc utilities
19
20-- list the primary key fields
21SELECT *
22FROM dblink_get_pkey('foo');
23
24-- build an insert statement based on a local tuple,
25-- replacing the primary key values with new ones
26SELECT dblink_build_sql_insert('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
27-- too many pk fields, should fail
28SELECT dblink_build_sql_insert('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
29
30-- build an update statement based on a local tuple,
31-- replacing the primary key values with new ones
32SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
33-- too many pk fields, should fail
34SELECT dblink_build_sql_update('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
35
36-- build a delete statement based on a local tuple,
37SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}');
38-- too many pk fields, should fail
39SELECT dblink_build_sql_delete('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
40
41-- repeat the test for table with primary key index with included columns
42CREATE TABLE foo_1(f1 int, f2 text, f3 text[], primary key (f1,f2) include (f3));
43INSERT INTO foo_1 VALUES (0,'a','{"a0","b0","c0"}');
44INSERT INTO foo_1 VALUES (1,'b','{"a1","b1","c1"}');
45INSERT INTO foo_1 VALUES (2,'c','{"a2","b2","c2"}');
46INSERT INTO foo_1 VALUES (3,'d','{"a3","b3","c3"}');
47INSERT INTO foo_1 VALUES (4,'e','{"a4","b4","c4"}');
48INSERT INTO foo_1 VALUES (5,'f','{"a5","b5","c5"}');
49INSERT INTO foo_1 VALUES (6,'g','{"a6","b6","c6"}');
50INSERT INTO foo_1 VALUES (7,'h','{"a7","b7","c7"}');
51INSERT INTO foo_1 VALUES (8,'i','{"a8","b8","c8"}');
52INSERT INTO foo_1 VALUES (9,'j','{"a9","b9","c9"}');
53
54-- misc utilities
55
56-- list the primary key fields
57SELECT *
58FROM dblink_get_pkey('foo_1');
59
60-- build an insert statement based on a local tuple,
61-- replacing the primary key values with new ones
62SELECT dblink_build_sql_insert('foo_1','1 2',2,'{"0", "a"}','{"99", "xyz"}');
63-- too many pk fields, should fail
64SELECT dblink_build_sql_insert('foo_1','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
65
66-- build an update statement based on a local tuple,
67-- replacing the primary key values with new ones
68SELECT dblink_build_sql_update('foo_1','1 2',2,'{"0", "a"}','{"99", "xyz"}');
69-- too many pk fields, should fail
70SELECT dblink_build_sql_update('foo_1','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
71
72-- build a delete statement based on a local tuple,
73SELECT dblink_build_sql_delete('foo_1','1 2',2,'{"0", "a"}');
74-- too many pk fields, should fail
75SELECT dblink_build_sql_delete('foo_1','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
76
77DROP TABLE foo_1;
78
79-- retest using a quoted and schema qualified table
80CREATE SCHEMA "MySchema";
81CREATE TABLE "MySchema"."Foo"(f1 int, f2 text, f3 text[], primary key (f1,f2));
82INSERT INTO "MySchema"."Foo" VALUES (0,'a','{"a0","b0","c0"}');
83
84-- list the primary key fields
85SELECT *
86FROM dblink_get_pkey('"MySchema"."Foo"');
87
88-- build an insert statement based on a local tuple,
89-- replacing the primary key values with new ones
90SELECT dblink_build_sql_insert('"MySchema"."Foo"','1 2',2,'{"0", "a"}','{"99", "xyz"}');
91
92-- build an update statement based on a local tuple,
93-- replacing the primary key values with new ones
94SELECT dblink_build_sql_update('"MySchema"."Foo"','1 2',2,'{"0", "a"}','{"99", "xyz"}');
95
96-- build a delete statement based on a local tuple,
97SELECT dblink_build_sql_delete('"MySchema"."Foo"','1 2',2,'{"0", "a"}');
98
99CREATE FUNCTION connection_parameters() RETURNS text LANGUAGE SQL AS $f$
100       SELECT $$dbname='$$||current_database()||$$' port=$$||current_setting('port');
101$f$;
102
103-- regular old dblink
104SELECT *
105FROM dblink(connection_parameters(),'SELECT * FROM foo') AS t(a int, b text, c text[])
106WHERE t.a > 7;
107
108-- should generate "connection not available" error
109SELECT *
110FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
111WHERE t.a > 7;
112
113-- The first-level connection's backend will crash on exit given OpenLDAP
114-- [2.4.24, 2.4.31].  We won't see evidence of any crash until the victim
115-- process terminates and the postmaster responds.  If process termination
116-- entails writing a core dump, that can take awhile.  Wait for the process to
117-- vanish.  At that point, the postmaster has called waitpid() on the crashed
118-- process, and it will accept no new connections until it has reinitialized
119-- the cluster.  (We can't exploit pg_stat_activity, because the crash happens
120-- after the backend updates shared memory to reflect its impending exit.)
121DO $pl$
122DECLARE
123	detail text;
124BEGIN
125	PERFORM wait_pid(crash_pid)
126	FROM dblink(connection_parameters(), $$
127		SELECT pg_backend_pid() FROM dblink(
128			'service=test_ldap '||connection_parameters(),
129			-- This string concatenation is a hack to shoehorn a
130			-- set_pgservicefile call into the SQL statement.
131			'SELECT 1' || set_pgservicefile('pg_service.conf')
132		) t(c int)
133	$$) AS t(crash_pid int);
134EXCEPTION WHEN OTHERS THEN
135	GET STACKED DIAGNOSTICS detail = PG_EXCEPTION_DETAIL;
136	-- Expected error in a non-LDAP build.
137	IF NOT detail LIKE 'syntax error in service file%' THEN RAISE; END IF;
138END
139$pl$;
140
141-- create a persistent connection
142SELECT dblink_connect(connection_parameters());
143
144-- use the persistent connection
145SELECT *
146FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
147WHERE t.a > 7;
148
149-- open a cursor with bad SQL and fail_on_error set to false
150SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foobar',false);
151
152-- reset remote transaction state
153SELECT dblink_exec('ABORT');
154
155-- open a cursor
156SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foo');
157
158-- close the cursor
159SELECT dblink_close('rmt_foo_cursor',false);
160
161-- open the cursor again
162SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foo');
163
164-- fetch some data
165SELECT *
166FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
167
168SELECT *
169FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
170
171-- this one only finds two rows left
172SELECT *
173FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
174
175-- intentionally botch a fetch
176SELECT *
177FROM dblink_fetch('rmt_foobar_cursor',4,false) AS t(a int, b text, c text[]);
178
179-- reset remote transaction state
180SELECT dblink_exec('ABORT');
181
182-- close the wrong cursor
183SELECT dblink_close('rmt_foobar_cursor',false);
184
185-- should generate 'cursor "rmt_foo_cursor" not found' error
186SELECT *
187FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
188
189-- this time, 'cursor "rmt_foo_cursor" not found' as a notice
190SELECT *
191FROM dblink_fetch('rmt_foo_cursor',4,false) AS t(a int, b text, c text[]);
192
193-- close the persistent connection
194SELECT dblink_disconnect();
195
196-- should generate "connection not available" error
197SELECT *
198FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
199WHERE t.a > 7;
200
201-- put more data into our table, first using arbitrary connection syntax
202-- but truncate the actual return value so we can use diff to check for success
203SELECT substr(dblink_exec(connection_parameters(),'INSERT INTO foo VALUES(10,''k'',''{"a10","b10","c10"}'')'),1,6);
204
205-- create a persistent connection
206SELECT dblink_connect(connection_parameters());
207
208-- put more data into our table, using persistent connection syntax
209-- but truncate the actual return value so we can use diff to check for success
210SELECT substr(dblink_exec('INSERT INTO foo VALUES(11,''l'',''{"a11","b11","c11"}'')'),1,6);
211
212-- let's see it
213SELECT *
214FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]);
215
216-- bad remote select
217SELECT *
218FROM dblink('SELECT * FROM foobar',false) AS t(a int, b text, c text[]);
219
220-- change some data
221SELECT dblink_exec('UPDATE foo SET f3[2] = ''b99'' WHERE f1 = 11');
222
223-- let's see it
224SELECT *
225FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
226WHERE a = 11;
227
228-- botch a change to some other data
229SELECT dblink_exec('UPDATE foobar SET f3[2] = ''b99'' WHERE f1 = 11',false);
230
231-- delete some data
232SELECT dblink_exec('DELETE FROM foo WHERE f1 = 11');
233
234-- let's see it
235SELECT *
236FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
237WHERE a = 11;
238
239-- close the persistent connection
240SELECT dblink_disconnect();
241
242--
243-- tests for the new named persistent connection syntax
244--
245
246-- should generate "missing "=" after "myconn" in connection info string" error
247SELECT *
248FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
249WHERE t.a > 7;
250
251-- create a named persistent connection
252SELECT dblink_connect('myconn',connection_parameters());
253
254-- use the named persistent connection
255SELECT *
256FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
257WHERE t.a > 7;
258
259-- use the named persistent connection, but get it wrong
260SELECT *
261FROM dblink('myconn','SELECT * FROM foobar',false) AS t(a int, b text, c text[])
262WHERE t.a > 7;
263
264-- create a second named persistent connection
265-- should error with "duplicate connection name"
266SELECT dblink_connect('myconn',connection_parameters());
267
268-- create a second named persistent connection with a new name
269SELECT dblink_connect('myconn2',connection_parameters());
270
271-- use the second named persistent connection
272SELECT *
273FROM dblink('myconn2','SELECT * FROM foo') AS t(a int, b text, c text[])
274WHERE t.a > 7;
275
276-- close the second named persistent connection
277SELECT dblink_disconnect('myconn2');
278
279-- open a cursor incorrectly
280SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foobar',false);
281
282-- reset remote transaction state
283SELECT dblink_exec('myconn','ABORT');
284
285-- test opening cursor in a transaction
286SELECT dblink_exec('myconn','BEGIN');
287
288-- an open transaction will prevent dblink_open() from opening its own
289SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foo');
290
291-- this should not commit the transaction because the client opened it
292SELECT dblink_close('myconn','rmt_foo_cursor');
293
294-- this should succeed because we have an open transaction
295SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
296
297-- commit remote transaction
298SELECT dblink_exec('myconn','COMMIT');
299
300-- test automatic transactions for multiple cursor opens
301SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foo');
302
303-- the second cursor
304SELECT dblink_open('myconn','rmt_foo_cursor2','SELECT * FROM foo');
305
306-- this should not commit the transaction
307SELECT dblink_close('myconn','rmt_foo_cursor2');
308
309-- this should succeed because we have an open transaction
310SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
311
312-- this should commit the transaction
313SELECT dblink_close('myconn','rmt_foo_cursor');
314
315-- this should fail because there is no open transaction
316SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
317
318-- reset remote transaction state
319SELECT dblink_exec('myconn','ABORT');
320
321-- open a cursor
322SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foo');
323
324-- fetch some data
325SELECT *
326FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
327
328SELECT *
329FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
330
331-- this one only finds three rows left
332SELECT *
333FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
334
335-- fetch some data incorrectly
336SELECT *
337FROM dblink_fetch('myconn','rmt_foobar_cursor',4,false) AS t(a int, b text, c text[]);
338
339-- reset remote transaction state
340SELECT dblink_exec('myconn','ABORT');
341
342-- should generate 'cursor "rmt_foo_cursor" not found' error
343SELECT *
344FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
345
346-- close the named persistent connection
347SELECT dblink_disconnect('myconn');
348
349-- should generate "missing "=" after "myconn" in connection info string" error
350SELECT *
351FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
352WHERE t.a > 7;
353
354-- create a named persistent connection
355SELECT dblink_connect('myconn',connection_parameters());
356
357-- put more data into our table, using named persistent connection syntax
358-- but truncate the actual return value so we can use diff to check for success
359SELECT substr(dblink_exec('myconn','INSERT INTO foo VALUES(11,''l'',''{"a11","b11","c11"}'')'),1,6);
360
361-- let's see it
362SELECT *
363FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]);
364
365-- change some data
366SELECT dblink_exec('myconn','UPDATE foo SET f3[2] = ''b99'' WHERE f1 = 11');
367
368-- let's see it
369SELECT *
370FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
371WHERE a = 11;
372
373-- delete some data
374SELECT dblink_exec('myconn','DELETE FROM foo WHERE f1 = 11');
375
376-- let's see it
377SELECT *
378FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
379WHERE a = 11;
380
381-- close the named persistent connection
382SELECT dblink_disconnect('myconn');
383
384-- close the named persistent connection again
385-- should get 'connection "myconn" not available' error
386SELECT dblink_disconnect('myconn');
387
388-- test asynchronous queries
389SELECT dblink_connect('dtest1', connection_parameters());
390SELECT * from
391 dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
392
393SELECT dblink_connect('dtest2', connection_parameters());
394SELECT * from
395 dblink_send_query('dtest2', 'select * from foo where f1 > 2 and f1 < 7') as t1;
396
397SELECT dblink_connect('dtest3', connection_parameters());
398SELECT * from
399 dblink_send_query('dtest3', 'select * from foo where f1 > 6') as t1;
400
401CREATE TEMPORARY TABLE result AS
402(SELECT * from dblink_get_result('dtest1') as t1(f1 int, f2 text, f3 text[]))
403UNION
404(SELECT * from dblink_get_result('dtest2') as t2(f1 int, f2 text, f3 text[]))
405UNION
406(SELECT * from dblink_get_result('dtest3') as t3(f1 int, f2 text, f3 text[]))
407ORDER by f1;
408
409-- dblink_get_connections returns an array with elements in a machine-dependent
410-- ordering, so we must resort to unnesting and sorting for a stable result
411create function unnest(anyarray) returns setof anyelement
412language sql strict immutable as $$
413select $1[i] from generate_series(array_lower($1,1), array_upper($1,1)) as i
414$$;
415
416SELECT * FROM unnest(dblink_get_connections()) ORDER BY 1;
417
418SELECT dblink_is_busy('dtest1');
419
420SELECT dblink_disconnect('dtest1');
421SELECT dblink_disconnect('dtest2');
422SELECT dblink_disconnect('dtest3');
423
424SELECT * from result;
425
426SELECT dblink_connect('dtest1', connection_parameters());
427SELECT * from
428 dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
429
430SELECT dblink_cancel_query('dtest1');
431SELECT dblink_error_message('dtest1');
432SELECT dblink_disconnect('dtest1');
433
434-- test foreign data wrapper functionality
435CREATE ROLE regress_dblink_user;
436DO $d$
437    BEGIN
438        EXECUTE $$CREATE SERVER fdtest FOREIGN DATA WRAPPER dblink_fdw
439            OPTIONS (dbname '$$||current_database()||$$',
440                     port '$$||current_setting('port')||$$'
441            )$$;
442    END;
443$d$;
444
445CREATE USER MAPPING FOR public SERVER fdtest
446  OPTIONS (server 'localhost');  -- fail, can't specify server here
447CREATE USER MAPPING FOR public SERVER fdtest OPTIONS (user :'USER');
448
449GRANT USAGE ON FOREIGN SERVER fdtest TO regress_dblink_user;
450GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO regress_dblink_user;
451
452SET SESSION AUTHORIZATION regress_dblink_user;
453-- should fail
454SELECT dblink_connect('myconn', 'fdtest');
455-- should succeed
456SELECT dblink_connect_u('myconn', 'fdtest');
457SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]);
458
459\c - -
460REVOKE USAGE ON FOREIGN SERVER fdtest FROM regress_dblink_user;
461REVOKE EXECUTE ON FUNCTION dblink_connect_u(text, text) FROM regress_dblink_user;
462DROP USER regress_dblink_user;
463DROP USER MAPPING FOR public SERVER fdtest;
464DROP SERVER fdtest;
465
466-- test asynchronous notifications
467SELECT dblink_connect(connection_parameters());
468
469--should return listen
470SELECT dblink_exec('LISTEN regression');
471--should return listen
472SELECT dblink_exec('LISTEN foobar');
473
474SELECT dblink_exec('NOTIFY regression');
475SELECT dblink_exec('NOTIFY foobar');
476
477SELECT 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();
478
479SELECT * from dblink_get_notify();
480
481SELECT dblink_disconnect();
482
483-- test dropped columns in dblink_build_sql_insert, dblink_build_sql_update
484CREATE TEMP TABLE test_dropped
485(
486	col1 INT NOT NULL DEFAULT 111,
487	id SERIAL PRIMARY KEY,
488	col2 INT NOT NULL DEFAULT 112,
489	col2b INT NOT NULL DEFAULT 113
490);
491
492INSERT INTO test_dropped VALUES(default);
493
494ALTER TABLE test_dropped
495	DROP COLUMN col1,
496	DROP COLUMN col2,
497	ADD COLUMN col3 VARCHAR(10) NOT NULL DEFAULT 'foo',
498	ADD COLUMN col4 INT NOT NULL DEFAULT 42;
499
500SELECT dblink_build_sql_insert('test_dropped', '1', 1,
501                               ARRAY['1'::TEXT], ARRAY['2'::TEXT]);
502
503SELECT dblink_build_sql_update('test_dropped', '1', 1,
504                               ARRAY['1'::TEXT], ARRAY['2'::TEXT]);
505
506SELECT dblink_build_sql_delete('test_dropped', '1', 1,
507                               ARRAY['2'::TEXT]);
508
509-- test local mimicry of remote GUC values that affect datatype I/O
510SET datestyle = ISO, MDY;
511SET intervalstyle = postgres;
512SET timezone = UTC;
513SELECT dblink_connect('myconn',connection_parameters());
514SELECT dblink_exec('myconn', 'SET datestyle = GERMAN, DMY;');
515
516-- single row synchronous case
517SELECT *
518FROM dblink('myconn',
519    'SELECT * FROM (VALUES (''12.03.2013 00:00:00+00'')) t')
520  AS t(a timestamptz);
521
522-- multi-row synchronous case
523SELECT *
524FROM dblink('myconn',
525    'SELECT * FROM
526     (VALUES (''12.03.2013 00:00:00+00''),
527             (''12.03.2013 00:00:00+00'')) t')
528  AS t(a timestamptz);
529
530-- single-row asynchronous case
531SELECT *
532FROM dblink_send_query('myconn',
533    'SELECT * FROM
534     (VALUES (''12.03.2013 00:00:00+00'')) t');
535CREATE TEMPORARY TABLE result AS
536(SELECT * from dblink_get_result('myconn') as t(t timestamptz))
537UNION ALL
538(SELECT * from dblink_get_result('myconn') as t(t timestamptz));
539SELECT * FROM result;
540DROP TABLE result;
541
542-- multi-row asynchronous case
543SELECT *
544FROM dblink_send_query('myconn',
545    'SELECT * FROM
546     (VALUES (''12.03.2013 00:00:00+00''),
547             (''12.03.2013 00:00:00+00'')) t');
548CREATE TEMPORARY TABLE result AS
549(SELECT * from dblink_get_result('myconn') as t(t timestamptz))
550UNION ALL
551(SELECT * from dblink_get_result('myconn') as t(t timestamptz))
552UNION ALL
553(SELECT * from dblink_get_result('myconn') as t(t timestamptz));
554SELECT * FROM result;
555DROP TABLE result;
556
557-- Try an ambiguous interval
558SELECT dblink_exec('myconn', 'SET intervalstyle = sql_standard;');
559SELECT *
560FROM dblink('myconn',
561    'SELECT * FROM (VALUES (''-1 2:03:04'')) i')
562  AS i(i interval);
563
564-- Try swapping to another format to ensure the GUCs are tracked
565-- properly through a change.
566CREATE TEMPORARY TABLE result (t timestamptz);
567
568SELECT dblink_exec('myconn', 'SET datestyle = ISO, MDY;');
569INSERT INTO result
570  SELECT *
571  FROM dblink('myconn',
572              'SELECT * FROM (VALUES (''03.12.2013 00:00:00+00'')) t')
573    AS t(a timestamptz);
574
575SELECT dblink_exec('myconn', 'SET datestyle = GERMAN, DMY;');
576INSERT INTO result
577  SELECT *
578  FROM dblink('myconn',
579              'SELECT * FROM (VALUES (''12.03.2013 00:00:00+00'')) t')
580    AS t(a timestamptz);
581
582SELECT * FROM result;
583
584DROP TABLE result;
585
586-- Check error throwing in dblink_fetch
587SELECT dblink_open('myconn','error_cursor',
588       'SELECT * FROM (VALUES (''1''), (''not an int'')) AS t(text);');
589SELECT *
590FROM dblink_fetch('myconn','error_cursor', 1) AS t(i int);
591SELECT *
592FROM dblink_fetch('myconn','error_cursor', 1) AS t(i int);
593
594-- Make sure that the local settings have retained their values in spite
595-- of shenanigans on the connection.
596SHOW datestyle;
597SHOW intervalstyle;
598
599-- Clean up GUC-setting tests
600SELECT dblink_disconnect('myconn');
601RESET datestyle;
602RESET intervalstyle;
603RESET timezone;
604