Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit640c198

Browse files
committed
Add dummy_index_am to src/test/modules/
This includes more tests dedicated to relation options, bringing thecoverage of this code close to 100%, and the module can be used forother purposes, like a base template for an index AM implementation.Author: Nikolay Sharplov, Michael PaquierReviewed-by: Álvaro Herrera, Dent JohnDiscussion:https://postgr.es/m/17071942.m9zZutALE6@x200m
1 parent69f9410 commit640c198

File tree

10 files changed

+555
-0
lines changed

10 files changed

+555
-0
lines changed

‎src/test/modules/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ include $(top_builddir)/src/Makefile.global
77
SUBDIRS =\
88
brin\
99
commit_ts\
10+
dummy_index_am\
1011
dummy_seclabel\
1112
snapshot_too_old\
1213
test_bloomfilter\
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Generated subdirectories
2+
/log/
3+
/results/
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# src/test/modules/dummy_index_am/Makefile
2+
3+
MODULES = dummy_index_am
4+
5+
EXTENSION = dummy_index_am
6+
DATA = dummy_index_am--1.0.sql
7+
PGFILEDESC = "dummy_index_am - index access method template"
8+
9+
REGRESS = reloptions
10+
11+
ifdefUSE_PGXS
12+
PG_CONFIG = pg_config
13+
PGXS :=$(shell$(PG_CONFIG) --pgxs)
14+
include$(PGXS)
15+
else
16+
subdir = src/test/modules/dummy_index_am
17+
top_builddir = ../../../..
18+
include$(top_builddir)/src/Makefile.global
19+
include$(top_srcdir)/contrib/contrib-global.mk
20+
endif
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Dummy Index AM
2+
==============
3+
4+
Dummy index AM is a module for testing any facility usable by an index
5+
access method, whose code is kept a maximum simple.
6+
7+
This includes tests for all relation option types:
8+
- boolean
9+
- integer
10+
- real
11+
- strings (with and without NULL as default)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* src/test/modules/dummy_index_am/dummy_index_am--1.0.sql*/
2+
3+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
4+
\echo Use"CREATE EXTENSION dummy_index_am" to load this file. \quit
5+
6+
CREATEFUNCTIONdihandler(internal)
7+
RETURNS index_am_handler
8+
AS'MODULE_PATHNAME'
9+
LANGUAGE C;
10+
11+
-- Access method
12+
CREATE ACCESS METHOD dummy_index_am TYPE INDEX HANDLER dihandler;
13+
COMMENTON ACCESS METHOD dummy_index_am IS'dummy index access method';
14+
15+
-- Operator classes
16+
CREATEOPERATOR CLASSint4_ops
17+
DEFAULT FOR TYPE int4 USING dummy_index_amAS
18+
OPERATOR1= (int4, int4),
19+
FUNCTION1 hashint4(int4);
Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* dummy_index_am.c
4+
*Index AM template main file.
5+
*
6+
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7+
* Portions Copyright (c) 1994, Regents of the University of California
8+
*
9+
* IDENTIFICATION
10+
* src/test/modules/dummy_index_am/dummy_index_am.c
11+
*
12+
*-------------------------------------------------------------------------
13+
*/
14+
#include"postgres.h"
15+
16+
#include"access/amapi.h"
17+
#include"access/reloptions.h"
18+
#include"catalog/index.h"
19+
#include"nodes/pathnodes.h"
20+
#include"utils/guc.h"
21+
#include"utils/rel.h"
22+
23+
PG_MODULE_MAGIC;
24+
25+
void_PG_init(void);
26+
27+
/* parse table for fillRelOptions */
28+
relopt_parse_eltdi_relopt_tab[5];
29+
30+
/* Kind of relation options for dummy index */
31+
relopt_kinddi_relopt_kind;
32+
33+
/* Dummy index options */
34+
typedefstructDummyIndexOptions
35+
{
36+
int32vl_len_;/* varlena header (do not touch directly!) */
37+
intoption_int;
38+
doubleoption_real;
39+
booloption_bool;
40+
intoption_string_val_offset;
41+
intoption_string_null_offset;
42+
}DummyIndexOptions;
43+
44+
/* Handler for index AM */
45+
PG_FUNCTION_INFO_V1(dihandler);
46+
47+
/*
48+
* Validation function for string relation options.
49+
*/
50+
staticvoid
51+
validate_string_option(constchar*value)
52+
{
53+
ereport(NOTICE,
54+
(errmsg("new option value for string parameter %s",
55+
value ?value :"NULL")));
56+
}
57+
58+
/*
59+
* This function creates a full set of relation option types,
60+
* with various patterns.
61+
*/
62+
staticvoid
63+
create_reloptions_table(void)
64+
{
65+
di_relopt_kind=add_reloption_kind();
66+
67+
add_int_reloption(di_relopt_kind,"option_int",
68+
"Integer option for dummy_index_am",
69+
10,-10,100,AccessExclusiveLock);
70+
di_relopt_tab[0].optname="option_int";
71+
di_relopt_tab[0].opttype=RELOPT_TYPE_INT;
72+
di_relopt_tab[0].offset= offsetof(DummyIndexOptions,option_int);
73+
74+
add_real_reloption(di_relopt_kind,"option_real",
75+
"Real option for dummy_index_am",
76+
3.1415,-10,100,AccessExclusiveLock);
77+
di_relopt_tab[1].optname="option_real";
78+
di_relopt_tab[1].opttype=RELOPT_TYPE_REAL;
79+
di_relopt_tab[1].offset= offsetof(DummyIndexOptions,option_real);
80+
81+
add_bool_reloption(di_relopt_kind,"option_bool",
82+
"Boolean option for dummy_index_am",
83+
true,AccessExclusiveLock);
84+
di_relopt_tab[2].optname="option_bool";
85+
di_relopt_tab[2].opttype=RELOPT_TYPE_BOOL;
86+
di_relopt_tab[2].offset= offsetof(DummyIndexOptions,option_bool);
87+
88+
add_string_reloption(di_relopt_kind,"option_string_val",
89+
"String option for dummy_index_am with non-NULL default",
90+
"DefaultValue",&validate_string_option,
91+
AccessExclusiveLock);
92+
di_relopt_tab[3].optname="option_string_val";
93+
di_relopt_tab[3].opttype=RELOPT_TYPE_STRING;
94+
di_relopt_tab[3].offset= offsetof(DummyIndexOptions,
95+
option_string_val_offset);
96+
97+
/*
98+
* String option for dummy_index_am with NULL default, and without
99+
* description.
100+
*/
101+
add_string_reloption(di_relopt_kind,"option_string_null",
102+
NULL,/* description */
103+
NULL,&validate_string_option,
104+
AccessExclusiveLock);
105+
di_relopt_tab[4].optname="option_string_null";
106+
di_relopt_tab[4].opttype=RELOPT_TYPE_STRING;
107+
di_relopt_tab[4].offset= offsetof(DummyIndexOptions,
108+
option_string_null_offset);
109+
}
110+
111+
112+
/*
113+
* Build a new index.
114+
*/
115+
staticIndexBuildResult*
116+
dibuild(Relationheap,Relationindex,IndexInfo*indexInfo)
117+
{
118+
IndexBuildResult*result;
119+
120+
result= (IndexBuildResult*)palloc(sizeof(IndexBuildResult));
121+
122+
/* let's pretend that no tuples were scanned */
123+
result->heap_tuples=0;
124+
/* and no index tuples were created (that is true) */
125+
result->index_tuples=0;
126+
127+
returnresult;
128+
}
129+
130+
/*
131+
* Build an empty index for the initialiation fork.
132+
*/
133+
staticvoid
134+
dibuildempty(Relationindex)
135+
{
136+
/* No need to build an init fork for a dummy index */
137+
}
138+
139+
/*
140+
* Insert new tuple to index AM.
141+
*/
142+
staticbool
143+
diinsert(Relationindex,Datum*values,bool*isnull,
144+
ItemPointerht_ctid,RelationheapRel,
145+
IndexUniqueCheckcheckUnique,
146+
IndexInfo*indexInfo)
147+
{
148+
/* nothing to do */
149+
return false;
150+
}
151+
152+
/*
153+
* Bulk deletion of all index entries pointing to a set of table tuples.
154+
*/
155+
staticIndexBulkDeleteResult*
156+
dibulkdelete(IndexVacuumInfo*info,IndexBulkDeleteResult*stats,
157+
IndexBulkDeleteCallbackcallback,void*callback_state)
158+
{
159+
/*
160+
* There is nothing to delete. Return NULL as there is nothing to pass to
161+
* amvacuumcleanup.
162+
*/
163+
returnNULL;
164+
}
165+
166+
/*
167+
* Post-VACUUM cleanup for index AM.
168+
*/
169+
staticIndexBulkDeleteResult*
170+
divacuumcleanup(IndexVacuumInfo*info,IndexBulkDeleteResult*stats)
171+
{
172+
/* Index has not been modified, so returning NULL is fine */
173+
returnNULL;
174+
}
175+
176+
/*
177+
* Estimate cost of index AM.
178+
*/
179+
staticvoid
180+
dicostestimate(PlannerInfo*root,IndexPath*path,doubleloop_count,
181+
Cost*indexStartupCost,Cost*indexTotalCost,
182+
Selectivity*indexSelectivity,double*indexCorrelation,
183+
double*indexPages)
184+
{
185+
/* Tell planner to never use this index! */
186+
*indexStartupCost=1.0e10;
187+
*indexTotalCost=1.0e10;
188+
189+
/* Do not care about the rest */
190+
*indexSelectivity=1;
191+
*indexCorrelation=0;
192+
*indexPages=1;
193+
}
194+
195+
/*
196+
* Parse relation options for index AM, returning a DummyIndexOptions
197+
* structure filled with option values.
198+
*/
199+
staticbytea*
200+
dioptions(Datumreloptions,boolvalidate)
201+
{
202+
relopt_value*options;
203+
intnumoptions;
204+
DummyIndexOptions*rdopts;
205+
206+
/* Parse the user-given reloptions */
207+
options=parseRelOptions(reloptions,validate,di_relopt_kind,&numoptions);
208+
rdopts=allocateReloptStruct(sizeof(DummyIndexOptions),options,numoptions);
209+
fillRelOptions((void*)rdopts,sizeof(DummyIndexOptions),options,numoptions,
210+
validate,di_relopt_tab,lengthof(di_relopt_tab));
211+
212+
return (bytea*)rdopts;
213+
}
214+
215+
/*
216+
* Validator for index AM.
217+
*/
218+
staticbool
219+
divalidate(Oidopclassoid)
220+
{
221+
/* Index is dummy so we are happy with any opclass */
222+
return true;
223+
}
224+
225+
/*
226+
* Begin scan of index AM.
227+
*/
228+
staticIndexScanDesc
229+
dibeginscan(Relationr,intnkeys,intnorderbys)
230+
{
231+
IndexScanDescscan;
232+
233+
/* Let's pretend we are doing something */
234+
scan=RelationGetIndexScan(r,nkeys,norderbys);
235+
returnscan;
236+
}
237+
238+
/*
239+
* Rescan of index AM.
240+
*/
241+
staticvoid
242+
direscan(IndexScanDescscan,ScanKeyscankey,intnscankeys,
243+
ScanKeyorderbys,intnorderbys)
244+
{
245+
/* nothing to do */
246+
}
247+
248+
/*
249+
* End scan of index AM.
250+
*/
251+
staticvoid
252+
diendscan(IndexScanDescscan)
253+
{
254+
/* nothing to do */
255+
}
256+
257+
/*
258+
* Index AM handler function: returns IndexAmRoutine with access method
259+
* parameters and callbacks.
260+
*/
261+
Datum
262+
dihandler(PG_FUNCTION_ARGS)
263+
{
264+
IndexAmRoutine*amroutine=makeNode(IndexAmRoutine);
265+
266+
amroutine->amstrategies=0;
267+
amroutine->amsupport=1;
268+
amroutine->amcanorder= false;
269+
amroutine->amcanorderbyop= false;
270+
amroutine->amcanbackward= false;
271+
amroutine->amcanunique= false;
272+
amroutine->amcanmulticol= false;
273+
amroutine->amoptionalkey= false;
274+
amroutine->amsearcharray= false;
275+
amroutine->amsearchnulls= false;
276+
amroutine->amstorage= false;
277+
amroutine->amclusterable= false;
278+
amroutine->ampredlocks= false;
279+
amroutine->amcanparallel= false;
280+
amroutine->amcaninclude= false;
281+
amroutine->amkeytype=InvalidOid;
282+
283+
amroutine->ambuild=dibuild;
284+
amroutine->ambuildempty=dibuildempty;
285+
amroutine->aminsert=diinsert;
286+
amroutine->ambulkdelete=dibulkdelete;
287+
amroutine->amvacuumcleanup=divacuumcleanup;
288+
amroutine->amcanreturn=NULL;
289+
amroutine->amcostestimate=dicostestimate;
290+
amroutine->amoptions=dioptions;
291+
amroutine->amproperty=NULL;
292+
amroutine->ambuildphasename=NULL;
293+
amroutine->amvalidate=divalidate;
294+
amroutine->ambeginscan=dibeginscan;
295+
amroutine->amrescan=direscan;
296+
amroutine->amgettuple=NULL;
297+
amroutine->amgetbitmap=NULL;
298+
amroutine->amendscan=diendscan;
299+
amroutine->ammarkpos=NULL;
300+
amroutine->amrestrpos=NULL;
301+
amroutine->amestimateparallelscan=NULL;
302+
amroutine->aminitparallelscan=NULL;
303+
amroutine->amparallelrescan=NULL;
304+
305+
PG_RETURN_POINTER(amroutine);
306+
}
307+
308+
void
309+
_PG_init(void)
310+
{
311+
create_reloptions_table();
312+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# dummy_index_am extension
2+
comment = 'dummy_index_am - index access method template'
3+
default_version = '1.0'
4+
module_pathname = '$libdir/dummy_index_am'
5+
relocatable = true

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp