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

Commitfb22b32

Browse files
committed
Allow functions returning void or cstring to appear in FROM clause,
to make life cushy for the JDBC driver. Centralize the decision-makingthat affects this by inventing a get_type_func_class() function, ratherthan adding special cases in half a dozen places.
1 parent857e210 commitfb22b32

File tree

5 files changed

+94
-55
lines changed

5 files changed

+94
-55
lines changed

‎src/backend/access/common/tupdesc.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.106 2004/08/29 05:06:39 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.107 2004/10/20 16:04:47 tgl Exp $
1212
*
1313
* NOTES
1414
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -607,13 +607,13 @@ RelationNameGetTupleDesc(const char *relname)
607607
TupleDesc
608608
TypeGetTupleDesc(Oidtypeoid,List*colaliases)
609609
{
610-
charfunctyptype=get_typtype(typeoid);
610+
TypeFuncClassfunctypclass=get_type_func_class(typeoid);
611611
TupleDesctupdesc=NULL;
612612

613613
/*
614614
* Build a suitable tupledesc representing the output rows
615615
*/
616-
if (functyptype=='c')
616+
if (functypclass==TYPEFUNC_COMPOSITE)
617617
{
618618
/* Composite data type, e.g. a table's row type */
619619
tupdesc=CreateTupleDescCopy(lookup_rowtype_tupdesc(typeoid,-1));
@@ -643,9 +643,9 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases)
643643
tupdesc->tdtypmod=-1;
644644
}
645645
}
646-
elseif (functyptype=='b'||functyptype=='d')
646+
elseif (functypclass==TYPEFUNC_SCALAR)
647647
{
648-
/*Must be a base data type, i.e. scalar */
648+
/*Base data type, i.e. scalar */
649649
char*attname;
650650

651651
/* the alias list is required for base types */
@@ -671,7 +671,7 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases)
671671
-1,
672672
0);
673673
}
674-
elseif (typeoid==RECORDOID)
674+
elseif (functypclass==TYPEFUNC_RECORD)
675675
{
676676
/* XXX can't support this because typmod wasn't passed in ... */
677677
ereport(ERROR,

‎src/backend/executor/nodeFunctionscan.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.27 2004/09/22 17:41:51 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.28 2004/10/20 16:04:48 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -132,7 +132,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
132132
FunctionScanState*scanstate;
133133
RangeTblEntry*rte;
134134
Oidfuncrettype;
135-
charfunctyptype;
135+
TypeFuncClassfunctypclass;
136136
TupleDesctupdesc=NULL;
137137

138138
/*
@@ -184,16 +184,16 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
184184
* Now determine if the function returns a simple or composite type,
185185
* and build an appropriate tupdesc.
186186
*/
187-
functyptype=get_typtype(funcrettype);
187+
functypclass=get_type_func_class(funcrettype);
188188

189-
if (functyptype=='c')
189+
if (functypclass==TYPEFUNC_COMPOSITE)
190190
{
191191
/* Composite data type, e.g. a table's row type */
192192
tupdesc=CreateTupleDescCopy(lookup_rowtype_tupdesc(funcrettype,-1));
193193
}
194-
elseif (functyptype=='b'||functyptype=='d')
194+
elseif (functypclass==TYPEFUNC_SCALAR)
195195
{
196-
/*Must be a base data type, i.e. scalar */
196+
/*Base data type, i.e. scalar */
197197
char*attname=strVal(linitial(rte->eref->colnames));
198198

199199
tupdesc=CreateTemplateTupleDesc(1, false);
@@ -204,9 +204,8 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
204204
-1,
205205
0);
206206
}
207-
elseif (funcrettype==RECORDOID)
207+
elseif (functypclass==TYPEFUNC_RECORD)
208208
{
209-
/* Must be a pseudo type, i.e. record */
210209
tupdesc=BuildDescForRelation(rte->coldeflist);
211210
}
212211
else

‎src/backend/parser/parse_relation.c

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.100 2004/08/29 05:06:44 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.101 2004/10/20 16:04:48 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -966,7 +966,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
966966
{
967967
RangeTblEntry*rte=makeNode(RangeTblEntry);
968968
Oidfuncrettype=exprType(funcexpr);
969-
charfunctyptype;
969+
TypeFuncClassfunctypclass;
970970
Alias*alias=rangefunc->alias;
971971
List*coldeflist=rangefunc->coldeflist;
972972
Alias*eref;
@@ -1008,18 +1008,15 @@ addRangeTableEntryForFunction(ParseState *pstate,
10081008
errmsg("a column definition list is required for functions returning \"record\"")));
10091009
}
10101010

1011-
functyptype=get_typtype(funcrettype);
1011+
functypclass=get_type_func_class(funcrettype);
10121012

1013-
if (functyptype=='c')
1013+
if (functypclass==TYPEFUNC_COMPOSITE)
10141014
{
1015-
/*
1016-
* Named composite data type, i.e. a table's row type
1017-
*/
1015+
/* Composite data type, e.g. a table's row type */
10181016
Oidfuncrelid=typeidTypeRelid(funcrettype);
10191017
Relationrel;
10201018

1021-
if (!OidIsValid(funcrelid))/* shouldn't happen if typtype is
1022-
* 'c' */
1019+
if (!OidIsValid(funcrelid))/* shouldn't happen */
10231020
elog(ERROR,"invalid typrelid for complex type %u",funcrettype);
10241021

10251022
/*
@@ -1038,12 +1035,10 @@ addRangeTableEntryForFunction(ParseState *pstate,
10381035
*/
10391036
relation_close(rel,NoLock);
10401037
}
1041-
elseif (functyptype=='b'||functyptype=='d')
1038+
elseif (functypclass==TYPEFUNC_SCALAR)
10421039
{
1043-
/*
1044-
* Must be a base data type, i.e. scalar. Just add one alias
1045-
* column named for the function.
1046-
*/
1040+
/* Base data type, i.e. scalar */
1041+
/* Just add one alias column named for the function. */
10471042
if (alias&&alias->colnames!=NIL)
10481043
{
10491044
if (list_length(alias->colnames)!=1)
@@ -1056,7 +1051,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
10561051
else
10571052
eref->colnames=list_make1(makeString(eref->aliasname));
10581053
}
1059-
elseif (functyptype=='p'&&funcrettype==RECORDOID)
1054+
elseif (functypclass==TYPEFUNC_RECORD)
10601055
{
10611056
ListCell*col;
10621057

@@ -1073,8 +1068,8 @@ addRangeTableEntryForFunction(ParseState *pstate,
10731068
else
10741069
ereport(ERROR,
10751070
(errcode(ERRCODE_DATATYPE_MISMATCH),
1076-
errmsg("function \"%s\" in FROM has unsupported return type",
1077-
funcname)));
1071+
errmsg("function \"%s\" in FROM has unsupported return type %s",
1072+
funcname,format_type_be(funcrettype))));
10781073

10791074
/*----------
10801075
* Flags:
@@ -1314,9 +1309,9 @@ expandRTE(List *rtable, int rtindex, int sublevels_up,
13141309
{
13151310
/* Function RTE */
13161311
Oidfuncrettype=exprType(rte->funcexpr);
1317-
charfunctyptype=get_typtype(funcrettype);
1312+
TypeFuncClassfunctypclass=get_type_func_class(funcrettype);
13181313

1319-
if (functyptype=='c')
1314+
if (functypclass==TYPEFUNC_COMPOSITE)
13201315
{
13211316
/*
13221317
* Composite data type, i.e. a table's row type
@@ -1332,11 +1327,9 @@ expandRTE(List *rtable, int rtindex, int sublevels_up,
13321327
expandRelation(funcrelid,rte->eref,rtindex,sublevels_up,
13331328
include_dropped,colnames,colvars);
13341329
}
1335-
elseif (functyptype=='b'||functyptype=='d')
1330+
elseif (functypclass==TYPEFUNC_SCALAR)
13361331
{
1337-
/*
1338-
* Must be a base data type, i.e. scalar
1339-
*/
1332+
/* Base data type, i.e. scalar */
13401333
if (colnames)
13411334
*colnames=lappend(*colnames,
13421335
linitial(rte->eref->colnames));
@@ -1352,7 +1345,7 @@ expandRTE(List *rtable, int rtindex, int sublevels_up,
13521345
*colvars=lappend(*colvars,varnode);
13531346
}
13541347
}
1355-
elseif (functyptype=='p'&&funcrettype==RECORDOID)
1348+
elseif (functypclass==TYPEFUNC_RECORD)
13561349
{
13571350
List*coldeflist=rte->coldeflist;
13581351
ListCell*col;
@@ -1389,9 +1382,10 @@ expandRTE(List *rtable, int rtindex, int sublevels_up,
13891382
}
13901383
}
13911384
else
1392-
ereport(ERROR,
1393-
(errcode(ERRCODE_DATATYPE_MISMATCH),
1394-
errmsg("function in FROM has unsupported return type")));
1385+
{
1386+
/* addRangeTableEntryForFunction should've caught this */
1387+
elog(ERROR,"function in FROM has unsupported return type");
1388+
}
13951389
}
13961390
break;
13971391
caseRTE_JOIN:
@@ -1669,14 +1663,15 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
16691663
{
16701664
/* Function RTE */
16711665
Oidfuncrettype=exprType(rte->funcexpr);
1672-
charfunctyptype=get_typtype(funcrettype);
1666+
TypeFuncClassfunctypclass=get_type_func_class(funcrettype);
16731667
List*coldeflist=rte->coldeflist;
16741668

1675-
if (functyptype=='c')
1669+
if (functypclass==TYPEFUNC_COMPOSITE)
16761670
{
16771671
/*
1678-
* Composite data type, i.e. a table's row type Same
1679-
* as ordinary relation RTE
1672+
* Composite data type, i.e. a table's row type
1673+
*
1674+
* Same as ordinary relation RTE
16801675
*/
16811676
Oidfuncrelid=typeidTypeRelid(funcrettype);
16821677
HeapTupletp;
@@ -1709,25 +1704,24 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
17091704
*vartypmod=att_tup->atttypmod;
17101705
ReleaseSysCache(tp);
17111706
}
1712-
elseif (functyptype=='b'||functyptype=='d')
1707+
elseif (functypclass==TYPEFUNC_SCALAR)
17131708
{
1714-
/*
1715-
* Must be a base data type, i.e. scalar
1716-
*/
1709+
/* Base data type, i.e. scalar */
17171710
*vartype=funcrettype;
17181711
*vartypmod=-1;
17191712
}
1720-
elseif (functyptype=='p'&&funcrettype==RECORDOID)
1713+
elseif (functypclass==TYPEFUNC_RECORD)
17211714
{
17221715
ColumnDef*colDef=list_nth(coldeflist,attnum-1);
17231716

17241717
*vartype=typenameTypeId(colDef->typename);
17251718
*vartypmod=-1;
17261719
}
17271720
else
1728-
ereport(ERROR,
1729-
(errcode(ERRCODE_DATATYPE_MISMATCH),
1730-
errmsg("function in FROM has unsupported return type")));
1721+
{
1722+
/* addRangeTableEntryForFunction should've caught this */
1723+
elog(ERROR,"function in FROM has unsupported return type");
1724+
}
17311725
}
17321726
break;
17331727
caseRTE_JOIN:

