summaryrefslogtreecommitdiff
path: root/contrib/dblink/sql
diff options
context:
space:
mode:
authorTom Lane2013-03-22 19:22:15 +0000
committerTom Lane2013-03-22 19:22:54 +0000
commit8a3b6772aedbd95557ab1fc489ddf007ac9d405d (patch)
tree006e57755d29f2b55620ad7e617a71670533351a /contrib/dblink/sql
parent549dae0352a06a43ec664dc158556e12ec2d30e5 (diff)
Fix contrib/dblink to handle inconsistent DateStyle/IntervalStyle safely.
If the remote database's settings of these GUCs are different from ours, ambiguous datetime values may be read incorrectly. To fix, temporarily adopt the remote server's settings while we ingest a query result. This is not a complete fix, since it doesn't do anything about ambiguous values in commands sent to the remote server; but there seems little we can do about that end of it given dblink's entirely textual API for transmitted commands. Back-patch to 9.2. The hazard exists in all versions, but this patch would need more work to apply before 9.2. Given the lack of field complaints about this issue, it doesn't seem worth the effort at present. Daniel Farina and Tom Lane
Diffstat (limited to 'contrib/dblink/sql')
-rw-r--r--contrib/dblink/sql/dblink.sql96
1 files changed, 96 insertions, 0 deletions
diff --git a/contrib/dblink/sql/dblink.sql b/contrib/dblink/sql/dblink.sql
index 4f72ccf1d8e..2a107601c55 100644
--- a/contrib/dblink/sql/dblink.sql
+++ b/contrib/dblink/sql/dblink.sql
@@ -426,3 +426,99 @@ SELECT dblink_build_sql_update('test_dropped', '1', 1,
SELECT dblink_build_sql_delete('test_dropped', '1', 1,
ARRAY['2'::TEXT]);
+
+-- 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','dbname=contrib_regression');
+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.2013 00:00:00+00''),
+ (''12.03.2013 00:00:00+00'')) t')
+ AS t(a timestamptz);
+
+-- single-row asynchronous case
+SELECT *
+FROM dblink_send_query('myconn',
+ 'SELECT * FROM
+ (VALUES (''12.03.2013 00:00:00+00'')) t');
+CREATE TEMPORARY TABLE result AS
+(SELECT * from dblink_get_result('myconn') as t(t timestamptz))
+UNION ALL
+(SELECT * from dblink_get_result('myconn') as t(t timestamptz));
+SELECT * FROM result;
+DROP TABLE result;
+
+-- multi-row asynchronous case
+SELECT *
+FROM dblink_send_query('myconn',
+ 'SELECT * FROM
+ (VALUES (''12.03.2013 00:00:00+00''),
+ (''12.03.2013 00:00:00+00'')) t');
+CREATE TEMPORARY TABLE result AS
+(SELECT * from dblink_get_result('myconn') as t(t timestamptz))
+UNION ALL
+(SELECT * from dblink_get_result('myconn') as t(t timestamptz))
+UNION ALL
+(SELECT * from dblink_get_result('myconn') as t(t timestamptz));
+SELECT * FROM result;
+DROP TABLE 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;');
+INSERT INTO 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;');
+INSERT INTO result
+ SELECT *
+ FROM dblink('myconn',
+ 'SELECT * FROM (VALUES (''12.03.2013 00:00:00+00'')) t')
+ AS t(a timestamptz);
+
+SELECT * FROM result;
+
+DROP TABLE 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;
+
+-- Clean up GUC-setting tests
+SELECT dblink_disconnect('myconn');
+RESET datestyle;
+RESET intervalstyle;
+RESET timezone;