@@ -492,9 +492,9 @@ ObjectTypeMap[] =
492
492
/* OCLASS_OPFAMILY */
493
493
{ "operator family" , OBJECT_OPFAMILY },
494
494
/* OCLASS_AMOP */
495
- { "operator of access method" , -1 }, /* unmapped */
495
+ { "operator of access method" , OBJECT_AMOP },
496
496
/* OCLASS_AMPROC */
497
- { "function of access method" , -1 }, /* unmapped */
497
+ { "function of access method" , OBJECT_AMPROC },
498
498
/* OCLASS_REWRITE */
499
499
{ "rule" , OBJECT_RULE },
500
500
/* OCLASS_TRIGGER */
@@ -552,9 +552,12 @@ static ObjectAddress get_object_address_attrdef(ObjectType objtype,
552
552
List * objname , Relation * relp , LOCKMODE lockmode ,
553
553
bool missing_ok );
554
554
static ObjectAddress get_object_address_type (ObjectType objtype ,
555
- List * objname , bool missing_ok );
555
+ ListCell * typecell , bool missing_ok );
556
556
static 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
+
558
561
static ObjectAddress get_object_address_usermapping (List * objname ,
559
562
List * objargs , bool missing_ok );
560
563
static ObjectAddress get_object_address_defacl (List * objname , List * objargs ,
@@ -567,8 +570,7 @@ static void getRelationTypeDescription(StringInfo buffer, Oid relid,
567
570
int32 objectSubId );
568
571
static void getProcedureTypeDescription (StringInfo buffer , Oid procid );
569
572
static 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 );
572
574
static void getRelationIdentity (StringInfo buffer , Oid relid , List * * objname );
573
575
574
576
/*
@@ -661,7 +663,8 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
661
663
ObjectAddress domaddr ;
662
664
char * constrname ;
663
665
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 );
665
668
constrname = strVal (linitial (objargs ));
666
669
667
670
address .classId = ConstraintRelationId ;
@@ -685,7 +688,7 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
685
688
break ;
686
689
case OBJECT_TYPE :
687
690
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 );
689
692
break ;
690
693
case OBJECT_AGGREGATE :
691
694
address .classId = ProcedureRelationId ;
@@ -721,8 +724,12 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
721
724
break ;
722
725
case OBJECT_OPCLASS :
723
726
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 );
726
733
break ;
727
734
case OBJECT_LARGEOBJECT :
728
735
Assert (list_length (objname ) == 1 );
@@ -1309,13 +1316,13 @@ get_object_address_attrdef(ObjectType objtype, List *objname,
1309
1316
* Find the ObjectAddress for a type or domain
1310
1317
*/
1311
1318
static 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 )
1313
1320
{
1314
1321
ObjectAddress address ;
1315
1322
TypeName * typename ;
1316
1323
Type tup ;
1317
1324
1318
- typename = (TypeName * ) linitial ( objname );
1325
+ typename = (TypeName * ) lfirst ( typecell );
1319
1326
1320
1327
address .classId = TypeRelationId ;
1321
1328
address .objectId = InvalidOid ;
@@ -1351,15 +1358,14 @@ get_object_address_type(ObjectType objtype, List *objname, bool missing_ok)
1351
1358
* Find the ObjectAddress for an opclass or opfamily.
1352
1359
*/
1353
1360
static 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 )
1356
1362
{
1357
1363
Oid amoid ;
1358
1364
ObjectAddress address ;
1359
1365
1360
- Assert (list_length (objargs ) == 1 );
1361
1366
/* 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 );
1363
1369
1364
1370
switch (objtype )
1365
1371
{
@@ -1384,6 +1390,114 @@ get_object_address_opcf(ObjectType objtype,
1384
1390
return address ;
1385
1391
}
1386
1392
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
+
1387
1501
/*
1388
1502
* Find the ObjectAddress for a user mapping.
1389
1503
*/
@@ -1673,7 +1787,9 @@ pg_get_object_address(PG_FUNCTION_ARGS)
1673
1787
if (type == OBJECT_AGGREGATE ||
1674
1788
type == OBJECT_FUNCTION ||
1675
1789
type == OBJECT_OPERATOR ||
1676
- type == OBJECT_CAST )
1790
+ type == OBJECT_CAST ||
1791
+ type == OBJECT_AMOP ||
1792
+ type == OBJECT_AMPROC )
1677
1793
{
1678
1794
/* in these cases, the args list must be of TypeName */
1679
1795
Datum * elems ;
@@ -1708,8 +1824,6 @@ pg_get_object_address(PG_FUNCTION_ARGS)
1708
1824
switch (type )
1709
1825
{
1710
1826
case OBJECT_DOMCONSTRAINT :
1711
- case OBJECT_OPCLASS :
1712
- case OBJECT_OPFAMILY :
1713
1827
case OBJECT_CAST :
1714
1828
case OBJECT_USER_MAPPING :
1715
1829
case OBJECT_DEFACL :
@@ -1718,6 +1832,20 @@ pg_get_object_address(PG_FUNCTION_ARGS)
1718
1832
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1719
1833
errmsg ("argument list length must be exactly %d" , 1 )));
1720
1834
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 */
1721
1849
case OBJECT_OPERATOR :
1722
1850
if (list_length (args ) != 2 )
1723
1851
ereport (ERROR ,
@@ -3730,24 +3858,22 @@ getObjectIdentityParts(const ObjectAddress *object,
3730
3858
opcForm -> opcmethod );
3731
3859
amForm = (Form_pg_am ) GETSTRUCT (amTup );
3732
3860
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 )),
3737
3864
quote_identifier (NameStr (amForm -> amname )));
3738
3865
if (objname )
3739
- {
3740
- * objname = list_make2 ( pstrdup ( schema ) ,
3866
+ * objname = list_make3 ( pstrdup ( NameStr ( amForm -> amname )),
3867
+ schema ,
3741
3868
pstrdup (NameStr (opcForm -> opcname )));
3742
- * objargs = list_make1 (pstrdup (NameStr (amForm -> amname )));
3743
- }
3869
+
3744
3870
ReleaseSysCache (amTup );
3745
3871
ReleaseSysCache (opcTup );
3746
3872
break ;
3747
3873
}
3748
3874
3749
3875
case OCLASS_OPFAMILY :
3750
- getOpFamilyIdentity (& buffer , object -> objectId , objname , objargs );
3876
+ getOpFamilyIdentity (& buffer , object -> objectId , objname );
3751
3877
break ;
3752
3878
3753
3879
case OCLASS_AMOP :
@@ -3758,10 +3884,8 @@ getObjectIdentityParts(const ObjectAddress *object,
3758
3884
SysScanDesc amscan ;
3759
3885
Form_pg_amop amopForm ;
3760
3886
StringInfoData opfam ;
3761
-
3762
- /* no objname support here */
3763
- if (objname )
3764
- * objname = NIL ;
3887
+ char * ltype ;
3888
+ char * rtype ;
3765
3889
3766
3890
amopDesc = heap_open (AccessMethodOperatorRelationId ,
3767
3891
AccessShareLock );
@@ -3783,13 +3907,21 @@ getObjectIdentityParts(const ObjectAddress *object,
3783
3907
amopForm = (Form_pg_amop ) GETSTRUCT (tup );
3784
3908
3785
3909
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
+ }
3787
3921
3788
3922
appendStringInfo (& buffer , "operator %d (%s, %s) of %s" ,
3789
3923
amopForm -> amopstrategy ,
3790
- format_type_be_qualified (amopForm -> amoplefttype ),
3791
- format_type_be_qualified (amopForm -> amoprighttype ),
3792
- opfam .data );
3924
+ ltype , rtype , opfam .data );
3793
3925
3794
3926
pfree (opfam .data );
3795
3927
@@ -3806,10 +3938,8 @@ getObjectIdentityParts(const ObjectAddress *object,
3806
3938
HeapTuple tup ;
3807
3939
Form_pg_amproc amprocForm ;
3808
3940
StringInfoData opfam ;
3809
-
3810
- /* no objname support here */
3811
- if (objname )
3812
- * objname = NIL ;
3941
+ char * ltype ;
3942
+ char * rtype ;
3813
3943
3814
3944
amprocDesc = heap_open (AccessMethodProcedureRelationId ,
3815
3945
AccessShareLock );
@@ -3831,13 +3961,21 @@ getObjectIdentityParts(const ObjectAddress *object,
3831
3961
amprocForm = (Form_pg_amproc ) GETSTRUCT (tup );
3832
3962
3833
3963
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
+ }
3835
3975
3836
3976
appendStringInfo (& buffer , "function %d (%s, %s) of %s" ,
3837
3977
amprocForm -> amprocnum ,
3838
- format_type_be_qualified (amprocForm -> amproclefttype ),
3839
- format_type_be_qualified (amprocForm -> amprocrighttype ),
3840
- opfam .data );
3978
+ ltype , rtype , opfam .data );
3841
3979
3842
3980
pfree (opfam .data );
3843
3981
@@ -4263,7 +4401,7 @@ getObjectIdentityParts(const ObjectAddress *object,
4263
4401
}
4264
4402
4265
4403
static void
4266
- getOpFamilyIdentity (StringInfo buffer , Oid opfid , List * * objname , List * * objargs )
4404
+ getOpFamilyIdentity (StringInfo buffer , Oid opfid , List * * objname )
4267
4405
{
4268
4406
HeapTuple opfTup ;
4269
4407
Form_pg_opfamily opfForm ;
@@ -4289,11 +4427,9 @@ getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **objname, List **objargs
4289
4427
NameStr (amForm -> amname ));
4290
4428
4291
4429
if (objname )
4292
- {
4293
- * objname = list_make2 ( pstrdup (schema ),
4430
+ * objname = list_make3 ( pstrdup ( NameStr ( amForm -> amname )),
4431
+ pstrdup (schema ),
4294
4432
pstrdup (NameStr (opfForm -> opfname )));
4295
- * objargs = list_make1 (pstrdup (NameStr (amForm -> amname )));
4296
- }
4297
4433
4298
4434
ReleaseSysCache (amTup );
4299
4435
ReleaseSysCache (opfTup );
0 commit comments