@@ -106,7 +106,9 @@ static Form_pg_sequence_data read_seq_tuple(Relation rel,
106
106
static void init_params (ParseState * pstate , List * options , bool for_identity ,
107
107
bool isInit ,
108
108
Form_pg_sequence seqform ,
109
- Form_pg_sequence_data seqdataform ,
109
+ int64 * last_value ,
110
+ bool * reset_state ,
111
+ bool * is_called ,
110
112
bool * need_seq_rewrite ,
111
113
List * * owned_by );
112
114
static void do_setval (Oid relid , int64 next , bool iscalled );
@@ -121,7 +123,9 @@ ObjectAddress
121
123
DefineSequence (ParseState * pstate , CreateSeqStmt * seq )
122
124
{
123
125
FormData_pg_sequence seqform ;
124
- FormData_pg_sequence_data seqdataform ;
126
+ int64 last_value ;
127
+ bool reset_state ;
128
+ bool is_called ;
125
129
bool need_seq_rewrite ;
126
130
List * owned_by ;
127
131
CreateStmt * stmt = makeNode (CreateStmt );
@@ -164,7 +168,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
164
168
165
169
/* Check and set all option values */
166
170
init_params (pstate , seq -> options , seq -> for_identity , true,
167
- & seqform , & seqdataform ,
171
+ & seqform , & last_value , & reset_state , & is_called ,
168
172
& need_seq_rewrite , & owned_by );
169
173
170
174
/*
@@ -179,7 +183,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
179
183
{
180
184
case SEQ_COL_LASTVAL :
181
185
coldef = makeColumnDef ("last_value" , INT8OID , -1 , InvalidOid );
182
- value [i - 1 ] = Int64GetDatumFast (seqdataform . last_value );
186
+ value [i - 1 ] = Int64GetDatumFast (last_value );
183
187
break ;
184
188
case SEQ_COL_LOG :
185
189
coldef = makeColumnDef ("log_cnt" , INT8OID , -1 , InvalidOid );
@@ -448,6 +452,9 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
448
452
ObjectAddress address ;
449
453
Relation rel ;
450
454
HeapTuple seqtuple ;
455
+ bool reset_state = false;
456
+ bool is_called ;
457
+ int64 last_value ;
451
458
HeapTuple newdatatuple ;
452
459
453
460
/* Open and lock sequence, and check for ownership along the way. */
@@ -481,12 +488,14 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
481
488
/* copy the existing sequence data tuple, so it can be modified locally */
482
489
newdatatuple = heap_copytuple (& datatuple );
483
490
newdataform = (Form_pg_sequence_data ) GETSTRUCT (newdatatuple );
491
+ last_value = newdataform -> last_value ;
492
+ is_called = newdataform -> is_called ;
484
493
485
494
UnlockReleaseBuffer (buf );
486
495
487
496
/* Check and set new values */
488
497
init_params (pstate , stmt -> options , stmt -> for_identity , false,
489
- seqform , newdataform ,
498
+ seqform , & last_value , & reset_state , & is_called ,
490
499
& need_seq_rewrite , & owned_by );
491
500
492
501
/* If needed, rewrite the sequence relation itself */
@@ -513,6 +522,10 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
513
522
/*
514
523
* Insert the modified tuple into the new storage file.
515
524
*/
525
+ newdataform -> last_value = last_value ;
526
+ newdataform -> is_called = is_called ;
527
+ if (reset_state )
528
+ newdataform -> log_cnt = 0 ;
516
529
fill_seq_with_data (seqrel , newdatatuple );
517
530
}
518
531
@@ -1236,17 +1249,19 @@ read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
1236
1249
/*
1237
1250
* init_params: process the options list of CREATE or ALTER SEQUENCE, and
1238
1251
* store the values into appropriate fields of seqform, for changes that go
1239
- * into the pg_sequence catalog, and fields of seqdataform for changes to the
1240
- * sequence relation itself. Set *need_seq_rewrite to true if we changed any
1241
- * parameters that require rewriting the sequence's relation (interesting for
1242
- * ALTER SEQUENCE). Also set *owned_by to any OWNED BY option, or to NIL if
1243
- * there is none.
1252
+ * into the pg_sequence catalog, and fields for changes to the sequence
1253
+ * relation itself (*is_called, *last_value and *reset_state). Set
1254
+ * *need_seq_rewrite to true if we changed any parameters that require
1255
+ * rewriting the sequence's relation (interesting for ALTER SEQUENCE). Also
1256
+ * set *owned_by to any OWNED BY option, or to NIL if there is none. Set
1257
+ * *reset_state to true if the internal state of the sequence needs to be
1258
+ * reset, affecting future nextval() calls, for example with WAL logging.
1244
1259
*
1245
1260
* If isInit is true, fill any unspecified options with default values;
1246
1261
* otherwise, do not change existing options that aren't explicitly overridden.
1247
1262
*
1248
1263
* Note: we force a sequence rewrite whenever we change parameters that affect
1249
- * generation of future sequence values, even if the seqdataform per se is not
1264
+ * generation of future sequence values, even if the metadata per se is not
1250
1265
* changed. This allows ALTER SEQUENCE to behave transactionally. Currently,
1251
1266
* the only option that doesn't cause that is OWNED BY. It's *necessary* for
1252
1267
* ALTER SEQUENCE OWNED BY to not rewrite the sequence, because that would
@@ -1257,7 +1272,9 @@ static void
1257
1272
init_params (ParseState * pstate , List * options , bool for_identity ,
1258
1273
bool isInit ,
1259
1274
Form_pg_sequence seqform ,
1260
- Form_pg_sequence_data seqdataform ,
1275
+ int64 * last_value ,
1276
+ bool * reset_state ,
1277
+ bool * is_called ,
1261
1278
bool * need_seq_rewrite ,
1262
1279
List * * owned_by )
1263
1280
{
@@ -1363,11 +1380,11 @@ init_params(ParseState *pstate, List *options, bool for_identity,
1363
1380
}
1364
1381
1365
1382
/*
1366
- * We must reset log_cnt when isInit or when changing any parameters that
1367
- * would affect future nextval allocations.
1383
+ * We must reset the state of the sequence when isInit or when changing
1384
+ * any parameters that would affect future nextval allocations.
1368
1385
*/
1369
1386
if (isInit )
1370
- seqdataform -> log_cnt = 0 ;
1387
+ * reset_state = true ;
1371
1388
1372
1389
/* AS type */
1373
1390
if (as_type != NULL )
@@ -1416,7 +1433,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
1416
1433
ereport (ERROR ,
1417
1434
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1418
1435
errmsg ("INCREMENT must not be zero" )));
1419
- seqdataform -> log_cnt = 0 ;
1436
+ * reset_state = true ;
1420
1437
}
1421
1438
else if (isInit )
1422
1439
{
@@ -1428,7 +1445,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
1428
1445
{
1429
1446
seqform -> seqcycle = boolVal (is_cycled -> arg );
1430
1447
Assert (BoolIsValid (seqform -> seqcycle ));
1431
- seqdataform -> log_cnt = 0 ;
1448
+ * reset_state = true ;
1432
1449
}
1433
1450
else if (isInit )
1434
1451
{
@@ -1439,7 +1456,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
1439
1456
if (max_value != NULL && max_value -> arg )
1440
1457
{
1441
1458
seqform -> seqmax = defGetInt64 (max_value );
1442
- seqdataform -> log_cnt = 0 ;
1459
+ * reset_state = true ;
1443
1460
}
1444
1461
else if (isInit || max_value != NULL || reset_max_value )
1445
1462
{
@@ -1455,7 +1472,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
1455
1472
}
1456
1473
else
1457
1474
seqform -> seqmax = -1 ; /* descending seq */
1458
- seqdataform -> log_cnt = 0 ;
1475
+ * reset_state = true ;
1459
1476
}
1460
1477
1461
1478
/* Validate maximum value. No need to check INT8 as seqmax is an int64 */
@@ -1471,7 +1488,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
1471
1488
if (min_value != NULL && min_value -> arg )
1472
1489
{
1473
1490
seqform -> seqmin = defGetInt64 (min_value );
1474
- seqdataform -> log_cnt = 0 ;
1491
+ * reset_state = true ;
1475
1492
}
1476
1493
else if (isInit || min_value != NULL || reset_min_value )
1477
1494
{
@@ -1487,7 +1504,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
1487
1504
}
1488
1505
else
1489
1506
seqform -> seqmin = 1 ; /* ascending seq */
1490
- seqdataform -> log_cnt = 0 ;
1507
+ * reset_state = true ;
1491
1508
}
1492
1509
1493
1510
/* Validate minimum value. No need to check INT8 as seqmin is an int64 */
@@ -1538,30 +1555,30 @@ init_params(ParseState *pstate, List *options, bool for_identity,
1538
1555
if (restart_value != NULL )
1539
1556
{
1540
1557
if (restart_value -> arg != NULL )
1541
- seqdataform -> last_value = defGetInt64 (restart_value );
1558
+ * last_value = defGetInt64 (restart_value );
1542
1559
else
1543
- seqdataform -> last_value = seqform -> seqstart ;
1544
- seqdataform -> is_called = false;
1545
- seqdataform -> log_cnt = 0 ;
1560
+ * last_value = seqform -> seqstart ;
1561
+ * is_called = false;
1562
+ * reset_state = true ;
1546
1563
}
1547
1564
else if (isInit )
1548
1565
{
1549
- seqdataform -> last_value = seqform -> seqstart ;
1550
- seqdataform -> is_called = false;
1566
+ * last_value = seqform -> seqstart ;
1567
+ * is_called = false;
1551
1568
}
1552
1569
1553
1570
/* crosscheck RESTART (or current value, if changing MIN/MAX) */
1554
- if (seqdataform -> last_value < seqform -> seqmin )
1571
+ if (* last_value < seqform -> seqmin )
1555
1572
ereport (ERROR ,
1556
1573
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1557
1574
errmsg ("RESTART value (%" PRId64 ") cannot be less than MINVALUE (%" PRId64 ")" ,
1558
- seqdataform -> last_value ,
1575
+ * last_value ,
1559
1576
seqform -> seqmin )));
1560
- if (seqdataform -> last_value > seqform -> seqmax )
1577
+ if (* last_value > seqform -> seqmax )
1561
1578
ereport (ERROR ,
1562
1579
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1563
1580
errmsg ("RESTART value (%" PRId64 ") cannot be greater than MAXVALUE (%" PRId64 ")" ,
1564
- seqdataform -> last_value ,
1581
+ * last_value ,
1565
1582
seqform -> seqmax )));
1566
1583
1567
1584
/* CACHE */
@@ -1573,7 +1590,7 @@ init_params(ParseState *pstate, List *options, bool for_identity,
1573
1590
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1574
1591
errmsg ("CACHE (%" PRId64 ") must be greater than zero" ,
1575
1592
seqform -> seqcache )));
1576
- seqdataform -> log_cnt = 0 ;
1593
+ * reset_state = true ;
1577
1594
}
1578
1595
else if (isInit )
1579
1596
{
0 commit comments