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

Commitfd1a421

Browse files
committed
Add prokind column, replacing proisagg and proiswindow
The new column distinguishes normal functions, procedures, aggregates,and window functions. This replaces the existing columns proisagg andproiswindow, and replaces the convention that procedures are indicatedby prorettype == 0. Also change prorettype to be VOIDOID for procedures.Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>Reviewed-by: Michael Paquier <michael@paquier.xyz>
1 parent1733460 commitfd1a421

40 files changed

+3270
-3198
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5062,15 +5062,17 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
50625062
</indexterm>
50635063

50645064
<para>
5065-
The catalog <structname>pg_proc</structname> stores information about functions (or procedures).
5066-
See <xref linkend="sql-createfunction"/>
5067-
and <xref linkend="xfunc"/> for more information.
5065+
The catalog <structname>pg_proc</structname> stores information about
5066+
functions, procedures, aggregate functions, and window functions
5067+
(collectively also known as routines). See <xref
5068+
linkend="sql-createfunction"/>, <xref linkend="sql-createprocedure"/>, and
5069+
<xref linkend="xfunc"/> for more information.
50685070
</para>
50695071

50705072
<para>
5071-
The table contains data for aggregate functions as well as plain functions.
5072-
If <structfield>proisagg</structfield> is true, there should be a matching
5073-
row in<structfield>pg_aggregate</structfield>.
5073+
If <structfield>prokind</structfield> indicates that the entry is for an
5074+
aggregate function, there should be a matching row in
5075+
<structfield>pg_aggregate</structfield>.
50745076
</para>
50755077

50765078
<table>
@@ -5157,17 +5159,12 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
51575159
</row>
51585160

51595161
<row>
5160-
<entry><structfield>proisagg</structfield></entry>
5161-
<entry><type>bool</type></entry>
5162-
<entry></entry>
5163-
<entry>Function is an aggregate function</entry>
5164-
</row>
5165-
5166-
<row>
5167-
<entry><structfield>proiswindow</structfield></entry>
5168-
<entry><type>bool</type></entry>
5162+
<entry><structfield>prokind</structfield></entry>
5163+
<entry><type>char</type></entry>
51695164
<entry></entry>
5170-
<entry>Function is a window function</entry>
5165+
<entry><literal>f</literal> for a normal function, <literal>p</literal>
5166+
for a procedure, <literal>a</literal> for an aggregate function, or
5167+
<literal>w</literal> for a window function</entry>
51715168
</row>
51725169

51735170
<row>
@@ -5264,7 +5261,7 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
52645261
<entry><structfield>prorettype</structfield></entry>
52655262
<entry><type>oid</type></entry>
52665263
<entry><literal><link linkend="catalog-pg-type"><structname>pg_type</structname></link>.oid</literal></entry>
5267-
<entry>Data type of the return value, or null for a procedure</entry>
5264+
<entry>Data type of the return value</entry>
52685265
</row>
52695266

52705267
<row>

‎src/backend/catalog/aclchk.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -830,21 +830,17 @@ objectsInSchemaToOids(ObjectType objtype, List *nspnames)
830830
BTEqualStrategyNumber,F_OIDEQ,
831831
ObjectIdGetDatum(namespaceId));
832832

833-
/*
834-
* When looking for functions, check for return type <>0.
835-
* When looking for procedures, check for return type ==0.
836-
* When looking for routines, don't check the return type.
837-
*/
838833
if (objtype==OBJECT_FUNCTION)
834+
/* includes aggregates and window functions */
839835
ScanKeyInit(&key[keycount++],
840-
Anum_pg_proc_prorettype,
841-
BTEqualStrategyNumber,F_OIDNE,
842-
InvalidOid);
836+
Anum_pg_proc_prokind,
837+
BTEqualStrategyNumber,F_CHARNE,
838+
CharGetDatum(PROKIND_PROCEDURE));
843839
elseif (objtype==OBJECT_PROCEDURE)
844840
ScanKeyInit(&key[keycount++],
845-
Anum_pg_proc_prorettype,
846-
BTEqualStrategyNumber,F_OIDEQ,
847-
InvalidOid);
841+
Anum_pg_proc_prokind,
842+
BTEqualStrategyNumber,F_CHAREQ,
843+
CharGetDatum(PROKIND_PROCEDURE));
848844

849845
rel=heap_open(ProcedureRelationId,AccessShareLock);
850846
scan=heap_beginscan_catalog(rel,keycount,key);

‎src/backend/catalog/information_schema.sql

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ CREATE VIEW routines AS
14131413
CAST(current_database()AS sql_identifier)AS routine_catalog,
14141414
CAST(n.nspnameAS sql_identifier)AS routine_schema,
14151415
CAST(p.pronameAS sql_identifier)AS routine_name,
1416-
CAST(CASEWHENp.prorettype<>0 THEN'FUNCTION'ELSE'PROCEDURE' END
1416+
CAST(CASEp.prokind WHEN'f' THEN'FUNCTION'WHEN'p' THEN'PROCEDURE' END
14171417
AS character_data)AS routine_type,
14181418
CAST(nullAS sql_identifier)AS module_catalog,
14191419
CAST(nullAS sql_identifier)AS module_schema,
@@ -1423,7 +1423,7 @@ CREATE VIEW routines AS
14231423
CAST(nullAS sql_identifier)AS udt_name,
14241424

14251425
CAST(
1426-
CASE WHENp.prorettype=0 THENNULL
1426+
CASE WHENp.prokind='p' THENNULL
14271427
WHENt.typelem<>0ANDt.typlen=-1 THEN'ARRAY'
14281428
WHENnt.nspname='pg_catalog' THEN format_type(t.oid,null)
14291429
ELSE'USER-DEFINED' ENDAS character_data)
@@ -1442,14 +1442,14 @@ CREATE VIEW routines AS
14421442
CAST(nullAS cardinal_number)AS datetime_precision,
14431443
CAST(nullAS character_data)AS interval_type,
14441444
CAST(nullAS cardinal_number)AS interval_precision,
1445-
CAST(CASE WHENp.prorettype<>0 THEN current_database() ENDAS sql_identifier)AS type_udt_catalog,
1445+
CAST(CASE WHENnt.nspnameIS NOT NULL THEN current_database() ENDAS sql_identifier)AS type_udt_catalog,
14461446
CAST(nt.nspnameAS sql_identifier)AS type_udt_schema,
14471447
CAST(t.typnameAS sql_identifier)AS type_udt_name,
14481448
CAST(nullAS sql_identifier)AS scope_catalog,
14491449
CAST(nullAS sql_identifier)AS scope_schema,
14501450
CAST(nullAS sql_identifier)AS scope_name,
14511451
CAST(nullAS cardinal_number)AS maximum_cardinality,
1452-
CAST(0AS sql_identifier)AS dtd_identifier,
1452+
CAST(CASE WHENp.prokind<>'p' THEN0 ENDAS sql_identifier)AS dtd_identifier,
14531453

14541454
CAST(CASE WHENl.lanname='sql' THEN'SQL' ELSE'EXTERNAL' ENDAS character_data)
14551455
AS routine_body,
@@ -1464,7 +1464,7 @@ CREATE VIEW routines AS
14641464
CAST('GENERAL'AS character_data)AS parameter_style,
14651465
CAST(CASE WHENp.provolatile='i' THEN'YES' ELSE'NO' ENDAS yes_or_no)AS is_deterministic,
14661466
CAST('MODIFIES'AS character_data)AS sql_data_access,
1467-
CAST(CASE WHENp.prorettype<>0 THEN
1467+
CAST(CASE WHENp.prokind<>'p' THEN
14681468
CASE WHENp.proisstrict THEN'YES' ELSE'NO' END ENDAS yes_or_no)AS is_null_call,
14691469
CAST(nullAS character_data)AS sql_path,
14701470
CAST('YES'AS yes_or_no)AS schema_level_routine,
@@ -1511,7 +1511,7 @@ CREATE VIEW routines AS
15111511
JOIN pg_language lONp.prolang=l.oid)
15121512
LEFT JOIN
15131513
(pg_type tJOIN pg_namespace ntONt.typnamespace=nt.oid)
1514-
ONp.prorettype=t.oid
1514+
ONp.prorettype=t.oidANDp.prokind<>'p'
15151515

15161516
WHERE (pg_has_role(p.proowner,'USAGE')
15171517
OR has_function_privilege(p.oid,'EXECUTE'));

‎src/backend/catalog/objectaddress.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4047,11 +4047,11 @@ getProcedureTypeDescription(StringInfo buffer, Oid procid)
40474047
elog(ERROR,"cache lookup failed for procedure %u",procid);
40484048
procForm= (Form_pg_proc)GETSTRUCT(procTup);
40494049

4050-
if (procForm->proisagg)
4050+
if (procForm->prokind==PROKIND_AGGREGATE)
40514051
appendStringInfoString(buffer,"aggregate");
4052-
elseif (procForm->prorettype==InvalidOid)
4052+
elseif (procForm->prokind==PROKIND_PROCEDURE)
40534053
appendStringInfoString(buffer,"procedure");
4054-
else
4054+
else/* function or window function */
40554055
appendStringInfoString(buffer,"function");
40564056

40574057
ReleaseSysCache(procTup);

‎src/backend/catalog/pg_aggregate.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,7 @@ AggregateCreate(const char *aggName,
616616
InvalidOid,/* no validator */
617617
"aggregate_dummy",/* placeholder proc */
618618
NULL,/* probin */
619-
true,/* isAgg */
620-
false,/* isWindowFunc */
619+
PROKIND_AGGREGATE,
621620
false,/* security invoker (currently not
622621
* definable for agg) */
623622
false,/* isLeakProof */

‎src/backend/catalog/pg_proc.c

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ ProcedureCreate(const char *procedureName,
7474
OidlanguageValidator,
7575
constchar*prosrc,
7676
constchar*probin,
77-
boolisAgg,
78-
boolisWindowFunc,
77+
charprokind,
7978
boolsecurity_definer,
8079
boolisLeakProof,
8180
boolisStrict,
@@ -335,8 +334,7 @@ ProcedureCreate(const char *procedureName,
335334
values[Anum_pg_proc_prorows-1]=Float4GetDatum(prorows);
336335
values[Anum_pg_proc_provariadic-1]=ObjectIdGetDatum(variadicType);
337336
values[Anum_pg_proc_protransform-1]=ObjectIdGetDatum(InvalidOid);
338-
values[Anum_pg_proc_proisagg-1]=BoolGetDatum(isAgg);
339-
values[Anum_pg_proc_proiswindow-1]=BoolGetDatum(isWindowFunc);
337+
values[Anum_pg_proc_prokind-1]=CharGetDatum(prokind);
340338
values[Anum_pg_proc_prosecdef-1]=BoolGetDatum(security_definer);
341339
values[Anum_pg_proc_proleakproof-1]=BoolGetDatum(isLeakProof);
342340
values[Anum_pg_proc_proisstrict-1]=BoolGetDatum(isStrict);
@@ -403,6 +401,21 @@ ProcedureCreate(const char *procedureName,
403401
aclcheck_error(ACLCHECK_NOT_OWNER,OBJECT_FUNCTION,
404402
procedureName);
405403

404+
/* Not okay to change routine kind */
405+
if (oldproc->prokind!=prokind)
406+
ereport(ERROR,
407+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
408+
errmsg("cannot change routine kind"),
409+
(oldproc->prokind==PROKIND_AGGREGATE ?
410+
errdetail("\"%s\" is an aggregate function.",procedureName) :
411+
oldproc->prokind==PROKIND_FUNCTION ?
412+
errdetail("\"%s\" is a function.",procedureName) :
413+
oldproc->prokind==PROKIND_PROCEDURE ?
414+
errdetail("\"%s\" is a procedure.",procedureName) :
415+
oldproc->prokind==PROKIND_WINDOW ?
416+
errdetail("\"%s\" is a window function.",procedureName) :
417+
0)));
418+
406419
/*
407420
* Not okay to change the return type of the existing proc, since
408421
* existing rules, views, etc may depend on the return type.
@@ -535,34 +548,6 @@ ProcedureCreate(const char *procedureName,
535548
}
536549
}
537550

538-
/* Can't change aggregate or window-function status, either */
539-
if (oldproc->proisagg!=isAgg)
540-
{
541-
if (oldproc->proisagg)
542-
ereport(ERROR,
543-
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
544-
errmsg("function \"%s\" is an aggregate function",
545-
procedureName)));
546-
else
547-
ereport(ERROR,
548-
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
549-
errmsg("function \"%s\" is not an aggregate function",
550-
procedureName)));
551-
}
552-
if (oldproc->proiswindow!=isWindowFunc)
553-
{
554-
if (oldproc->proiswindow)
555-
ereport(ERROR,
556-
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
557-
errmsg("function \"%s\" is a window function",
558-
procedureName)));
559-
else
560-
ereport(ERROR,
561-
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
562-
errmsg("function \"%s\" is not a window function",
563-
procedureName)));
564-
}
565-
566551
/*
567552
* Do not change existing ownership or permissions, either. Note
568553
* dependency-update code below has to agree with this decision.
@@ -857,8 +842,7 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
857842

858843
/* Disallow pseudotype result */
859844
/* except for RECORD, VOID, or polymorphic */
860-
if (proc->prorettype&&
861-
get_typtype(proc->prorettype)==TYPTYPE_PSEUDO&&
845+
if (get_typtype(proc->prorettype)==TYPTYPE_PSEUDO&&
862846
proc->prorettype!=RECORDOID&&
863847
proc->prorettype!=VOIDOID&&
864848
!IsPolymorphicType(proc->prorettype))

‎src/backend/catalog/system_views.sql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,11 @@ WHERE
332332
UNION ALL
333333
SELECT
334334
l.objoid,l.classoid,l.objsubid,
335-
CASE WHENpro.proisagg= true THEN'aggregate'::text
336-
WHENpro.proisagg= false THEN'function'::text
337-
ENDAS objtype,
335+
CASEpro.prokind
336+
WHEN'a' THEN'aggregate'::text
337+
WHEN'f' THEN'function'::text
338+
WHEN'p' THEN'procedure'::text
339+
WHEN'w' THEN'window'::text ENDAS objtype,
338340
pro.pronamespaceAS objnamespace,
339341
CASE WHEN pg_function_is_visible(pro.oid)
340342
THEN quote_ident(pro.proname)

‎src/backend/commands/dropcmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ RemoveObjects(DropStmt *stmt)
9292
*/
9393
if (stmt->removeType==OBJECT_FUNCTION)
9494
{
95-
if (get_func_isagg(address.objectId))
95+
if (get_func_prokind(address.objectId)==PROKIND_AGGREGATE)
9696
ereport(ERROR,
9797
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
9898
errmsg("\"%s\" is an aggregate function",

‎src/backend/commands/functioncmds.c

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,9 +1003,12 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
10031003

10041004
if (stmt->is_procedure)
10051005
{
1006+
/*
1007+
* Sometime in the future, procedures might be allowed to return
1008+
* results; for now, they all return VOID.
1009+
*/
10061010
Assert(!stmt->returnType);
1007-
1008-
prorettype=InvalidOid;
1011+
prorettype=VOIDOID;
10091012
returnsSet= false;
10101013
}
10111014
elseif (stmt->returnType)
@@ -1097,8 +1100,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
10971100
languageValidator,
10981101
prosrc_str,/* converted to text later */
10991102
probin_str,/* converted to text later */
1100-
false,/* not an aggregate */
1101-
isWindowFunc,
1103+
stmt->is_procedure ?PROKIND_PROCEDURE : (isWindowFunc ?PROKIND_WINDOW :PROKIND_FUNCTION),
11021104
security,
11031105
isLeakProof,
11041106
isStrict,
@@ -1126,7 +1128,7 @@ RemoveFunctionById(Oid funcOid)
11261128
{
11271129
Relationrelation;
11281130
HeapTupletup;
1129-
boolisagg;
1131+
charprokind;
11301132

11311133
/*
11321134
* Delete the pg_proc tuple.
@@ -1137,7 +1139,7 @@ RemoveFunctionById(Oid funcOid)
11371139
if (!HeapTupleIsValid(tup))/* should not happen */
11381140
elog(ERROR,"cache lookup failed for function %u",funcOid);
11391141

1140-
isagg= ((Form_pg_proc)GETSTRUCT(tup))->proisagg;
1142+
prokind= ((Form_pg_proc)GETSTRUCT(tup))->prokind;
11411143

11421144
CatalogTupleDelete(relation,&tup->t_self);
11431145

@@ -1148,7 +1150,7 @@ RemoveFunctionById(Oid funcOid)
11481150
/*
11491151
* If there's a pg_aggregate tuple, delete that too.
11501152
*/
1151-
if (isagg)
1153+
if (prokind==PROKIND_AGGREGATE)
11521154
{
11531155
relation=heap_open(AggregateRelationId,RowExclusiveLock);
11541156

@@ -1203,13 +1205,13 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
12031205
aclcheck_error(ACLCHECK_NOT_OWNER,stmt->objtype,
12041206
NameListToString(stmt->func->objname));
12051207

1206-
if (procForm->proisagg)
1208+
if (procForm->prokind==PROKIND_AGGREGATE)
12071209
ereport(ERROR,
12081210
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
12091211
errmsg("\"%s\" is an aggregate function",
12101212
NameListToString(stmt->func->objname))));
12111213

1212-
is_procedure= (procForm->prorettype==InvalidOid);
1214+
is_procedure= (procForm->prokind==PROKIND_PROCEDURE);
12131215

12141216
/* Examine requested actions. */
12151217
foreach(l,stmt->actions)
@@ -1525,14 +1527,10 @@ CreateCast(CreateCastStmt *stmt)
15251527
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
15261528
errmsg("cast function must not be volatile")));
15271529
#endif
1528-
if (procstruct->proisagg)
1530+
if (procstruct->prokind!=PROKIND_FUNCTION)
15291531
ereport(ERROR,
15301532
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1531-
errmsg("cast function must not be an aggregate function")));
1532-
if (procstruct->proiswindow)
1533-
ereport(ERROR,
1534-
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1535-
errmsg("cast function must not be a window function")));
1533+
errmsg("cast function must be a normal function")));
15361534
if (procstruct->proretset)
15371535
ereport(ERROR,
15381536
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
@@ -1777,14 +1775,10 @@ check_transform_function(Form_pg_proc procstruct)
17771775
ereport(ERROR,
17781776
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
17791777
errmsg("transform function must not be volatile")));
1780-
if (procstruct->proisagg)
1781-
ereport(ERROR,
1782-
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1783-
errmsg("transform function must not be an aggregate function")));
1784-
if (procstruct->proiswindow)
1778+
if (procstruct->prokind!=PROKIND_FUNCTION)
17851779
ereport(ERROR,
17861780
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1787-
errmsg("transform function mustnotbe awindow function")));
1781+
errmsg("transform function must be anormal function")));
17881782
if (procstruct->proretset)
17891783
ereport(ERROR,
17901784
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp