]> granicus.if.org Git - postgresql/commitdiff
When the remote query result has a different number of columns
authorJoe Conway <mail@joeconway.com>
Tue, 3 Jan 2006 23:45:52 +0000 (23:45 +0000)
committerJoe Conway <mail@joeconway.com>
Tue, 3 Jan 2006 23:45:52 +0000 (23:45 +0000)
than the local query specifies (e.g. in the FROM clause),
throw an ERROR (instead of crashing). Fix for bug #2129 reported
by Akio Iwaasa.

contrib/dblink/README.dblink
contrib/dblink/dblink.c
contrib/dblink/dblink.h
contrib/dblink/doc/cursor

index 22db35049139c447d503d26bf019aaee74637f35..9e1bdba6cba6d974223618a8366057e60d53a384 100644 (file)
@@ -8,7 +8,7 @@
  * Darko Prenosil <Darko.Prenosil@finteh.hr>
  * Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
  *
- * Copyright (c) 2001-2005, PostgreSQL Global Development Group
+ * Copyright (c) 2001-2006, PostgreSQL Global Development Group
  * ALL RIGHTS RESERVED;
  * 
  * Permission to use, copy, modify, and distribute this software and its
index 4da66a4b4d9b334f258968fc8a7d68c344b0c1a4..4fd17c3227158b662c4e25cdd7981d8a91b62187 100644 (file)
@@ -8,7 +8,7 @@
  * Darko Prenosil <Darko.Prenosil@finteh.hr>
  * Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
  *
- * Copyright (c) 2001-2005, PostgreSQL Global Development Group
+ * Copyright (c) 2001-2006, PostgreSQL Global Development Group
  * ALL RIGHTS RESERVED;
  *
  * Permission to use, copy, modify, and distribute this software and its
@@ -579,14 +579,6 @@ dblink_fetch(PG_FUNCTION_ARGS)
                /* got results, keep track of them */
                funcctx->user_fctx = res;
 
-               /* fast track when no results */
-               if (funcctx->max_calls < 1)
-               {
-                       if (res)
-                               PQclear(res);
-                       SRF_RETURN_DONE(funcctx);
-               }
-
                /* get a tuple descriptor for our result type */
                switch (get_call_result_type(fcinfo, NULL, &tupdesc))
                {
@@ -609,6 +601,21 @@ dblink_fetch(PG_FUNCTION_ARGS)
                /* make sure we have a persistent copy of the tupdesc */
                tupdesc = CreateTupleDescCopy(tupdesc);
 
+               /* check result and tuple descriptor have the same number of columns */
+               if (PQnfields(res) != tupdesc->natts)
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_DATATYPE_MISMATCH),
+                               errmsg("remote query result rowtype does not match "
+                                               "the specified FROM clause rowtype")));
+
+               /* fast track when no results */
+               if (funcctx->max_calls < 1)
+               {
+                       if (res)
+                               PQclear(res);
+                       SRF_RETURN_DONE(funcctx);
+               }
+
                /* store needed metadata for subsequent calls */
                attinmeta = TupleDescGetAttInMetadata(tupdesc);
                funcctx->attinmeta = attinmeta;
@@ -778,14 +785,6 @@ dblink_record(PG_FUNCTION_ARGS)
                if (freeconn)
                        PQfinish(conn);
 
-               /* fast track when no results */
-               if (funcctx->max_calls < 1)
-               {
-                       if (res)
-                               PQclear(res);
-                       SRF_RETURN_DONE(funcctx);
-               }
-
                if (!is_sql_cmd)
                {
                        /* get a tuple descriptor for our result type */
@@ -811,6 +810,21 @@ dblink_record(PG_FUNCTION_ARGS)
                        tupdesc = CreateTupleDescCopy(tupdesc);
                }
 
+               /* check result and tuple descriptor have the same number of columns */
+               if (PQnfields(res) != tupdesc->natts)
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_DATATYPE_MISMATCH),
+                               errmsg("remote query result rowtype does not match "
+                                               "the specified FROM clause rowtype")));
+
+               /* fast track when no results */
+               if (funcctx->max_calls < 1)
+               {
+                       if (res)
+                               PQclear(res);
+                       SRF_RETURN_DONE(funcctx);
+               }
+
                /* store needed metadata for subsequent calls */
                attinmeta = TupleDescGetAttInMetadata(tupdesc);
                funcctx->attinmeta = attinmeta;
index 63d6d525db9519bf5f14122b34cbb26c3cbf1d39..8f2c9ff4c1f1714554cf0d84f247df4929002416 100644 (file)
@@ -8,7 +8,7 @@
  * Darko Prenosil <Darko.Prenosil@finteh.hr>
  * Shridhar Daithankar <shridhar_daithankar@persistent.co.in>
  *
- * Copyright (c) 2001-2005, PostgreSQL Global Development Group
+ * Copyright (c) 2001-2006, PostgreSQL Global Development Group
  * ALL RIGHTS RESERVED;
  *
  * Permission to use, copy, modify, and distribute this software and its
index b989fcb69cc5c810f73552cf739b89b4f268929c..321c823e211353e3d3be900fa02ca014196c7a73 100644 (file)
@@ -92,6 +92,13 @@ Outputs
 
   Returns setof record
 
+Note
+
+  On a mismatch between the number of return fields as specified in the FROM
+  clause, and the actual number of fields returned by the remote cursor, an
+  ERROR will be thrown. In this event, the remote cursor is still advanced
+  by as many rows as it would have been if the ERROR had not occurred.
+
 Example usage
 
 test=# select dblink_connect('dbname=postgres');