Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3cd8411

Browse files
committed
When returning type "record", replace use of pgresultGetTupleDesc
with ReturnSetInfo->expectedDesc. This allows custom datatypes(e.g. from tsearch2) to be returned at runtime. Previous behaviordepended on the type oid to match between the remote and localdatabase, which obviously doesn't work well for custom types.Per report from Mark Gibson.
1 parent64a2e1f commit3cd8411

File tree

1 file changed

+22
-60
lines changed

1 file changed

+22
-60
lines changed

‎contrib/dblink/dblink.c

Lines changed: 22 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ static char *quote_ident_cstr(char *rawstr);
8282
staticint16get_attnum_pk_pos(int16*pkattnums,int16pknumatts,int16key);
8383
staticHeapTupleget_tuple_of_interest(Oidrelid,int16*pkattnums,int16pknumatts,char**src_pkattvals);
8484
staticOidget_relid_from_relname(text*relname_text);
85-
staticTupleDescpgresultGetTupleDesc(PGresult*res);
8685
staticchar*generate_relation_name(Oidrelid);
8786

8887
/* Global */
@@ -395,6 +394,7 @@ dblink_fetch(PG_FUNCTION_ARGS)
395394
StringInfostr=makeStringInfo();
396395
char*curname=NULL;
397396
inthowmany=0;
397+
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
398398

399399
if (PG_NARGS()==3)
400400
{
@@ -457,7 +457,16 @@ dblink_fetch(PG_FUNCTION_ARGS)
457457
if (functyptype=='c')
458458
tupdesc=TypeGetTupleDesc(functypeid,NIL);
459459
elseif (functyptype=='p'&&functypeid==RECORDOID)
460-
tupdesc=pgresultGetTupleDesc(res);
460+
{
461+
if (!rsinfo|| !IsA(rsinfo,ReturnSetInfo))
462+
ereport(ERROR,
463+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
464+
errmsg("function returning record called in context "
465+
"that cannot accept type record")));
466+
467+
/* get the requested return tuple description */
468+
tupdesc=CreateTupleDescCopy(rsinfo->expectedDesc);
469+
}
461470
else
462471
/* shouldn't happen */
463472
elog(ERROR,"return type must be a row type");
@@ -550,6 +559,7 @@ dblink_record(PG_FUNCTION_ARGS)
550559
char*sql=NULL;
551560
char*conname=NULL;
552561
remoteConn*rcon=NULL;
562+
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
553563

554564
/* create a function context for cross-call persistence */
555565
funcctx=SRF_FIRSTCALL_INIT();
@@ -620,7 +630,16 @@ dblink_record(PG_FUNCTION_ARGS)
620630
if (functyptype=='c')
621631
tupdesc=TypeGetTupleDesc(functypeid,NIL);
622632
elseif (functyptype=='p'&&functypeid==RECORDOID)
623-
tupdesc=pgresultGetTupleDesc(res);
633+
{
634+
if (!rsinfo|| !IsA(rsinfo,ReturnSetInfo))
635+
ereport(ERROR,
636+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
637+
errmsg("function returning record called in context "
638+
"that cannot accept type record")));
639+
640+
/* get the requested return tuple description */
641+
tupdesc=CreateTupleDescCopy(rsinfo->expectedDesc);
642+
}
624643
else
625644
/* shouldn't happen */
626645
elog(ERROR,"return type must be a row type");
@@ -1803,63 +1822,6 @@ get_relid_from_relname(text *relname_text)
18031822
returnrelid;
18041823
}
18051824

1806-
staticTupleDesc
1807-
pgresultGetTupleDesc(PGresult*res)
1808-
{
1809-
intnatts;
1810-
AttrNumberattnum;
1811-
TupleDescdesc;
1812-
char*attname;
1813-
int32atttypmod;
1814-
intattdim;
1815-
boolattisset;
1816-
Oidatttypid;
1817-
inti;
1818-
1819-
/*
1820-
* allocate a new tuple descriptor
1821-
*/
1822-
natts=PQnfields(res);
1823-
if (natts<1)
1824-
/* shouldn't happen */
1825-
elog(ERROR,"cannot create a description for empty results");
1826-
1827-
desc=CreateTemplateTupleDesc(natts, false);
1828-
1829-
attnum=0;
1830-
1831-
for (i=0;i<natts;i++)
1832-
{
1833-
/*
1834-
* for each field, get the name and type information from the
1835-
* query result and have TupleDescInitEntry fill in the attribute
1836-
* information we need.
1837-
*/
1838-
attnum++;
1839-
1840-
attname=PQfname(res,i);
1841-
atttypid=PQftype(res,i);
1842-
atttypmod=PQfmod(res,i);
1843-
1844-
if (PQfsize(res,i)!=get_typlen(atttypid))
1845-
ereport(ERROR,
1846-
(errcode(ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH),
1847-
errmsg("field size mismatch"),
1848-
errdetail("Size of remote field \"%s\" does not match " \
1849-
"size of local type \"%s\".",attname,
1850-
format_type_with_typemod(atttypid,
1851-
atttypmod))));
1852-
1853-
attdim=0;
1854-
attisset= false;
1855-
1856-
TupleDescInitEntry(desc,attnum,attname,atttypid,
1857-
atttypmod,attdim,attisset);
1858-
}
1859-
1860-
returndesc;
1861-
}
1862-
18631825
/*
18641826
* generate_relation_name - copied from ruleutils.c
18651827
*Compute the name to display for a relation specified by OID

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp