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

Commit773df88

Browse files
committed
Support reloptions of enum type
All our current in core relation options of type string (not many,admittedly) behave in reality like enums. But after seeing animplementation for enum reloptions, it's clear that strings are messier,so introduce the new reloption type. Switch all string options to beenums instead.Fortunately we have a recently introduced test module for reloptions, sowe don't lose coverage of string reloptions, which may still be used bythird-party modules.Authors: Nikolay Shaplov, Álvaro HerreraReviewed-by: Nikita Glukhov, Aleksandr ParfenovDiscussion:https://postgr.es/m/43332102.S2V5pIjXRx@x200m
1 parentcaba97a commit773df88

File tree

12 files changed

+214
-75
lines changed

12 files changed

+214
-75
lines changed

‎src/backend/access/common/reloptions.c

Lines changed: 121 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,25 @@ static relopt_real realRelOpts[] =
433433
{{NULL}}
434434
};
435435

436-
staticrelopt_stringstringRelOpts[]=
436+
/* values from GistOptBufferingMode */
437+
relopt_enum_elt_defgistBufferingOptValues[]=
438+
{
439+
{"auto",GIST_OPTION_BUFFERING_AUTO},
440+
{"on",GIST_OPTION_BUFFERING_ON},
441+
{"off",GIST_OPTION_BUFFERING_OFF},
442+
{(constchar*)NULL}/* list terminator */
443+
};
444+
445+
/* values from ViewOptCheckOption */
446+
relopt_enum_elt_defviewCheckOptValues[]=
447+
{
448+
/* no value for NOT_SET */
449+
{"local",VIEW_OPTION_CHECK_OPTION_LOCAL},
450+
{"cascaded",VIEW_OPTION_CHECK_OPTION_CASCADED},
451+
{(constchar*)NULL}/* list terminator */
452+
};
453+
454+
staticrelopt_enumenumRelOpts[]=
437455
{
438456
{
439457
{
@@ -442,10 +460,9 @@ static relopt_string stringRelOpts[] =
442460
RELOPT_KIND_GIST,
443461
AccessExclusiveLock
444462
},
445-
4,
446-
false,
447-
gistValidateBufferingOption,
448-
"auto"
463+
gistBufferingOptValues,
464+
GIST_OPTION_BUFFERING_AUTO,
465+
gettext_noop("Valid values are \"on\", \"off\", and \"auto\".")
449466
},
450467
{
451468
{
@@ -454,15 +471,20 @@ static relopt_string stringRelOpts[] =
454471
RELOPT_KIND_VIEW,
455472
AccessExclusiveLock
456473
},
457-
0,
458-
true,
459-
validateWithCheckOption,
460-
NULL
474+
viewCheckOptValues,
475+
VIEW_OPTION_CHECK_OPTION_NOT_SET,
476+
gettext_noop("Valid values are \"local\" and \"cascaded\".")
461477
},
462478
/* list terminator */
463479
{{NULL}}
464480
};
465481

482+
staticrelopt_stringstringRelOpts[]=
483+
{
484+
/* list terminator */
485+
{{NULL}}
486+
};
487+
466488
staticrelopt_gen**relOpts=NULL;
467489
staticbits32last_assigned_kind=RELOPT_KIND_LAST_DEFAULT;
468490

@@ -505,6 +527,12 @@ initialize_reloptions(void)
505527
realRelOpts[i].gen.lockmode));
506528
j++;
507529
}
530+
for (i=0;enumRelOpts[i].gen.name;i++)
531+
{
532+
Assert(DoLockModesConflict(enumRelOpts[i].gen.lockmode,
533+
enumRelOpts[i].gen.lockmode));
534+
j++;
535+
}
508536
for (i=0;stringRelOpts[i].gen.name;i++)
509537
{
510538
Assert(DoLockModesConflict(stringRelOpts[i].gen.lockmode,
@@ -543,6 +571,14 @@ initialize_reloptions(void)
543571
j++;
544572
}
545573

574+
for (i=0;enumRelOpts[i].gen.name;i++)
575+
{
576+
relOpts[j]=&enumRelOpts[i].gen;
577+
relOpts[j]->type=RELOPT_TYPE_ENUM;
578+
relOpts[j]->namelen=strlen(relOpts[j]->name);
579+
j++;
580+
}
581+
546582
for (i=0;stringRelOpts[i].gen.name;i++)
547583
{
548584
relOpts[j]=&stringRelOpts[i].gen;
@@ -641,6 +677,9 @@ allocate_reloption(bits32 kinds, int type, const char *name, const char *desc,
641677
caseRELOPT_TYPE_REAL:
642678
size=sizeof(relopt_real);
643679
break;
680+
caseRELOPT_TYPE_ENUM:
681+
size=sizeof(relopt_enum);
682+
break;
644683
caseRELOPT_TYPE_STRING:
645684
size=sizeof(relopt_string);
646685
break;
@@ -661,6 +700,13 @@ allocate_reloption(bits32 kinds, int type, const char *name, const char *desc,
661700
newoption->type=type;
662701
newoption->lockmode=lockmode;
663702

703+
/*
704+
* Set the default lock mode for this option. There is no actual way
705+
* for a module to enforce it when declaring a custom relation option,
706+
* so just use the highest level, which is safe for all cases.
707+
*/
708+
newoption->lockmode=AccessExclusiveLock;
709+
664710
MemoryContextSwitchTo(oldcxt);
665711

666712
returnnewoption;
@@ -721,6 +767,34 @@ add_real_reloption(bits32 kinds, const char *name, const char *desc, double defa
721767
add_reloption((relopt_gen*)newoption);
722768
}
723769

770+
/*
771+
* add_enum_reloption
772+
*Add a new enum reloption
773+
*
774+
* The members array must have a terminating NULL entry.
775+
*
776+
* The detailmsg is shown when unsupported values are passed, and has this
777+
* form: "Valid values are \"foo\", \"bar\", and \"bar\"."
778+
*
779+
* The members array and detailmsg are not copied -- caller must ensure that
780+
* they are valid throughout the life of the process.
781+
*/
782+
void
783+
add_enum_reloption(bits32kinds,constchar*name,constchar*desc,
784+
relopt_enum_elt_def*members,intdefault_val,
785+
constchar*detailmsg,LOCKMODElockmode)
786+
{
787+
relopt_enum*newoption;
788+
789+
newoption= (relopt_enum*)allocate_reloption(kinds,RELOPT_TYPE_ENUM,
790+
name,desc,lockmode);
791+
newoption->members=members;
792+
newoption->default_val=default_val;
793+
newoption->detailmsg=detailmsg;
794+
795+
add_reloption((relopt_gen*)newoption);
796+
}
797+
724798
/*
725799
* add_string_reloption
726800
*Add a new string reloption
@@ -1237,6 +1311,37 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len,
12371311
optreal->min,optreal->max)));
12381312
}
12391313
break;
1314+
caseRELOPT_TYPE_ENUM:
1315+
{
1316+
relopt_enum*optenum= (relopt_enum*)option->gen;
1317+
relopt_enum_elt_def*elt;
1318+
1319+
parsed= false;
1320+
for (elt=optenum->members;elt->string_val;elt++)
1321+
{
1322+
if (pg_strcasecmp(value,elt->string_val)==0)
1323+
{
1324+
option->values.enum_val=elt->symbol_val;
1325+
parsed= true;
1326+
break;
1327+
}
1328+
}
1329+
if (validate&& !parsed)
1330+
ereport(ERROR,
1331+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1332+
errmsg("invalid value for enum option \"%s\": %s",
1333+
option->gen->name,value),
1334+
optenum->detailmsg ?
1335+
errdetail_internal("%s",_(optenum->detailmsg)) :0));
1336+
1337+
/*
1338+
* If value is not among the allowed string values, but we are
1339+
* not asked to validate, just use the default numeric value.
1340+
*/
1341+
if (!parsed)
1342+
option->values.enum_val=optenum->default_val;
1343+
}
1344+
break;
12401345
caseRELOPT_TYPE_STRING:
12411346
{
12421347
relopt_string*optstring= (relopt_string*)option->gen;
@@ -1330,6 +1435,11 @@ fillRelOptions(void *rdopts, Size basesize,
13301435
options[i].values.real_val :
13311436
((relopt_real*)options[i].gen)->default_val;
13321437
break;
1438+
caseRELOPT_TYPE_ENUM:
1439+
*(int*)itempos=options[i].isset ?
1440+
options[i].values.enum_val :
1441+
((relopt_enum*)options[i].gen)->default_val;
1442+
break;
13331443
caseRELOPT_TYPE_STRING:
13341444
optstring= (relopt_string*)options[i].gen;
13351445
if (options[i].isset)
@@ -1446,8 +1556,8 @@ view_reloptions(Datum reloptions, bool validate)
14461556
staticconstrelopt_parse_elttab[]= {
14471557
{"security_barrier",RELOPT_TYPE_BOOL,
14481558
offsetof(ViewOptions,security_barrier)},
1449-
{"check_option",RELOPT_TYPE_STRING,
1450-
offsetof(ViewOptions,check_option_offset)}
1559+
{"check_option",RELOPT_TYPE_ENUM,
1560+
offsetof(ViewOptions,check_option)}
14511561
};
14521562

14531563
options=parseRelOptions(reloptions,validate,RELOPT_KIND_VIEW,&numoptions);

‎src/backend/access/gist/gistbuild.c

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,15 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
125125

126126
buildstate.indexrel=index;
127127
buildstate.heaprel=heap;
128+
128129
if (index->rd_options)
129130
{
130131
/* Get buffering mode from the options string */
131132
GiSTOptions*options= (GiSTOptions*)index->rd_options;
132-
char*bufferingMode= (char*)options+options->bufferingModeOffset;
133133

134-
if (strcmp(bufferingMode,"on")==0)
134+
if (options->buffering_mode==GIST_OPTION_BUFFERING_ON)
135135
buildstate.bufferingMode=GIST_BUFFERING_STATS;
136-
elseif (strcmp(bufferingMode,"off")==0)
136+
elseif (options->buffering_mode==GIST_OPTION_BUFFERING_OFF)
137137
buildstate.bufferingMode=GIST_BUFFERING_DISABLED;
138138
else
139139
buildstate.bufferingMode=GIST_BUFFERING_AUTO;
@@ -236,25 +236,6 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
236236
returnresult;
237237
}
238238

239-
/*
240-
* Validator for "buffering" reloption on GiST indexes. Allows "on", "off"
241-
* and "auto" values.
242-
*/
243-
void
244-
gistValidateBufferingOption(constchar*value)
245-
{
246-
if (value==NULL||
247-
(strcmp(value,"on")!=0&&
248-
strcmp(value,"off")!=0&&
249-
strcmp(value,"auto")!=0))
250-
{
251-
ereport(ERROR,
252-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
253-
errmsg("invalid value for \"buffering\" option"),
254-
errdetail("Valid values are \"on\", \"off\", and \"auto\".")));
255-
}
256-
}
257-
258239
/*
259240
* Attempt to switch to buffering mode.
260241
*

‎src/backend/access/gist/gistutil.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ gistoptions(Datum reloptions, bool validate)
913913
intnumoptions;
914914
staticconstrelopt_parse_elttab[]= {
915915
{"fillfactor",RELOPT_TYPE_INT, offsetof(GiSTOptions,fillfactor)},
916-
{"buffering",RELOPT_TYPE_STRING, offsetof(GiSTOptions,bufferingModeOffset)}
916+
{"buffering",RELOPT_TYPE_ENUM, offsetof(GiSTOptions,buffering_mode)}
917917
};
918918

919919
options=parseRelOptions(reloptions,validate,RELOPT_KIND_GIST,

‎src/backend/commands/view.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,6 @@
3838

3939
staticvoidcheckViewTupleDesc(TupleDescnewdesc,TupleDescolddesc);
4040

41-
/*---------------------------------------------------------------------
42-
* Validator for "check_option" reloption on views. The allowed values
43-
* are "local" and "cascaded".
44-
*/
45-
void
46-
validateWithCheckOption(constchar*value)
47-
{
48-
if (value==NULL||
49-
(strcmp(value,"local")!=0&&
50-
strcmp(value,"cascaded")!=0))
51-
{
52-
ereport(ERROR,
53-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
54-
errmsg("invalid value for \"check_option\" option"),
55-
errdetail("Valid values are \"local\" and \"cascaded\".")));
56-
}
57-
}
58-
5941
/*---------------------------------------------------------------------
6042
* DefineVirtualRelation
6143
*

‎src/include/access/gist_private.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,14 +380,22 @@ typedef struct GISTBuildBuffers
380380
introotlevel;
381381
}GISTBuildBuffers;
382382

383+
/* GiSTOptions->buffering_mode values */
384+
typedefenumGistOptBufferingMode
385+
{
386+
GIST_OPTION_BUFFERING_AUTO,
387+
GIST_OPTION_BUFFERING_ON,
388+
GIST_OPTION_BUFFERING_OFF
389+
}GistOptBufferingMode;
390+
383391
/*
384392
* Storage type for GiST's reloptions
385393
*/
386394
typedefstructGiSTOptions
387395
{
388396
int32vl_len_;/* varlena header (do not touch directly!) */
389397
intfillfactor;/* page fill factor in percent (0..100) */
390-
intbufferingModeOffset;/*usebuffering build? */
398+
GistOptBufferingModebuffering_mode;/* buffering build mode */
391399
}GiSTOptions;
392400

393401
/* gist.c */

‎src/include/access/reloptions.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ typedef enum relopt_type
3131
RELOPT_TYPE_BOOL,
3232
RELOPT_TYPE_INT,
3333
RELOPT_TYPE_REAL,
34+
RELOPT_TYPE_ENUM,
3435
RELOPT_TYPE_STRING
3536
}relopt_type;
3637

@@ -80,6 +81,7 @@ typedef struct relopt_value
8081
boolbool_val;
8182
intint_val;
8283
doublereal_val;
84+
intenum_val;
8385
char*string_val;/* allocated separately */
8486
}values;
8587
}relopt_value;
@@ -107,6 +109,25 @@ typedef struct relopt_real
107109
doublemax;
108110
}relopt_real;
109111

112+
/*
113+
* relopt_enum_elt_def -- One member of the array of acceptable values
114+
* of an enum reloption.
115+
*/
116+
typedefstructrelopt_enum_elt_def
117+
{
118+
constchar*string_val;
119+
intsymbol_val;
120+
}relopt_enum_elt_def;
121+
122+
typedefstructrelopt_enum
123+
{
124+
relopt_gengen;
125+
relopt_enum_elt_def*members;
126+
intdefault_val;
127+
constchar*detailmsg;
128+
/* null-terminated array of members */
129+
}relopt_enum;
130+
110131
/* validation routines for strings */
111132
typedefvoid (*validate_string_relopt) (constchar*value);
112133

@@ -254,6 +275,9 @@ extern void add_int_reloption(bits32 kinds, const char *name, const char *desc,
254275
externvoidadd_real_reloption(bits32kinds,constchar*name,constchar*desc,
255276
doubledefault_val,doublemin_val,doublemax_val,
256277
LOCKMODElockmode);
278+
externvoidadd_enum_reloption(bits32kinds,constchar*name,constchar*desc,
279+
relopt_enum_elt_def*members,intdefault_val,
280+
constchar*detailmsg,LOCKMODElockmode);
257281
externvoidadd_string_reloption(bits32kinds,constchar*name,constchar*desc,
258282
constchar*default_val,validate_string_reloptvalidator,
259283
LOCKMODElockmode);

‎src/include/commands/view.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
#include"catalog/objectaddress.h"
1818
#include"nodes/parsenodes.h"
1919

20-
externvoidvalidateWithCheckOption(constchar*value);
21-
2220
externObjectAddressDefineView(ViewStmt*stmt,constchar*queryString,
2321
intstmt_location,intstmt_len);
2422

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp