Skip to content

Commit 0e01f5d

Browse files
committed
Support amproperty method.
Query select pg_index_column_has_property('index_name'::regclass,1,'distance_orderable') returns value 'true' instead of null now.
1 parent 7386406 commit 0e01f5d

File tree

4 files changed

+143
-0
lines changed

4 files changed

+143
-0
lines changed

expected/rum.out

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,45 @@ CREATE TRIGGER tsvectorupdate
4747
BEFORE UPDATE OR INSERT ON test_rum
4848
FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('a', 'pg_catalog.english', 't');
4949
CREATE INDEX rumidx ON test_rum USING rum (a rum_tsvector_ops);
50+
-- Access method properties
51+
SELECT a.amname, p.name, pg_indexam_has_property(a.oid,p.name)
52+
FROM pg_am a, unnest(array['can_order','can_unique','can_multi_col','can_exclude']) p(name)
53+
WHERE a.amname = 'rum' ORDER BY a.amname;
54+
amname | name | pg_indexam_has_property
55+
--------+---------------+-------------------------
56+
rum | can_order | f
57+
rum | can_unique | f
58+
rum | can_multi_col | t
59+
rum | can_exclude | t
60+
(4 rows)
61+
62+
-- Index properties
63+
SELECT p.name, pg_index_has_property('rumidx'::regclass,p.name)
64+
FROM unnest(array['clusterable','index_scan','bitmap_scan','backward_scan']) p(name);
65+
name | pg_index_has_property
66+
---------------+-----------------------
67+
clusterable | f
68+
index_scan | t
69+
bitmap_scan | t
70+
backward_scan | f
71+
(4 rows)
72+
73+
-- Index column properties
74+
SELECT p.name, pg_index_column_has_property('rumidx'::regclass,1,p.name)
75+
FROM unnest(array['asc','desc','nulls_first','nulls_last','orderable','distance_orderable','returnable','search_array','search_nulls']) p(name);
76+
name | pg_index_column_has_property
77+
--------------------+------------------------------
78+
asc | f
79+
desc | f
80+
nulls_first | f
81+
nulls_last | f
82+
orderable | f
83+
distance_orderable | t
84+
returnable | f
85+
search_array | f
86+
search_nulls | f
87+
(9 rows)
88+
5089
\copy test_rum(t) from 'data/rum.data';
5190
CREATE INDEX failed_rumidx ON test_rum USING rum (a rum_tsvector_addon_ops);
5291
ERROR: additional information attribute "a" is not found in index

sql/rum.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ BEFORE UPDATE OR INSERT ON test_rum
1313
FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('a', 'pg_catalog.english', 't');
1414
CREATE INDEX rumidx ON test_rum USING rum (a rum_tsvector_ops);
1515

16+
-- Access method properties
17+
SELECT a.amname, p.name, pg_indexam_has_property(a.oid,p.name)
18+
FROM pg_am a, unnest(array['can_order','can_unique','can_multi_col','can_exclude']) p(name)
19+
WHERE a.amname = 'rum' ORDER BY a.amname;
20+
21+
-- Index properties
22+
SELECT p.name, pg_index_has_property('rumidx'::regclass,p.name)
23+
FROM unnest(array['clusterable','index_scan','bitmap_scan','backward_scan']) p(name);
24+
25+
-- Index column properties
26+
SELECT p.name, pg_index_column_has_property('rumidx'::regclass,1,p.name)
27+
FROM unnest(array['asc','desc','nulls_first','nulls_last','orderable','distance_orderable','returnable','search_array','search_nulls']) p(name);
28+
1629
\copy test_rum(t) from 'data/rum.data';
1730

1831
CREATE INDEX failed_rumidx ON test_rum USING rum (a rum_tsvector_addon_ops);

src/rum.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@ typedef struct RumState
400400

401401
/* rumutil.c */
402402
extern bytea *rumoptions(Datum reloptions, bool validate);
403+
extern bool rumproperty(Oid index_oid, int attno,
404+
IndexAMProperty prop, const char *propname,
405+
bool *res, bool *isnull);
403406
extern Datum rumhandler(PG_FUNCTION_ARGS);
404407
extern void initRumState(RumState * state, Relation index);
405408
extern Buffer RumNewBuffer(Relation index);

src/rumutil.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
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"
@@ -23,6 +25,7 @@
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)
111114
amroutine->amstorage = true;
112115
amroutine->amclusterable = false;
113116
amroutine->ampredlocks = true;
117+
#if PG_VERSION_NUM >= 100000
118+
amroutine->amcanparallel = false;
119+
#endif
114120
amroutine->amkeytype = InvalidOid;
115121

116122
amroutine->ambuild = rumbuild;
@@ -121,6 +127,7 @@ rumhandler(PG_FUNCTION_ARGS)
121127
amroutine->amcanreturn = NULL;
122128
amroutine->amcostestimate = gincostestimate;
123129
amroutine->amoptions = rumoptions;
130+
amroutine->amproperty = rumproperty;
124131
amroutine->amvalidate = rumvalidate;
125132
amroutine->ambeginscan = rumbeginscan;
126133
amroutine->amrescan = rumrescan;
@@ -129,6 +136,11 @@ rumhandler(PG_FUNCTION_ARGS)
129136
amroutine->amendscan = rumendscan;
130137
amroutine->ammarkpos = NULL;
131138
amroutine->amrestrpos = NULL;
139+
#if PG_VERSION_NUM >= 100000
140+
amroutine->amestimateparallelscan = NULL;
141+
amroutine->aminitparallelscan = NULL;
142+
amroutine->amparallelrescan = NULL;
143+
#endif
132144

133145
PG_RETURN_POINTER(amroutine);
134146
}
@@ -877,6 +889,82 @@ rumoptions(Datum reloptions, bool validate)
877889
return (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
*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy