13
13
14
14
#include "postgres.h"
15
15
16
+ #include "access/htup_details.h"
16
17
#include "access/reloptions.h"
17
18
#include "catalog/pg_collation.h"
19
+ #include "catalog/pg_opclass.h"
18
20
#include "catalog/pg_type.h"
19
21
#include "miscadmin.h"
20
22
#include "storage/indexfsm.h"
23
25
#include "utils/guc.h"
24
26
#include "utils/index_selfuncs.h"
25
27
#include "utils/lsyscache.h"
28
+ #include "utils/syscache.h"
26
29
#include "utils/typcache.h"
27
30
28
31
#include "rum.h"
@@ -111,6 +114,9 @@ rumhandler(PG_FUNCTION_ARGS)
111
114
amroutine -> amstorage = true;
112
115
amroutine -> amclusterable = false;
113
116
amroutine -> ampredlocks = true;
117
+ #if PG_VERSION_NUM >= 100000
118
+ amroutine -> amcanparallel = false;
119
+ #endif
114
120
amroutine -> amkeytype = InvalidOid ;
115
121
116
122
amroutine -> ambuild = rumbuild ;
@@ -121,6 +127,7 @@ rumhandler(PG_FUNCTION_ARGS)
121
127
amroutine -> amcanreturn = NULL ;
122
128
amroutine -> amcostestimate = gincostestimate ;
123
129
amroutine -> amoptions = rumoptions ;
130
+ amroutine -> amproperty = rumproperty ;
124
131
amroutine -> amvalidate = rumvalidate ;
125
132
amroutine -> ambeginscan = rumbeginscan ;
126
133
amroutine -> amrescan = rumrescan ;
@@ -129,6 +136,11 @@ rumhandler(PG_FUNCTION_ARGS)
129
136
amroutine -> amendscan = rumendscan ;
130
137
amroutine -> ammarkpos = NULL ;
131
138
amroutine -> amrestrpos = NULL ;
139
+ #if PG_VERSION_NUM >= 100000
140
+ amroutine -> amestimateparallelscan = NULL ;
141
+ amroutine -> aminitparallelscan = NULL ;
142
+ amroutine -> amparallelrescan = NULL ;
143
+ #endif
132
144
133
145
PG_RETURN_POINTER (amroutine );
134
146
}
@@ -877,6 +889,82 @@ rumoptions(Datum reloptions, bool validate)
877
889
return (bytea * ) rdopts ;
878
890
}
879
891
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
+
880
968
/*
881
969
* Fetch index's statistical data into *stats
882
970
*
0 commit comments