|
|
@ -8,7 +8,7 @@ |
|
|
|
* Darko Prenosil <Darko.Prenosil@finteh.hr> |
|
|
|
* Darko Prenosil <Darko.Prenosil@finteh.hr> |
|
|
|
* Shridhar Daithankar <shridhar_daithankar@persistent.co.in> |
|
|
|
* 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; |
|
|
|
* ALL RIGHTS RESERVED; |
|
|
|
* |
|
|
|
* |
|
|
|
* Permission to use, copy, modify, and distribute this software and its |
|
|
|
* 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 */ |
|
|
|
/* got results, keep track of them */ |
|
|
|
funcctx->user_fctx = res; |
|
|
|
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 */ |
|
|
|
/* get a tuple descriptor for our result type */ |
|
|
|
switch (get_call_result_type(fcinfo, NULL, &tupdesc)) |
|
|
|
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 */ |
|
|
|
/* make sure we have a persistent copy of the tupdesc */ |
|
|
|
tupdesc = CreateTupleDescCopy(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 */ |
|
|
|
/* store needed metadata for subsequent calls */ |
|
|
|
attinmeta = TupleDescGetAttInMetadata(tupdesc); |
|
|
|
attinmeta = TupleDescGetAttInMetadata(tupdesc); |
|
|
|
funcctx->attinmeta = attinmeta; |
|
|
|
funcctx->attinmeta = attinmeta; |
|
|
@ -778,14 +785,6 @@ dblink_record(PG_FUNCTION_ARGS) |
|
|
|
if (freeconn) |
|
|
|
if (freeconn) |
|
|
|
PQfinish(conn); |
|
|
|
PQfinish(conn); |
|
|
|
|
|
|
|
|
|
|
|
/* fast track when no results */ |
|
|
|
|
|
|
|
if (funcctx->max_calls < 1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (res) |
|
|
|
|
|
|
|
PQclear(res); |
|
|
|
|
|
|
|
SRF_RETURN_DONE(funcctx); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!is_sql_cmd) |
|
|
|
if (!is_sql_cmd) |
|
|
|
{ |
|
|
|
{ |
|
|
|
/* get a tuple descriptor for our result type */ |
|
|
|
/* get a tuple descriptor for our result type */ |
|
|
@ -811,6 +810,21 @@ dblink_record(PG_FUNCTION_ARGS) |
|
|
|
tupdesc = CreateTupleDescCopy(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 */ |
|
|
|
/* store needed metadata for subsequent calls */ |
|
|
|
attinmeta = TupleDescGetAttInMetadata(tupdesc); |
|
|
|
attinmeta = TupleDescGetAttInMetadata(tupdesc); |
|
|
|
funcctx->attinmeta = attinmeta; |
|
|
|
funcctx->attinmeta = attinmeta; |
|
|
|