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

Commit6776142

Browse files
committed
Revise parse tree representation for VACUUM and ANALYZE.
Like commitf41551f, this aimsto make it easier to add non-Boolean options to VACUUM (or, inthis case, to ANALYZE). Instead of building up a bitmap ofoptions directly in the parser, build up a list of DefElemobjects and let ExecVacuum() sort it out; right now, we makeno use of the fact that a DefElem can carry an associated value,but it will be easy to make that change in the future.Masahiko SawadaDiscussion:http://postgr.es/m/CAD21AoATE4sn0jFFH3NcfUZXkU2BMbjBWB_kDj-XWYA-LXDcQA@mail.gmail.com
1 parentf41551f commit6776142

File tree

7 files changed

+116
-86
lines changed

7 files changed

+116
-86
lines changed

‎src/backend/commands/vacuum.c

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,55 @@ static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params);
8383
* happen in vacuum().
8484
*/
8585
void
86-
ExecVacuum(VacuumStmt*vacstmt,boolisTopLevel)
86+
ExecVacuum(ParseState*pstate,VacuumStmt*vacstmt,boolisTopLevel)
8787
{
8888
VacuumParamsparams;
89+
ListCell*lc;
90+
91+
params.options=vacstmt->is_vacuumcmd ?VACOPT_VACUUM :VACOPT_ANALYZE;
92+
93+
/* Parse options list */
94+
foreach(lc,vacstmt->options)
95+
{
96+
DefElem*opt= (DefElem*)lfirst(lc);
97+
98+
/* Parse common options for VACUUM and ANALYZE */
99+
if (strcmp(opt->defname,"verbose")==0)
100+
params.options |=VACOPT_VERBOSE;
101+
elseif (strcmp(opt->defname,"skip_locked")==0)
102+
params.options |=VACOPT_SKIP_LOCKED;
103+
elseif (!vacstmt->is_vacuumcmd)
104+
ereport(ERROR,
105+
(errcode(ERRCODE_SYNTAX_ERROR),
106+
errmsg("unrecognized ANALYZE option \"%s\"",opt->defname),
107+
parser_errposition(pstate,opt->location)));
108+
109+
/* Parse options available on VACUUM */
110+
elseif (strcmp(opt->defname,"analyze")==0)
111+
params.options |=VACOPT_ANALYZE;
112+
elseif (strcmp(opt->defname,"freeze")==0)
113+
params.options |=VACOPT_FREEZE;
114+
elseif (strcmp(opt->defname,"full")==0)
115+
params.options |=VACOPT_FULL;
116+
elseif (strcmp(opt->defname,"disable_page_skipping")==0)
117+
params.options |=VACOPT_DISABLE_PAGE_SKIPPING;
118+
else
119+
ereport(ERROR,
120+
(errcode(ERRCODE_SYNTAX_ERROR),
121+
errmsg("unrecognized VACUUM option \"%s\"",opt->defname),
122+
parser_errposition(pstate,opt->location)));
123+
}
89124

90125
/* sanity checks on options */
91-
Assert(vacstmt->options& (VACOPT_VACUUM |VACOPT_ANALYZE));
92-
Assert((vacstmt->options&VACOPT_VACUUM)||
93-
!(vacstmt->options& (VACOPT_FULL |VACOPT_FREEZE)));
94-
Assert(!(vacstmt->options&VACOPT_SKIPTOAST));
126+
Assert(params.options& (VACOPT_VACUUM |VACOPT_ANALYZE));
127+
Assert((params.options&VACOPT_VACUUM)||
128+
!(params.options& (VACOPT_FULL |VACOPT_FREEZE)));
129+
Assert(!(params.options&VACOPT_SKIPTOAST));
95130

96131
/*
97132
* Make sure VACOPT_ANALYZE is specified if any column lists are present.
98133
*/
99-
if (!(vacstmt->options&VACOPT_ANALYZE))
134+
if (!(params.options&VACOPT_ANALYZE))
100135
{
101136
ListCell*lc;
102137

@@ -111,14 +146,11 @@ ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel)
111146
}
112147
}
113148

114-
/* copy options from parse tree */
115-
params.options=vacstmt->options;
116-
117149
/*
118150
* All freeze ages are zero if the FREEZE option is given; otherwise pass
119151
* them as -1 which means to use the default values.
120152
*/
121-
if (vacstmt->options&VACOPT_FREEZE)
153+
if (params.options&VACOPT_FREEZE)
122154
{
123155
params.freeze_min_age=0;
124156
params.freeze_table_age=0;

‎src/backend/parser/gram.y

Lines changed: 42 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
306306
create_extension_opt_itemalter_extension_opt_item
307307

308308
%type<ival>opt_locklock_typecast_context
309-
%type<ival>vacuum_option_listvacuum_option_elem
310-
analyze_option_listanalyze_option_elem
309+
%type<str>vac_analyze_option_name
310+
%type<defelt>vac_analyze_option_elem
311+
%type<list>vac_analyze_option_list
311312
%type<boolean>opt_or_replace
312313
opt_grant_grant_optionopt_grant_admin_option
313314
opt_nowaitopt_if_existsopt_with_data
@@ -10460,85 +10461,62 @@ cluster_index_specification:
1046010461
VacuumStmt:VACUUMopt_fullopt_freezeopt_verboseopt_analyzeopt_vacuum_relation_list
1046110462
{
1046210463
VacuumStmt *n = makeNode(VacuumStmt);
10463-
n->options =VACOPT_VACUUM;
10464+
n->options =NIL;
1046410465
if ($2)
10465-
n->options |= VACOPT_FULL;
10466+
n->options = lappend(n->options,
10467+
makeDefElem("full",NULL, @2));
1046610468
if ($3)
10467-
n->options |= VACOPT_FREEZE;
10469+
n->options = lappend(n->options,
10470+
makeDefElem("freeze",NULL, @3));
1046810471
if ($4)
10469-
n->options |= VACOPT_VERBOSE;
10472+
n->options = lappend(n->options,
10473+
makeDefElem("verbose",NULL, @4));
1047010474
if ($5)
10471-
n->options |= VACOPT_ANALYZE;
10475+
n->options = lappend(n->options,
10476+
makeDefElem("analyze",NULL, @5));
1047210477
n->rels =$6;
10478+
n->is_vacuumcmd =true;
1047310479
$$ = (Node *)n;
1047410480
}
10475-
|VACUUM'('vacuum_option_list')'opt_vacuum_relation_list
10481+
|VACUUM'('vac_analyze_option_list')'opt_vacuum_relation_list
1047610482
{
1047710483
VacuumStmt *n = makeNode(VacuumStmt);
10478-
n->options =VACOPT_VACUUM |$3;
10484+
n->options =$3;
1047910485
n->rels =$5;
10486+
n->is_vacuumcmd =true;
1048010487
$$ = (Node *) n;
1048110488
}
1048210489
;
1048310490

10484-
vacuum_option_list:
10485-
vacuum_option_elem{$$ =$1; }
10486-
|vacuum_option_list','vacuum_option_elem{$$ =$1 |$3; }
10487-
;
10488-
10489-
vacuum_option_elem:
10490-
analyze_keyword{$$ = VACOPT_ANALYZE; }
10491-
|VERBOSE{$$ = VACOPT_VERBOSE; }
10492-
|FREEZE{$$ = VACOPT_FREEZE; }
10493-
|FULL{$$ = VACOPT_FULL; }
10494-
|IDENT
10495-
{
10496-
if (strcmp($1,"disable_page_skipping") ==0)
10497-
$$ = VACOPT_DISABLE_PAGE_SKIPPING;
10498-
elseif (strcmp($1,"skip_locked") ==0)
10499-
$$ = VACOPT_SKIP_LOCKED;
10500-
else
10501-
ereport(ERROR,
10502-
(errcode(ERRCODE_SYNTAX_ERROR),
10503-
errmsg("unrecognized VACUUM option\"%s\"", $1),
10504-
parser_errposition(@1)));
10505-
}
10506-
;
10507-
1050810491
AnalyzeStmt:analyze_keywordopt_verboseopt_vacuum_relation_list
1050910492
{
1051010493
VacuumStmt *n = makeNode(VacuumStmt);
10511-
n->options =VACOPT_ANALYZE;
10494+
n->options =NIL;
1051210495
if ($2)
10513-
n->options |= VACOPT_VERBOSE;
10496+
n->options = lappend(n->options,
10497+
makeDefElem("verbose",NULL, @2));
1051410498
n->rels =$3;
10499+
n->is_vacuumcmd =false;
1051510500
$$ = (Node *)n;
1051610501
}
10517-
|analyze_keyword'('analyze_option_list')'opt_vacuum_relation_list
10502+
|analyze_keyword'('vac_analyze_option_list')'opt_vacuum_relation_list
1051810503
{
1051910504
VacuumStmt *n = makeNode(VacuumStmt);
10520-
n->options =VACOPT_ANALYZE |$3;
10505+
n->options =$3;
1052110506
n->rels =$5;
10507+
n->is_vacuumcmd =false;
1052210508
$$ = (Node *) n;
1052310509
}
1052410510
;
1052510511

10526-
analyze_option_list:
10527-
analyze_option_elem{$$ =$1; }
10528-
|analyze_option_list','analyze_option_elem{$$ =$1 |$3; }
10529-
;
10530-
10531-
analyze_option_elem:
10532-
VERBOSE{$$ = VACOPT_VERBOSE; }
10533-
|IDENT
10512+
vac_analyze_option_list:
10513+
vac_analyze_option_elem
1053410514
{
10535-
if (strcmp($1,"skip_locked") ==0)
10536-
$$ = VACOPT_SKIP_LOCKED;
10537-
else
10538-
ereport(ERROR,
10539-
(errcode(ERRCODE_SYNTAX_ERROR),
10540-
errmsg("unrecognized ANALYZE option\"%s\"", $1),
10541-
parser_errposition(@1)));
10515+
$$ = list_make1($1);
10516+
}
10517+
|vac_analyze_option_list','vac_analyze_option_elem
10518+
{
10519+
$$ = lappend($1,$3);
1054210520
}
1054310521
;
1054410522

@@ -10547,6 +10525,18 @@ analyze_keyword:
1054710525
|ANALYSE/* British*/{}
1054810526
;
1054910527

10528+
vac_analyze_option_elem:
10529+
vac_analyze_option_name
10530+
{
10531+
$$ = makeDefElem($1,NULL,@1);
10532+
}
10533+
;
10534+
10535+
vac_analyze_option_name:
10536+
NonReservedWord{$$ =$1; }
10537+
|analyze_keyword{$$ ="analyze"; }
10538+
;
10539+
1055010540
opt_analyze:
1055110541
analyze_keyword{$$ =true; }
1055210542
|/*EMPTY*/{$$ =false; }

‎src/backend/tcop/utility.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -664,10 +664,10 @@ standard_ProcessUtility(PlannedStmt *pstmt,
664664
VacuumStmt*stmt= (VacuumStmt*)parsetree;
665665

666666
/* we choose to allow this during "read only" transactions */
667-
PreventCommandDuringRecovery((stmt->options&VACOPT_VACUUM) ?
667+
PreventCommandDuringRecovery(stmt->is_vacuumcmd ?
668668
"VACUUM" :"ANALYZE");
669669
/* forbidden in parallel mode due to CommandIsReadOnly */
670-
ExecVacuum(stmt,isTopLevel);
670+
ExecVacuum(pstate,stmt,isTopLevel);
671671
}
672672
break;
673673

@@ -2570,7 +2570,7 @@ CreateCommandTag(Node *parsetree)
25702570
break;
25712571

25722572
caseT_VacuumStmt:
2573-
if (((VacuumStmt*)parsetree)->options&VACOPT_VACUUM)
2573+
if (((VacuumStmt*)parsetree)->is_vacuumcmd)
25742574
tag="VACUUM";
25752575
else
25762576
tag="ANALYZE";

‎src/include/commands/vacuum.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,23 @@ typedef struct VacAttrStats
136136
introwstride;
137137
}VacAttrStats;
138138

139+
typedefenumVacuumOption
140+
{
141+
VACOPT_VACUUM=1 <<0,/* do VACUUM */
142+
VACOPT_ANALYZE=1 <<1,/* do ANALYZE */
143+
VACOPT_VERBOSE=1 <<2,/* print progress info */
144+
VACOPT_FREEZE=1 <<3,/* FREEZE option */
145+
VACOPT_FULL=1 <<4,/* FULL (non-concurrent) vacuum */
146+
VACOPT_SKIP_LOCKED=1 <<5,/* skip if cannot get lock */
147+
VACOPT_SKIPTOAST=1 <<6,/* don't process the TOAST table, if any */
148+
VACOPT_DISABLE_PAGE_SKIPPING=1 <<7/* don't skip any pages */
149+
}VacuumOption;
150+
139151
/*
140152
* Parameters customizing behavior of VACUUM and ANALYZE.
153+
*
154+
* Note that at least one of VACOPT_VACUUM and VACOPT_ANALYZE must be set
155+
* in options.
141156
*/
142157
typedefstructVacuumParams
143158
{
@@ -163,7 +178,7 @@ extern intvacuum_multixact_freeze_table_age;
163178

164179

165180
/* in commands/vacuum.c */
166-
externvoidExecVacuum(VacuumStmt*vacstmt,boolisTopLevel);
181+
externvoidExecVacuum(ParseState*pstate,VacuumStmt*vacstmt,boolisTopLevel);
167182
externvoidvacuum(List*relations,VacuumParams*params,
168183
BufferAccessStrategybstrategy,boolisTopLevel);
169184
externvoidvac_open_indexes(Relationrelation,LOCKMODElockmode,

‎src/include/nodes/parsenodes.h

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3151,21 +3151,16 @@ typedef struct ClusterStmt
31513151
*Vacuum and Analyze Statements
31523152
*
31533153
* Even though these are nominally two statements, it's convenient to use
3154-
* just one node type for both. Note that at least one of VACOPT_VACUUM
3155-
* and VACOPT_ANALYZE must be set in options.
3154+
* just one node type for both.
31563155
* ----------------------
31573156
*/
3158-
typedefenumVacuumOption
3157+
typedefstructVacuumStmt
31593158
{
3160-
VACOPT_VACUUM=1 <<0,/* do VACUUM */
3161-
VACOPT_ANALYZE=1 <<1,/* do ANALYZE */
3162-
VACOPT_VERBOSE=1 <<2,/* print progress info */
3163-
VACOPT_FREEZE=1 <<3,/* FREEZE option */
3164-
VACOPT_FULL=1 <<4,/* FULL (non-concurrent) vacuum */
3165-
VACOPT_SKIP_LOCKED=1 <<5,/* skip if cannot get lock */
3166-
VACOPT_SKIPTOAST=1 <<6,/* don't process the TOAST table, if any */
3167-
VACOPT_DISABLE_PAGE_SKIPPING=1 <<7/* don't skip any pages */
3168-
}VacuumOption;
3159+
NodeTagtype;
3160+
List*options;/* list of DefElem nodes */
3161+
List*rels;/* list of VacuumRelation, or NIL for all */
3162+
boolis_vacuumcmd;/* true for VACUUM, false for ANALYZE */
3163+
}VacuumStmt;
31693164

31703165
/*
31713166
* Info about a single target table of VACUUM/ANALYZE.
@@ -3182,13 +3177,6 @@ typedef struct VacuumRelation
31823177
List*va_cols;/* list of column names, or NIL for all */
31833178
}VacuumRelation;
31843179

3185-
typedefstructVacuumStmt
3186-
{
3187-
NodeTagtype;
3188-
intoptions;/* OR of VacuumOption flags */
3189-
List*rels;/* list of VacuumRelation, or NIL for all */
3190-
}VacuumStmt;
3191-
31923180
/* ----------------------
31933181
*Explain Statement
31943182
*

‎src/test/regress/expected/vacuum.out

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,12 @@ ERROR: column "does_not_exist" of relation "vacparted" does not exist
116116
ANALYZE (VERBOSE) does_not_exist;
117117
ERROR: relation "does_not_exist" does not exist
118118
ANALYZE (nonexistent-arg) does_not_exist;
119-
ERROR:unrecognized ANALYZE option "nonexistent"
119+
ERROR:syntax error at or near "-"
120120
LINE 1: ANALYZE (nonexistent-arg) does_not_exist;
121+
^
122+
ANALYZE (nonexistentarg) does_not_exit;
123+
ERROR: unrecognized ANALYZE option "nonexistentarg"
124+
LINE 1: ANALYZE (nonexistentarg) does_not_exit;
121125
^
122126
-- ensure argument order independence, and that SKIP_LOCKED on non-existing
123127
-- relation still errors out.

‎src/test/regress/sql/vacuum.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ ANALYZE vactst (i), vacparted (does_not_exist);
9292
-- parenthesized syntax for ANALYZE
9393
ANALYZE (VERBOSE) does_not_exist;
9494
ANALYZE (nonexistent-arg) does_not_exist;
95+
ANALYZE (nonexistentarg) does_not_exit;
9596

9697
-- ensure argument order independence, and that SKIP_LOCKED on non-existing
9798
-- relation still errors out.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp