@@ -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 , LOCKMODE lockmode ,
553553 bool missing_ok );
554554static ObjectAddress get_object_address_type (ObjectType objtype ,
555- List * objname , bool missing_ok );
555+ ListCell * typecell , bool missing_ok );
556556static ObjectAddress get_object_address_opcf (ObjectType objtype , List * objname ,
557- List * objargs , bool missing_ok );
557+ bool missing_ok );
558+ static ObjectAddress get_object_address_opf_member (ObjectType objtype ,
559+ List * objname , List * objargs , bool missing_ok );
560+
558561static ObjectAddress get_object_address_usermapping (List * objname ,
559562 List * objargs , bool missing_ok );
560563static ObjectAddress get_object_address_defacl (List * objname , List * objargs ,
@@ -567,8 +570,7 @@ static void getRelationTypeDescription(StringInfo buffer, Oid relid,
567570 int32 objectSubId );
568571static void getProcedureTypeDescription (StringInfo buffer , Oid procid );
569572static void getConstraintTypeDescription (StringInfo buffer , Oid constroid );
570- static void getOpFamilyIdentity (StringInfo buffer , Oid opfid , List * * objname ,
571- List * * objargs );
573+ static void getOpFamilyIdentity (StringInfo buffer , Oid opfid , List * * objname );
572574static void getRelationIdentity (StringInfo buffer , Oid relid , List * * objname );
573575
574576/*
@@ -661,7 +663,8 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
661663 ObjectAddress domaddr ;
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 case OBJECT_TYPE :
687690 case OBJECT_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 case OBJECT_AGGREGATE :
691694 address .classId = ProcedureRelationId ;
@@ -721,8 +724,12 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
721724 break ;
722725 case OBJECT_OPCLASS :
723726 case OBJECT_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+ case OBJECT_AMOP :
730+ case OBJECT_AMPROC :
731+ address = get_object_address_opf_member (objtype , objname ,
732+ objargs , missing_ok );
726733 break ;
727734 case OBJECT_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 */
13111318static ObjectAddress
1312- get_object_address_type (ObjectType objtype , List * objname , bool missing_ok )
1319+ get_object_address_type (ObjectType objtype , ListCell * typecell , bool missing_ok )
13131320{
13141321 ObjectAddress address ;
13151322 TypeName * typename ;
13161323 Type tup ;
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 */
13531360static ObjectAddress
1354- get_object_address_opcf (ObjectType objtype ,
1355- List * objname , List * objargs , bool missing_ok )
1361+ get_object_address_opcf (ObjectType objtype , List * objname , bool missing_ok )
13561362{
13571363 Oid amoid ;
13581364 ObjectAddress address ;
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 return address ;
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+ static ObjectAddress
1399+ get_object_address_opf_member (ObjectType objtype ,
1400+ List * objname , List * objargs , bool missing_ok )
1401+ {
1402+ ObjectAddress famaddr ;
1403+ ObjectAddress address ;
1404+ ListCell * cell ;
1405+ List * copy ;
1406+ char * typenames [2 ];
1407+ Oid typeoids [2 ];
1408+ int membernum ;
1409+ int i ;
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+ ObjectAddress typaddr ;
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+ case OBJECT_AMOP :
1438+ {
1439+ HeapTuple tp ;
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+ case OBJECT_AMPROC :
1467+ {
1468+ HeapTuple tp ;
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+ return address ;
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 case OBJECT_DOMCONSTRAINT :
1711- case OBJECT_OPCLASS :
1712- case OBJECT_OPFAMILY :
17131827 case OBJECT_CAST :
17141828 case OBJECT_USER_MAPPING :
17151829 case OBJECT_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+ case OBJECT_OPFAMILY :
1836+ case OBJECT_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+ case OBJECT_AMOP :
1843+ case OBJECT_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 case OBJECT_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 case OCLASS_OPFAMILY :
3750- getOpFamilyIdentity (& buffer , object -> objectId , objname , objargs );
3876+ getOpFamilyIdentity (& buffer , object -> objectId , objname );
37513877 break ;
37523878
37533879 case OCLASS_AMOP :
@@ -3758,10 +3884,8 @@ getObjectIdentityParts(const ObjectAddress *object,
37583884 SysScanDesc amscan ;
37593885 Form_pg_amop amopForm ;
37603886 StringInfoData opfam ;
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 HeapTuple tup ;
38073939 Form_pg_amproc amprocForm ;
38083940 StringInfoData opfam ;
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
42654403static void
4266- getOpFamilyIdentity (StringInfo buffer , Oid opfid , List * * objname , List * * objargs )
4404+ getOpFamilyIdentity (StringInfo buffer , Oid opfid , List * * objname )
42674405{
42684406 HeapTuple opfTup ;
42694407 Form_pg_opfamily opfForm ;
@@ -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