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

Commita61fd53

Browse files
committed
Support opfamily members in get_object_address
In the spirit of890192e and4464303: have get_object_addressunderstand individual pg_amop and pg_amproc objects. There is no way torefer to such objects directly in the grammar -- rather, they are almostalways considered an integral part of the opfamily that contains them.(The only case that deals with them individually is ALTER OPERATORFAMILY ADD/DROP, which carries the opfamily address separately and thusdoes not need it to be part of each added/dropped element's address.)In event triggers it becomes possible to become involved with individualamop/amproc elements, and this commit enables pg_get_object_address todo so as well.To make the overall coding simpler, this commit also slightly changesthe get_object_address representation for opclasses and opfamilies:instead of having the AM name in the objargs array, I moved it as thefirst element of the objnames array. This enables the new code to useobjargs for the type names used by pg_amop and pg_amproc.Reviewed by: Stephen Frost
1 parent8d1f239 commita61fd53

File tree

7 files changed

+264
-117
lines changed

7 files changed

+264
-117
lines changed

‎src/backend/catalog/objectaddress.c

Lines changed: 185 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -492,9 +492,9 @@ ObjectTypeMap[] =
492492
/* OCLASS_OPFAMILY */
493493
{"operator family",OBJECT_OPFAMILY },
494494
/* OCLASS_AMOP */
495-
{"operator of access method",-1 },/* unmapped */
495+
{"operator of access method",OBJECT_AMOP },
496496
/* OCLASS_AMPROC */
497-
{"function of access method",-1 },/* unmapped */
497+
{"function of access method",OBJECT_AMPROC },
498498
/* OCLASS_REWRITE */
499499
{"rule",OBJECT_RULE },
500500
/* OCLASS_TRIGGER */
@@ -552,9 +552,12 @@ static ObjectAddress get_object_address_attrdef(ObjectType objtype,
552552
List*objname,Relation*relp,LOCKMODElockmode,
553553
boolmissing_ok);
554554
staticObjectAddressget_object_address_type(ObjectTypeobjtype,
555-
List*objname,boolmissing_ok);
555+
ListCell*typecell,boolmissing_ok);
556556
staticObjectAddressget_object_address_opcf(ObjectTypeobjtype,List*objname,
557-
List*objargs,boolmissing_ok);
557+
boolmissing_ok);
558+
staticObjectAddressget_object_address_opf_member(ObjectTypeobjtype,
559+
List*objname,List*objargs,boolmissing_ok);
560+
558561
staticObjectAddressget_object_address_usermapping(List*objname,
559562
List*objargs,boolmissing_ok);
560563
staticObjectAddressget_object_address_defacl(List*objname,List*objargs,
@@ -567,8 +570,7 @@ static void getRelationTypeDescription(StringInfo buffer, Oid relid,
567570
int32objectSubId);
568571
staticvoidgetProcedureTypeDescription(StringInfobuffer,Oidprocid);
569572
staticvoidgetConstraintTypeDescription(StringInfobuffer,Oidconstroid);
570-
staticvoidgetOpFamilyIdentity(StringInfobuffer,Oidopfid,List**objname,
571-
List**objargs);
573+
staticvoidgetOpFamilyIdentity(StringInfobuffer,Oidopfid,List**objname);
572574
staticvoidgetRelationIdentity(StringInfobuffer,Oidrelid,List**objname);
573575

574576
/*
@@ -661,7 +663,8 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
661663
ObjectAddressdomaddr;
662664
char*constrname;
663665

664-
domaddr=get_object_address_type(OBJECT_DOMAIN,objname,missing_ok);
666+
domaddr=get_object_address_type(OBJECT_DOMAIN,
667+
list_head(objname),missing_ok);
665668
constrname=strVal(linitial(objargs));
666669

667670
address.classId=ConstraintRelationId;
@@ -685,7 +688,7 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
685688
break;
686689
caseOBJECT_TYPE:
687690
caseOBJECT_DOMAIN:
688-
address=get_object_address_type(objtype,objname,missing_ok);
691+
address=get_object_address_type(objtype,list_head(objname),missing_ok);
689692
break;
690693
caseOBJECT_AGGREGATE:
691694
address.classId=ProcedureRelationId;
@@ -721,8 +724,12 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
721724
break;
722725
caseOBJECT_OPCLASS:
723726
caseOBJECT_OPFAMILY:
724-
address=get_object_address_opcf(objtype,
725-
objname,objargs,missing_ok);
727+
address=get_object_address_opcf(objtype,objname,missing_ok);
728+
break;
729+
caseOBJECT_AMOP:
730+
caseOBJECT_AMPROC:
731+
address=get_object_address_opf_member(objtype,objname,
732+
objargs,missing_ok);
726733
break;
727734
caseOBJECT_LARGEOBJECT:
728735
Assert(list_length(objname)==1);
@@ -1309,13 +1316,13 @@ get_object_address_attrdef(ObjectType objtype, List *objname,
13091316
* Find the ObjectAddress for a type or domain
13101317
*/
13111318
staticObjectAddress
1312-
get_object_address_type(ObjectTypeobjtype,List*objname,boolmissing_ok)
1319+
get_object_address_type(ObjectTypeobjtype,ListCell*typecell,boolmissing_ok)
13131320
{
13141321
ObjectAddressaddress;
13151322
TypeName*typename;
13161323
Typetup;
13171324

1318-
typename= (TypeName*)linitial(objname);
1325+
typename= (TypeName*)lfirst(typecell);
13191326

13201327
address.classId=TypeRelationId;
13211328
address.objectId=InvalidOid;
@@ -1351,15 +1358,14 @@ get_object_address_type(ObjectType objtype, List *objname, bool missing_ok)
13511358
* Find the ObjectAddress for an opclass or opfamily.
13521359
*/
13531360
staticObjectAddress
1354-
get_object_address_opcf(ObjectTypeobjtype,
1355-
List*objname,List*objargs,boolmissing_ok)
1361+
get_object_address_opcf(ObjectTypeobjtype,List*objname,boolmissing_ok)
13561362
{
13571363
Oidamoid;
13581364
ObjectAddressaddress;
13591365

1360-
Assert(list_length(objargs)==1);
13611366
/* XXX no missing_ok support here */
1362-
amoid=get_am_oid(strVal(linitial(objargs)), false);
1367+
amoid=get_am_oid(strVal(linitial(objname)), false);
1368+
objname=list_copy_tail(objname,1);
13631369

13641370
switch (objtype)
13651371
{
@@ -1384,6 +1390,114 @@ get_object_address_opcf(ObjectType objtype,
13841390
returnaddress;
13851391
}
13861392

1393+
/*
1394+
* Find the ObjectAddress for an opclass/opfamily member.
1395+
*
1396+
* (The returned address corresponds to a pg_amop/pg_amproc object).
1397+
*/
1398+
staticObjectAddress
1399+
get_object_address_opf_member(ObjectTypeobjtype,
1400+
List*objname,List*objargs,boolmissing_ok)
1401+
{
1402+
ObjectAddressfamaddr;
1403+
ObjectAddressaddress;
1404+
ListCell*cell;
1405+
List*copy;
1406+
char*typenames[2];
1407+
Oidtypeoids[2];
1408+
intmembernum;
1409+
inti;
1410+
1411+
/*
1412+
* The last element of the objname list contains the strategy or procedure
1413+
* number. We need to strip that out before getting the opclass/family
1414+
* address. The rest can be used directly by get_object_address_opcf().
1415+
*/
1416+
membernum=atoi(strVal(llast(objname)));
1417+
copy=list_truncate(list_copy(objname),list_length(objname)-1);
1418+
1419+
/* no missing_ok support here */
1420+
famaddr=get_object_address_opcf(OBJECT_OPFAMILY,copy, false);
1421+
1422+
/* find out left/right type names and OIDs */
1423+
i=0;
1424+
foreach (cell,objargs)
1425+
{
1426+
ObjectAddresstypaddr;
1427+
1428+
typenames[i]=strVal(lfirst(cell));
1429+
typaddr=get_object_address_type(OBJECT_TYPE,cell,missing_ok);
1430+
typeoids[i]=typaddr.objectId;
1431+
if (i++ >=2)
1432+
break;
1433+
}
1434+
1435+
switch (objtype)
1436+
{
1437+
caseOBJECT_AMOP:
1438+
{
1439+
HeapTupletp;
1440+
1441+
ObjectAddressSet(address,AccessMethodOperatorRelationId,
1442+
InvalidOid);
1443+
1444+
tp=SearchSysCache4(AMOPSTRATEGY,
1445+
ObjectIdGetDatum(famaddr.objectId),
1446+
ObjectIdGetDatum(typeoids[0]),
1447+
ObjectIdGetDatum(typeoids[1]),
1448+
Int16GetDatum(membernum));
1449+
if (!HeapTupleIsValid(tp))
1450+
{
1451+
if (!missing_ok)
1452+
ereport(ERROR,
1453+
(errcode(ERRCODE_UNDEFINED_OBJECT),
1454+
errmsg("operator %d (%s, %s) of %s does not exist",
1455+
membernum,typenames[0],typenames[1],
1456+
getObjectDescription(&famaddr))));
1457+
}
1458+
else
1459+
{
1460+
address.objectId=HeapTupleGetOid(tp);
1461+
ReleaseSysCache(tp);
1462+
}
1463+
}
1464+
break;
1465+
1466+
caseOBJECT_AMPROC:
1467+
{
1468+
HeapTupletp;
1469+
1470+
ObjectAddressSet(address,AccessMethodProcedureRelationId,
1471+
InvalidOid);
1472+
1473+
tp=SearchSysCache4(AMPROCNUM,
1474+
ObjectIdGetDatum(famaddr.objectId),
1475+
ObjectIdGetDatum(typeoids[0]),
1476+
ObjectIdGetDatum(typeoids[1]),
1477+
Int16GetDatum(membernum));
1478+
if (!HeapTupleIsValid(tp))
1479+
{
1480+
if (!missing_ok)
1481+
ereport(ERROR,
1482+
(errcode(ERRCODE_UNDEFINED_OBJECT),
1483+
errmsg("function %d (%s, %s) of %s does not exist",
1484+
membernum,typenames[0],typenames[1],
1485+
getObjectDescription(&famaddr))));
1486+
}
1487+
else
1488+
{
1489+
address.objectId=HeapTupleGetOid(tp);
1490+
ReleaseSysCache(tp);
1491+
}
1492+
}
1493+
break;
1494+
default:
1495+
elog(ERROR,"unrecognized objtype: %d", (int)objtype);
1496+
}
1497+
1498+
returnaddress;
1499+
}
1500+
13871501
/*
13881502
* Find the ObjectAddress for a user mapping.
13891503
*/
@@ -1673,7 +1787,9 @@ pg_get_object_address(PG_FUNCTION_ARGS)
16731787
if (type==OBJECT_AGGREGATE||
16741788
type==OBJECT_FUNCTION||
16751789
type==OBJECT_OPERATOR||
1676-
type==OBJECT_CAST)
1790+
type==OBJECT_CAST||
1791+
type==OBJECT_AMOP||
1792+
type==OBJECT_AMPROC)
16771793
{
16781794
/* in these cases, the args list must be of TypeName */
16791795
Datum*elems;
@@ -1708,8 +1824,6 @@ pg_get_object_address(PG_FUNCTION_ARGS)
17081824
switch (type)
17091825
{
17101826
caseOBJECT_DOMCONSTRAINT:
1711-
caseOBJECT_OPCLASS:
1712-
caseOBJECT_OPFAMILY:
17131827
caseOBJECT_CAST:
17141828
caseOBJECT_USER_MAPPING:
17151829
caseOBJECT_DEFACL:
@@ -1718,6 +1832,20 @@ pg_get_object_address(PG_FUNCTION_ARGS)
17181832
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
17191833
errmsg("argument list length must be exactly %d",1)));
17201834
break;
1835+
caseOBJECT_OPFAMILY:
1836+
caseOBJECT_OPCLASS:
1837+
if (list_length(name)<2)
1838+
ereport(ERROR,
1839+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1840+
errmsg("name list length must be at least %d",2)));
1841+
break;
1842+
caseOBJECT_AMOP:
1843+
caseOBJECT_AMPROC:
1844+
if (list_length(name)<3)
1845+
ereport(ERROR,
1846+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1847+
errmsg("name list length must be at least %d",3)));
1848+
/* fall through to check args length */
17211849
caseOBJECT_OPERATOR:
17221850
if (list_length(args)!=2)
17231851
ereport(ERROR,
@@ -3730,24 +3858,22 @@ getObjectIdentityParts(const ObjectAddress *object,
37303858
opcForm->opcmethod);
37313859
amForm= (Form_pg_am)GETSTRUCT(amTup);
37323860

3733-
appendStringInfoString(&buffer,
3734-
quote_qualified_identifier(schema,
3735-
NameStr(opcForm->opcname)));
3736-
appendStringInfo(&buffer," USING %s",
3861+
appendStringInfo(&buffer,"%s USING %s",
3862+
quote_qualified_identifier(schema,
3863+
NameStr(opcForm->opcname)),
37373864
quote_identifier(NameStr(amForm->amname)));
37383865
if (objname)
3739-
{
3740-
*objname=list_make2(pstrdup(schema),
3866+
*objname=list_make3(pstrdup(NameStr(amForm->amname)),
3867+
schema,
37413868
pstrdup(NameStr(opcForm->opcname)));
3742-
*objargs=list_make1(pstrdup(NameStr(amForm->amname)));
3743-
}
3869+
37443870
ReleaseSysCache(amTup);
37453871
ReleaseSysCache(opcTup);
37463872
break;
37473873
}
37483874

37493875
caseOCLASS_OPFAMILY:
3750-
getOpFamilyIdentity(&buffer,object->objectId,objname,objargs);
3876+
getOpFamilyIdentity(&buffer,object->objectId,objname);
37513877
break;
37523878

37533879
caseOCLASS_AMOP:
@@ -3758,10 +3884,8 @@ getObjectIdentityParts(const ObjectAddress *object,
37583884
SysScanDescamscan;
37593885
Form_pg_amopamopForm;
37603886
StringInfoDataopfam;
3761-
3762-
/* no objname support here */
3763-
if (objname)
3764-
*objname=NIL;
3887+
char*ltype;
3888+
char*rtype;
37653889

37663890
amopDesc=heap_open(AccessMethodOperatorRelationId,
37673891
AccessShareLock);
@@ -3783,13 +3907,21 @@ getObjectIdentityParts(const ObjectAddress *object,
37833907
amopForm= (Form_pg_amop)GETSTRUCT(tup);
37843908

37853909
initStringInfo(&opfam);
3786-
getOpFamilyIdentity(&opfam,amopForm->amopfamily,NULL,NULL);
3910+
getOpFamilyIdentity(&opfam,amopForm->amopfamily,objname);
3911+
3912+
ltype=format_type_be_qualified(amopForm->amoplefttype);
3913+
rtype=format_type_be_qualified(amopForm->amoprighttype);
3914+
3915+
if (objname)
3916+
{
3917+
*objname=lappend(*objname,
3918+
psprintf("%d",amopForm->amopstrategy));
3919+
*objargs=list_make2(ltype,rtype);
3920+
}
37873921

37883922
appendStringInfo(&buffer,"operator %d (%s, %s) of %s",
37893923
amopForm->amopstrategy,
3790-
format_type_be_qualified(amopForm->amoplefttype),
3791-
format_type_be_qualified(amopForm->amoprighttype),
3792-
opfam.data);
3924+
ltype,rtype,opfam.data);
37933925

37943926
pfree(opfam.data);
37953927

@@ -3806,10 +3938,8 @@ getObjectIdentityParts(const ObjectAddress *object,
38063938
HeapTupletup;
38073939
Form_pg_amprocamprocForm;
38083940
StringInfoDataopfam;
3809-
3810-
/* no objname support here */
3811-
if (objname)
3812-
*objname=NIL;
3941+
char*ltype;
3942+
char*rtype;
38133943

38143944
amprocDesc=heap_open(AccessMethodProcedureRelationId,
38153945
AccessShareLock);
@@ -3831,13 +3961,21 @@ getObjectIdentityParts(const ObjectAddress *object,
38313961
amprocForm= (Form_pg_amproc)GETSTRUCT(tup);
38323962

38333963
initStringInfo(&opfam);
3834-
getOpFamilyIdentity(&opfam,amprocForm->amprocfamily,NULL,NULL);
3964+
getOpFamilyIdentity(&opfam,amprocForm->amprocfamily,objname);
3965+
3966+
ltype=format_type_be_qualified(amprocForm->amproclefttype);
3967+
rtype=format_type_be_qualified(amprocForm->amprocrighttype);
3968+
3969+
if (objname)
3970+
{
3971+
*objname=lappend(*objname,
3972+
psprintf("%d",amprocForm->amprocnum));
3973+
*objargs=list_make2(ltype,rtype);
3974+
}
38353975

38363976
appendStringInfo(&buffer,"function %d (%s, %s) of %s",
38373977
amprocForm->amprocnum,
3838-
format_type_be_qualified(amprocForm->amproclefttype),
3839-
format_type_be_qualified(amprocForm->amprocrighttype),
3840-
opfam.data);
3978+
ltype,rtype,opfam.data);
38413979

38423980
pfree(opfam.data);
38433981

@@ -4263,7 +4401,7 @@ getObjectIdentityParts(const ObjectAddress *object,
42634401
}
42644402

42654403
staticvoid
4266-
getOpFamilyIdentity(StringInfobuffer,Oidopfid,List**objname,List**objargs)
4404+
getOpFamilyIdentity(StringInfobuffer,Oidopfid,List**objname)
42674405
{
42684406
HeapTupleopfTup;
42694407
Form_pg_opfamilyopfForm;
@@ -4289,11 +4427,9 @@ getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **objname, List **objargs
42894427
NameStr(amForm->amname));
42904428

42914429
if (objname)
4292-
{
4293-
*objname=list_make2(pstrdup(schema),
4430+
*objname=list_make3(pstrdup(NameStr(amForm->amname)),
4431+
pstrdup(schema),
42944432
pstrdup(NameStr(opfForm->opfname)));
4295-
*objargs=list_make1(pstrdup(NameStr(amForm->amname)));
4296-
}
42974433

42984434
ReleaseSysCache(amTup);
42994435
ReleaseSysCache(opfTup);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp