When the remote query result has a different number of columns
authorJoe Conway <[email protected]>
Tue, 3 Jan 2006 23:47:24 +0000 (23:47 +0000)
committerJoe Conway <[email protected]>
Tue, 3 Jan 2006 23:47:24 +0000 (23:47 +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 <[email protected]>
  * Shridhar Daithankar <[email protected]>
  *
- * 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 5de15144590d1b691721e8dda2360226a9438042..313c32f2d0037424dc9ba9f585b89ef2b76dbb0b 100644 (file)
@@ -8,7 +8,7 @@
  * Darko Prenosil <[email protected]>
  * Shridhar Daithankar <[email protected]>
  *
- * 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
@@ -547,14 +547,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);
-       }
-
        /* check typtype to see if we have a predetermined return type */
        functypeid = get_func_rettype(funcid);
        functyptype = get_typtype(functypeid);
@@ -577,6 +569,21 @@ dblink_fetch(PG_FUNCTION_ARGS)
            /* shouldn't happen */
            elog(ERROR, "return type must be a row type");
 
+       /* 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;
@@ -749,14 +756,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);
-       }
-
        /* check typtype to see if we have a predetermined return type */
        functypeid = get_func_rettype(funcid);
        functyptype = get_typtype(functypeid);
@@ -782,6 +781,21 @@ dblink_record(PG_FUNCTION_ARGS)
                elog(ERROR, "return type must be a row type");
        }
 
+       /* 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 <[email protected]>
  * Shridhar Daithankar <[email protected]>
  *
- * 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 23a3ce89ba55b4e8b5860455a59f4f7237a48928..1220d85ea32171bcb074a6e22b265c617c34c09d 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=template1');