Index: dblink.c
===================================================================
RCS file: /cvsroot/pgsql/contrib/dblink/dblink.c,v
retrieving revision 1.50
diff -c -r1.50 dblink.c
*** dblink.c	22 Nov 2005 18:17:04 -0000	1.50
--- dblink.c	3 Jan 2006 02:20:43 -0000
***************
*** 579,592 ****
  		/* 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))
  		{
--- 579,584 ----
***************
*** 609,614 ****
--- 601,621 ----
  		/* 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,791 ****
  		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 */
--- 785,790 ----
***************
*** 811,816 ****
--- 810,830 ----
  			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;
