When the remote query result has a different number of columns
authorJoe Conway
Tue, 3 Jan 2006 23:45:52 +0000 (23:45 +0000)
committerJoe Conway
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 
  * Shridhar Daithankar 
  *
- * 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 
  * Shridhar Daithankar 
  *
- * 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 
  * Shridhar Daithankar 
  *
- * 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');