Skip to content

Commit a4f1265

Browse files
Add option list to CHECKPOINT command.
This commit adds the boilerplate code for supporting a list of options in CHECKPOINT commands. No actual options are supported yet, but follow-up commits will add support for MODE and FLUSH_UNLOGGED. While at it, this commit refactors the code for executing CHECKPOINT commands to its own function since it's about to become significantly larger. Author: Christoph Berg <myon@debian.org> Reviewed-by: Fujii Masao <masao.fujii@oss.nttdata.com> Discussion: https://postgr.es/m/aDnaKTEf-0dLiEfz%40msg.df7cb.de
1 parent bb938e2 commit a4f1265

File tree

9 files changed

+64
-12
lines changed

9 files changed

+64
-12
lines changed

doc/src/sgml/ref/checkpoint.sgml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
CHECKPOINT
24+
CHECKPOINT [ ( option [, ...] ) ]
25+
26+
<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
2527
</synopsis>
2628
</refsynopsisdiv>
2729

@@ -58,6 +60,13 @@ CHECKPOINT
5860
</para>
5961
</refsect1>
6062

63+
<refsect1>
64+
<title>Parameters</title>
65+
66+
<para>
67+
</para>
68+
</refsect1>
69+
6170
<refsect1>
6271
<title>Compatibility</title>
6372

src/backend/parser/gram.y

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,6 +2034,13 @@ CheckPointStmt:
20342034

20352035
$$ = (Node *) n;
20362036
}
2037+
| CHECKPOINT '(' utility_option_list ')'
2038+
{
2039+
CheckPointStmt *n = makeNode(CheckPointStmt);
2040+
2041+
$$ = (Node *) n;
2042+
n->options = $3;
2043+
}
20372044
;
20382045

20392046

src/backend/postmaster/checkpointer.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "access/xlog.h"
4343
#include "access/xlog_internal.h"
4444
#include "access/xlogrecovery.h"
45+
#include "catalog/pg_authid.h"
4546
#include "libpq/pqsignal.h"
4647
#include "miscadmin.h"
4748
#include "pgstat.h"
@@ -61,6 +62,7 @@
6162
#include "storage/shmem.h"
6263
#include "storage/smgr.h"
6364
#include "storage/spin.h"
65+
#include "utils/acl.h"
6466
#include "utils/guc.h"
6567
#include "utils/memutils.h"
6668
#include "utils/resowner.h"
@@ -976,6 +978,35 @@ CheckpointerShmemInit(void)
976978
}
977979
}
978980

981+
/*
982+
* ExecCheckpoint
983+
* Primary entry point for manual CHECKPOINT commands
984+
*
985+
* This is mainly a wrapper for RequestCheckpoint().
986+
*/
987+
void
988+
ExecCheckpoint(ParseState *pstate, CheckPointStmt *stmt)
989+
{
990+
foreach_ptr(DefElem, opt, stmt->options)
991+
ereport(ERROR,
992+
(errcode(ERRCODE_SYNTAX_ERROR),
993+
errmsg("unrecognized CHECKPOINT option \"%s\"", opt->defname),
994+
parser_errposition(pstate, opt->location)));
995+
996+
if (!has_privs_of_role(GetUserId(), ROLE_PG_CHECKPOINT))
997+
ereport(ERROR,
998+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
999+
/* translator: %s is name of an SQL command (e.g., CHECKPOINT) */
1000+
errmsg("permission denied to execute %s command",
1001+
"CHECKPOINT"),
1002+
errdetail("Only roles with privileges of the \"%s\" role may execute this command.",
1003+
"pg_checkpoint")));
1004+
1005+
RequestCheckpoint(CHECKPOINT_WAIT |
1006+
CHECKPOINT_FAST |
1007+
(RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1008+
}
1009+
9791010
/*
9801011
* RequestCheckpoint
9811012
* Called in backend processes to request a checkpoint

src/backend/tcop/utility.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -943,17 +943,7 @@ standard_ProcessUtility(PlannedStmt *pstmt,
943943
break;
944944

945945
case T_CheckPointStmt:
946-
if (!has_privs_of_role(GetUserId(), ROLE_PG_CHECKPOINT))
947-
ereport(ERROR,
948-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
949-
/* translator: %s is name of a SQL command, eg CHECKPOINT */
950-
errmsg("permission denied to execute %s command",
951-
"CHECKPOINT"),
952-
errdetail("Only roles with privileges of the \"%s\" role may execute this command.",
953-
"pg_checkpoint")));
954-
955-
RequestCheckpoint(CHECKPOINT_FAST | CHECKPOINT_WAIT |
956-
(RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
946+
ExecCheckpoint(pstate, (CheckPointStmt *) parsetree);
957947
break;
958948

959949
/*

src/bin/psql/tab-complete.in.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3153,6 +3153,9 @@ match_previous_words(int pattern_id,
31533153
COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures);
31543154
else if (Matches("CALL", MatchAny))
31553155
COMPLETE_WITH("(");
3156+
/* CHECKPOINT */
3157+
else if (Matches("CHECKPOINT"))
3158+
COMPLETE_WITH("(");
31563159
/* CLOSE */
31573160
else if (Matches("CLOSE"))
31583161
COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_cursors,

src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4047,6 +4047,7 @@ typedef struct RefreshMatViewStmt
40474047
typedef struct CheckPointStmt
40484048
{
40494049
NodeTag type;
4050+
List *options; /* list of DefElem nodes */
40504051
} CheckPointStmt;
40514052

40524053
/* ----------------------

src/include/postmaster/bgwriter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef _BGWRITER_H
1616
#define _BGWRITER_H
1717

18+
#include "parser/parse_node.h"
1819
#include "storage/block.h"
1920
#include "storage/relfilelocator.h"
2021
#include "storage/smgr.h"
@@ -30,6 +31,7 @@ extern PGDLLIMPORT double CheckPointCompletionTarget;
3031
pg_noreturn extern void BackgroundWriterMain(const void *startup_data, size_t startup_data_len);
3132
pg_noreturn extern void CheckpointerMain(const void *startup_data, size_t startup_data_len);
3233

34+
extern void ExecCheckpoint(ParseState *pstate, CheckPointStmt *stmt);
3335
extern void RequestCheckpoint(int flags);
3436
extern void CheckpointWriteDelay(int flags, double progress);
3537

src/test/regress/expected/stats.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,12 @@ DROP TABLE test_stats_temp;
926926
-- Checkpoint twice: The checkpointer reports stats after reporting completion
927927
-- of the checkpoint. But after a second checkpoint we'll see at least the
928928
-- results of the first.
929+
--
930+
-- While at it, test checkpoint options.
931+
CHECKPOINT (WRONG);
932+
ERROR: unrecognized CHECKPOINT option "wrong"
933+
LINE 1: CHECKPOINT (WRONG);
934+
^
929935
CHECKPOINT;
930936
CHECKPOINT;
931937
SELECT num_requested > :rqst_ckpts_before FROM pg_stat_checkpointer;

src/test/regress/sql/stats.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ DROP TABLE test_stats_temp;
439439
-- Checkpoint twice: The checkpointer reports stats after reporting completion
440440
-- of the checkpoint. But after a second checkpoint we'll see at least the
441441
-- results of the first.
442+
--
443+
-- While at it, test checkpoint options.
444+
CHECKPOINT (WRONG);
442445
CHECKPOINT;
443446
CHECKPOINT;
444447

0 commit comments

Comments
 (0)