1313
1414#include "postgres.h"
1515
16+ #include "access/htup_details.h"
1617#include "access/reloptions.h"
1718#include "catalog/pg_collation.h"
19+ #include "catalog/pg_opclass.h"
1820#include "catalog/pg_type.h"
1921#include "miscadmin.h"
2022#include "storage/indexfsm.h"
2325#include "utils/guc.h"
2426#include "utils/index_selfuncs.h"
2527#include "utils/lsyscache.h"
28+ #include "utils/syscache.h"
2629#include "utils/typcache.h"
2730
2831#include "rum.h"
@@ -111,6 +114,9 @@ rumhandler(PG_FUNCTION_ARGS)
111114amroutine -> amstorage = true;
112115amroutine -> amclusterable = false;
113116amroutine -> ampredlocks = true;
117+ #if PG_VERSION_NUM >=100000
118+ amroutine -> amcanparallel = false;
119+ #endif
114120amroutine -> amkeytype = InvalidOid ;
115121
116122amroutine -> ambuild = rumbuild ;
@@ -121,6 +127,7 @@ rumhandler(PG_FUNCTION_ARGS)
121127amroutine -> amcanreturn = NULL ;
122128amroutine -> amcostestimate = gincostestimate ;
123129amroutine -> amoptions = rumoptions ;
130+ amroutine -> amproperty = rumproperty ;
124131amroutine -> amvalidate = rumvalidate ;
125132amroutine -> ambeginscan = rumbeginscan ;
126133amroutine -> amrescan = rumrescan ;
@@ -129,6 +136,11 @@ rumhandler(PG_FUNCTION_ARGS)
129136amroutine -> amendscan = rumendscan ;
130137amroutine -> ammarkpos = NULL ;
131138amroutine -> amrestrpos = NULL ;
139+ #if PG_VERSION_NUM >=100000
140+ amroutine -> amestimateparallelscan = NULL ;
141+ amroutine -> aminitparallelscan = NULL ;
142+ amroutine -> amparallelrescan = NULL ;
143+ #endif
132144
133145PG_RETURN_POINTER (amroutine );
134146}
@@ -877,6 +889,82 @@ rumoptions(Datum reloptions, bool validate)
877889return (bytea * )rdopts ;
878890}
879891
892+ bool
893+ rumproperty (Oid index_oid ,int attno ,
894+ IndexAMProperty prop ,const char * propname ,
895+ bool * res ,bool * isnull )
896+ {
897+ HeapTuple tuple ;
898+ Form_pg_index rd_index PG_USED_FOR_ASSERTS_ONLY ;
899+ Form_pg_opclass rd_opclass ;
900+ Datum datum ;
901+ bool disnull ;
902+ oidvector * indclass ;
903+ Oid opclass ,
904+ opfamily ,
905+ opcintype ;
906+ int16 procno ;
907+
908+ /* Only answer column-level inquiries */
909+ if (attno == 0 )
910+ return false;
911+
912+ switch (prop )
913+ {
914+ case AMPROP_DISTANCE_ORDERABLE :
915+ procno = RUM_ORDERING_PROC ;
916+ break ;
917+ default :
918+ return false;
919+ }
920+
921+ /* First we need to know the column's opclass. */
922+
923+ tuple = SearchSysCache1 (INDEXRELID ,ObjectIdGetDatum (index_oid ));
924+ if (!HeapTupleIsValid (tuple ))
925+ {
926+ * isnull = true;
927+ return true;
928+ }
929+ rd_index = (Form_pg_index )GETSTRUCT (tuple );
930+
931+ /* caller is supposed to guarantee this */
932+ Assert (attno > 0 && attno <=rd_index -> indnatts );
933+
934+ datum = SysCacheGetAttr (INDEXRELID ,tuple ,
935+ Anum_pg_index_indclass ,& disnull );
936+ Assert (!disnull );
937+
938+ indclass = ((oidvector * )DatumGetPointer (datum ));
939+ opclass = indclass -> values [attno - 1 ];
940+
941+ ReleaseSysCache (tuple );
942+
943+ /* Now look up the opclass family and input datatype. */
944+
945+ tuple = SearchSysCache1 (CLAOID ,ObjectIdGetDatum (opclass ));
946+ if (!HeapTupleIsValid (tuple ))
947+ {
948+ * isnull = true;
949+ return true;
950+ }
951+ rd_opclass = (Form_pg_opclass )GETSTRUCT (tuple );
952+
953+ opfamily = rd_opclass -> opcfamily ;
954+ opcintype = rd_opclass -> opcintype ;
955+
956+ ReleaseSysCache (tuple );
957+
958+ /* And now we can check whether the function is provided. */
959+
960+ * res = SearchSysCacheExists4 (AMPROCNUM ,
961+ ObjectIdGetDatum (opfamily ),
962+ ObjectIdGetDatum (opcintype ),
963+ ObjectIdGetDatum (opcintype ),
964+ Int16GetDatum (procno ));
965+ return true;
966+ }
967+
880968/*
881969 * Fetch index's statistical data into *stats
882970 *