diff --git a/doc/src/sgml/ref/discard.sgml b/doc/src/sgml/ref/discard.sgml
index 65ebbae1385..762f8657116 100644
--- a/doc/src/sgml/ref/discard.sgml
+++ b/doc/src/sgml/ref/discard.sgml
@@ -21,7 +21,7 @@ PostgreSQL documentation
-DISCARD { ALL | PLANS | TEMPORARY | TEMP }
+DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP }
@@ -66,6 +66,15 @@ DISCARD { ALL | PLANS | TEMPORARY | TEMP }
+
+ SEQUENCES
+
+
+ Discards all cached sequence values.
+
+
+
+
ALL
@@ -83,6 +92,7 @@ UNLISTEN *;
SELECT pg_advisory_unlock_all();
DISCARD PLANS;
DISCARD TEMP;
+DISCARD SEQUENCES;
diff --git a/src/backend/commands/discard.c b/src/backend/commands/discard.c
index 76f3ab672ad..9010368f577 100644
--- a/src/backend/commands/discard.c
+++ b/src/backend/commands/discard.c
@@ -18,13 +18,14 @@
#include "commands/async.h"
#include "commands/discard.h"
#include "commands/prepare.h"
+#include "commands/sequence.h"
#include "utils/guc.h"
#include "utils/portal.h"
static void DiscardAll(bool isTopLevel);
/*
- * DISCARD { ALL | TEMP | PLANS }
+ * DISCARD { ALL | SEQUENCES | TEMP | PLANS }
*/
void
DiscardCommand(DiscardStmt *stmt, bool isTopLevel)
@@ -39,6 +40,10 @@ DiscardCommand(DiscardStmt *stmt, bool isTopLevel)
ResetPlanCache();
break;
+ case DISCARD_SEQUENCES:
+ ResetSequenceCaches();
+ break;
+
case DISCARD_TEMP:
ResetTempTableNamespace();
break;
@@ -69,4 +74,5 @@ DiscardAll(bool isTopLevel)
LockReleaseAll(USER_LOCKMETHOD, true);
ResetPlanCache();
ResetTempTableNamespace();
+ ResetSequenceCaches();
}
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index ddfaf3bd293..3ec6b7654aa 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -1602,3 +1602,19 @@ seq_redo(XLogRecPtr lsn, XLogRecord *record)
pfree(localpage);
}
+
+/*
+ * Flush cached sequence information.
+ */
+void
+ResetSequenceCaches(void)
+{
+ SeqTableData *next;
+
+ while (seqtab != NULL)
+ {
+ next = seqtab->next;
+ free(seqtab);
+ seqtab = seqtab->next;
+ }
+}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index a9812af7cfc..0efe1705e24 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -1674,7 +1674,7 @@ CheckPointStmt:
/*****************************************************************************
*
- * DISCARD { ALL | TEMP | PLANS }
+ * DISCARD { ALL | TEMP | PLANS | SEQUENCES }
*
*****************************************************************************/
@@ -1703,6 +1703,13 @@ DiscardStmt:
n->target = DISCARD_PLANS;
$$ = (Node *) n;
}
+ | DISCARD SEQUENCES
+ {
+ DiscardStmt *n = makeNode(DiscardStmt);
+ n->target = DISCARD_SEQUENCES;
+ $$ = (Node *) n;
+ }
+
;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index b1023c4e882..fffaa35d344 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -2190,6 +2190,9 @@ CreateCommandTag(Node *parsetree)
case DISCARD_TEMP:
tag = "DISCARD TEMP";
break;
+ case DISCARD_SEQUENCES:
+ tag = "DISCARD SEQUENCES";
+ break;
default:
tag = "???";
}
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index b3de387b941..255061c1c41 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -2378,7 +2378,7 @@ psql_completion(char *text, int start, int end)
else if (pg_strcasecmp(prev_wd, "DISCARD") == 0)
{
static const char *const list_DISCARD[] =
- {"ALL", "PLANS", "TEMP", NULL};
+ {"ALL", "PLANS", "SEQUENCES", "TEMP", NULL};
COMPLETE_WITH_LIST(list_DISCARD);
}
diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h
index 6bd4892cfc1..ffafe6c52f4 100644
--- a/src/include/commands/sequence.h
+++ b/src/include/commands/sequence.h
@@ -74,6 +74,7 @@ extern Datum pg_sequence_parameters(PG_FUNCTION_ARGS);
extern Oid DefineSequence(CreateSeqStmt *stmt);
extern Oid AlterSequence(AlterSeqStmt *stmt);
extern void ResetSequence(Oid seq_relid);
+extern void ResetSequenceCaches(void);
extern void seq_redo(XLogRecPtr lsn, XLogRecord *rptr);
extern void seq_desc(StringInfo buf, uint8 xl_info, char *rec);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 51fef68ca3c..e5235cbf40f 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2543,6 +2543,7 @@ typedef enum DiscardMode
{
DISCARD_ALL,
DISCARD_PLANS,
+ DISCARD_SEQUENCES,
DISCARD_TEMP
} DiscardMode;
diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out
index 87feb08b14a..37e9a8cfa1a 100644
--- a/src/test/regress/expected/sequence.out
+++ b/src/test/regress/expected/sequence.out
@@ -163,6 +163,9 @@ SELECT nextval('sequence_test'::text);
99
(1 row)
+DISCARD SEQUENCES;
+SELECT currval('sequence_test'::regclass);
+ERROR: currval of sequence "sequence_test" is not yet defined in this session
DROP SEQUENCE sequence_test;
-- renaming sequences
CREATE SEQUENCE foo_seq;
diff --git a/src/test/regress/sql/sequence.sql b/src/test/regress/sql/sequence.sql
index a32e0494a02..31cbc926c02 100644
--- a/src/test/regress/sql/sequence.sql
+++ b/src/test/regress/sql/sequence.sql
@@ -72,6 +72,8 @@ SELECT setval('sequence_test'::regclass, 32);
SELECT nextval('sequence_test'::text);
SELECT setval('sequence_test'::regclass, 99, false);
SELECT nextval('sequence_test'::text);
+DISCARD SEQUENCES;
+SELECT currval('sequence_test'::regclass);
DROP SEQUENCE sequence_test;