From: Joe Conway Date: Tue, 3 Jan 2006 23:48:04 +0000 (+0000) Subject: When the remote query result has a different number of columns X-Git-Tag: REL7_4_11~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fcacfc96a2e13e1abe920f4a94a2fc51b5853c71;p=thirdparty%2Fpostgresql.git When the remote query result has a different number of columns 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. --- diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c index 3fea501b60c..dbaebc88552 100644 --- a/contrib/dblink/dblink.c +++ b/contrib/dblink/dblink.c @@ -446,10 +446,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) - SRF_RETURN_DONE(funcctx); - /* check typtype to see if we have a predetermined return type */ functypeid = get_func_rettype(funcid); functyptype = get_typtype(functypeid); @@ -474,6 +470,22 @@ dblink_fetch(PG_FUNCTION_ARGS) /* store needed metadata for subsequent calls */ slot = TupleDescGetSlot(tupdesc); funcctx->slot = slot; + + /* 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); + } + attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; @@ -617,10 +629,6 @@ dblink_record(PG_FUNCTION_ARGS) if (freeconn && PG_NARGS() == 2) PQfinish(conn); - /* fast track when no results */ - if (funcctx->max_calls < 1) - SRF_RETURN_DONE(funcctx); - /* check typtype to see if we have a predetermined return type */ functypeid = get_func_rettype(funcid); functyptype = get_typtype(functypeid); @@ -648,6 +656,22 @@ dblink_record(PG_FUNCTION_ARGS) /* store needed metadata for subsequent calls */ slot = TupleDescGetSlot(tupdesc); funcctx->slot = slot; + + /* 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); + } + attinmeta = TupleDescGetAttInMetadata(tupdesc); funcctx->attinmeta = attinmeta; diff --git a/contrib/dblink/doc/cursor b/contrib/dblink/doc/cursor index 7c9cc3cde25..bf591a4d6e5 100644 --- a/contrib/dblink/doc/cursor +++ b/contrib/dblink/doc/cursor @@ -79,6 +79,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');