‎src/backend/utils/cache/lsyscache.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.116 2004/08/29 05:06:50 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.117 2004/10/20 16:04:49 tgl Exp $
1111
*
1212
* NOTES
1313
* Eventually, the index information should go through here, too.
@@ -1547,6 +1547,42 @@ get_typtype(Oid typid)
15471547
return'\0';
15481548
}
15491549

1550+
/*
1551+
* get_type_func_class
1552+
*
1553+
*Given the type OID, obtain its TYPEFUNC classification.
1554+
*
1555+
* This is intended to centralize a bunch of formerly ad-hoc code for
1556+
* classifying types. The categories used here are useful for deciding
1557+
* how to handle functions returning the datatype.
1558+
*/
1559+
TypeFuncClass
1560+
get_type_func_class(Oidtypid)
1561+
{
1562+
switch (get_typtype(typid))
1563+
{
1564+
case'c':
1565+
returnTYPEFUNC_COMPOSITE;
1566+
case'b':
1567+
case'd':
1568+
returnTYPEFUNC_SCALAR;
1569+
case'p':
1570+
if (typid==RECORDOID)
1571+
returnTYPEFUNC_RECORD;
1572+
/*
1573+
* We treat VOID and CSTRING as legitimate scalar datatypes,
1574+
* mostly for the convenience of the JDBC driver (which wants
1575+
* to be able to do "SELECT * FROM foo()" for all legitimately
1576+
* user-callable functions).
1577+
*/
1578+
if (typid==VOIDOID||typid==CSTRINGOID)
1579+
returnTYPEFUNC_SCALAR;
1580+
returnTYPEFUNC_OTHER;
1581+
}
1582+
/* shouldn't get here, probably */
1583+
returnTYPEFUNC_OTHER;
1584+
}
1585+
15501586
/*
15511587
* get_typ_typrelid
15521588
*

‎src/include/utils/lsyscache.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.90 2004/08/29 05:06:59 momjian Exp $
9+
* $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.91 2004/10/20 16:04:50 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -24,6 +24,15 @@ typedef enum IOFuncSelector
2424
IOFunc_send
2525
}IOFuncSelector;
2626

27+
/* Type categories for get_type_func_class */
28+
typedefenumTypeFuncClass
29+
{
30+
TYPEFUNC_SCALAR,
31+
TYPEFUNC_COMPOSITE,
32+
TYPEFUNC_RECORD,
33+
TYPEFUNC_OTHER
34+
}TypeFuncClass;
35+
2736
externboolop_in_opclass(Oidopno,Oidopclass);
2837
externvoidget_op_opclass_properties(Oidopno,Oidopclass,
2938
int*strategy,Oid*subtype,
@@ -85,6 +94,7 @@ extern char get_typstorage(Oid typid);
8594
externint32get_typtypmod(Oidtypid);
8695
externNode*get_typdefault(Oidtypid);
8796
externcharget_typtype(Oidtypid);
97+
externTypeFuncClassget_type_func_class(Oidtypid);
8898
externOidget_typ_typrelid(Oidtypid);
8999
externOidget_element_type(Oidtypid);
90100
externOidget_array_type(Oidtypid);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp