Skip to content

Commit a03209a

Browse files
committed
Global tables with local buffers
1 parent b8f2da0 commit a03209a

File tree

25 files changed

+617
-48
lines changed

25 files changed

+617
-48
lines changed

src/backend/access/gist/gistutil.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,8 @@ gistGetFakeLSN(Relation rel)
10281028
{
10291029
static XLogRecPtr counter = FirstNormalUnloggedLSN;
10301030

1031-
if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
1031+
if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP ||
1032+
rel->rd_rel->relpersistence == RELPERSISTENCE_SESSION)
10321033
{
10331034
/*
10341035
* Temporary relations are only accessible in our session, so a simple

src/backend/access/heap/heapam_handler.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ heapam_relation_copy_data(Relation rel, const RelFileNode *newrnode)
673673
* init fork of an unlogged relation.
674674
*/
675675
if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT ||
676+
rel->rd_rel->relpersistence == RELPERSISTENCE_SESSION ||
676677
(rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED &&
677678
forkNum == INIT_FORKNUM))
678679
log_smgrcreate(newrnode, forkNum);

src/backend/access/nbtree/nbtpage.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,11 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access)
763763
/* Read an existing block of the relation */
764764
buf = ReadBuffer(rel, blkno);
765765
LockBuffer(buf, access);
766-
_bt_checkpage(rel, buf);
766+
/* Session temporary relation may be not yet initialized for this backend. */
767+
if (blkno == BTREE_METAPAGE && PageIsNew(BufferGetPage(buf)) && IsSessionRelationBackendId(rel->rd_backend))
768+
_bt_initmetapage(BufferGetPage(buf), P_NONE, 0);
769+
else
770+
_bt_checkpage(rel, buf);
767771
}
768772
else
769773
{

src/backend/catalog/catalog.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence)
409409
case RELPERSISTENCE_TEMP:
410410
backend = BackendIdForTempRelations();
411411
break;
412+
case RELPERSISTENCE_SESSION:
413+
backend = BackendIdForSessionRelations();
414+
break;
412415
case RELPERSISTENCE_UNLOGGED:
413416
case RELPERSISTENCE_PERMANENT:
414417
backend = InvalidBackendId;

src/backend/catalog/index.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3590,7 +3590,7 @@ reindex_relation(Oid relid, int flags, int options)
35903590
if (flags & REINDEX_REL_FORCE_INDEXES_UNLOGGED)
35913591
persistence = RELPERSISTENCE_UNLOGGED;
35923592
else if (flags & REINDEX_REL_FORCE_INDEXES_PERMANENT)
3593-
persistence = RELPERSISTENCE_PERMANENT;
3593+
persistence = rel->rd_rel->relpersistence == RELPERSISTENCE_SESSION ? RELPERSISTENCE_SESSION : RELPERSISTENCE_PERMANENT;
35943594
else
35953595
persistence = rel->rd_rel->relpersistence;
35963596

src/backend/catalog/storage.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ RelationCreateStorage(RelFileNode rnode, char relpersistence)
9393
backend = InvalidBackendId;
9494
needs_wal = false;
9595
break;
96+
case RELPERSISTENCE_SESSION:
97+
backend = BackendIdForSessionRelations();
98+
needs_wal = false;
99+
break;
96100
case RELPERSISTENCE_PERMANENT:
97101
backend = InvalidBackendId;
98102
needs_wal = true;

src/backend/commands/cluster.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1400,7 +1400,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
14001400
*/
14011401
if (newrelpersistence == RELPERSISTENCE_UNLOGGED)
14021402
reindex_flags |= REINDEX_REL_FORCE_INDEXES_UNLOGGED;
1403-
else if (newrelpersistence == RELPERSISTENCE_PERMANENT)
1403+
else if (newrelpersistence != RELPERSISTENCE_TEMP)
14041404
reindex_flags |= REINDEX_REL_FORCE_INDEXES_PERMANENT;
14051405

14061406
/* Report that we are now reindexing relations */

src/backend/commands/sequence.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static HTAB *seqhashtab = NULL; /* hash table for SeqTable items */
9494
*/
9595
static SeqTableData *last_used_seq = NULL;
9696

97-
static void fill_seq_with_data(Relation rel, HeapTuple tuple);
97+
static void fill_seq_with_data(Relation rel, HeapTuple tuple, Buffer buf);
9898
static Relation lock_and_open_sequence(SeqTable seq);
9999
static void create_seq_hashtable(void);
100100
static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel);
@@ -222,7 +222,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
222222

223223
/* now initialize the sequence's data */
224224
tuple = heap_form_tuple(tupDesc, value, null);
225-
fill_seq_with_data(rel, tuple);
225+
fill_seq_with_data(rel, tuple, InvalidBuffer);
226226

227227
/* process OWNED BY if given */
228228
if (owned_by)
@@ -327,7 +327,7 @@ ResetSequence(Oid seq_relid)
327327
/*
328328
* Insert the modified tuple into the new storage file.
329329
*/
330-
fill_seq_with_data(seq_rel, tuple);
330+
fill_seq_with_data(seq_rel, tuple, InvalidBuffer);
331331

332332
/* Clear local cache so that we don't think we have cached numbers */
333333
/* Note that we do not change the currval() state */
@@ -340,18 +340,21 @@ ResetSequence(Oid seq_relid)
340340
* Initialize a sequence's relation with the specified tuple as content
341341
*/
342342
static void
343-
fill_seq_with_data(Relation rel, HeapTuple tuple)
343+
fill_seq_with_data(Relation rel, HeapTuple tuple, Buffer buf)
344344
{
345-
Buffer buf;
346345
Page page;
347346
sequence_magic *sm;
348347
OffsetNumber offnum;
348+
bool lockBuffer = false;
349349

350350
/* Initialize first page of relation with special magic number */
351351

352-
buf = ReadBuffer(rel, P_NEW);
353-
Assert(BufferGetBlockNumber(buf) == 0);
354-
352+
if (buf == InvalidBuffer)
353+
{
354+
buf = ReadBuffer(rel, P_NEW);
355+
Assert(BufferGetBlockNumber(buf) == 0);
356+
lockBuffer = true;
357+
}
355358
page = BufferGetPage(buf);
356359

357360
PageInit(page, BufferGetPageSize(buf), sizeof(sequence_magic));
@@ -360,7 +363,8 @@ fill_seq_with_data(Relation rel, HeapTuple tuple)
360363

361364
/* Now insert sequence tuple */
362365

363-
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
366+
if (lockBuffer)
367+
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
364368

365369
/*
366370
* Since VACUUM does not process sequences, we have to force the tuple to
@@ -410,7 +414,8 @@ fill_seq_with_data(Relation rel, HeapTuple tuple)
410414

411415
END_CRIT_SECTION();
412416

413-
UnlockReleaseBuffer(buf);
417+
if (lockBuffer)
418+
UnlockReleaseBuffer(buf);
414419
}
415420

416421
/*
@@ -502,7 +507,7 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
502507
/*
503508
* Insert the modified tuple into the new storage file.
504509
*/
505-
fill_seq_with_data(seqrel, newdatatuple);
510+
fill_seq_with_data(seqrel, newdatatuple, InvalidBuffer);
506511
}
507512

508513
/* process OWNED BY if given */
@@ -1178,6 +1183,16 @@ read_seq_tuple(Relation rel, Buffer *buf, HeapTuple seqdatatuple)
11781183
LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
11791184

11801185
page = BufferGetPage(*buf);
1186+
if (rel->rd_rel->relpersistence == RELPERSISTENCE_SESSION && PageIsNew(page))
1187+
{
1188+
/* Initialize sequence for global temporary tables */
1189+
Datum value[SEQ_COL_LASTCOL] = {0};
1190+
bool null[SEQ_COL_LASTCOL] = {false};
1191+
value[SEQ_COL_LASTVAL-1] = Int64GetDatumFast(1); /* start sequence with 1 */
1192+
HeapTuple tuple = heap_form_tuple(RelationGetDescr(rel), value, null);
1193+
fill_seq_with_data(rel, tuple, *buf);
1194+
}
1195+
11811196
sm = (sequence_magic *) PageGetSpecialPointer(page);
11821197

11831198
if (sm->magic != SEQ_MAGIC)

src/backend/commands/tablecmds.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
586586
* Check consistency of arguments
587587
*/
588588
if (stmt->oncommit != ONCOMMIT_NOOP
589-
&& stmt->relation->relpersistence != RELPERSISTENCE_TEMP)
589+
&& stmt->relation->relpersistence != RELPERSISTENCE_TEMP
590+
&& stmt->relation->relpersistence != RELPERSISTENCE_SESSION)
590591
ereport(ERROR,
591592
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
592593
errmsg("ON COMMIT can only be used on temporary tables")));
@@ -7678,6 +7679,12 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
76787679
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
76797680
errmsg("constraints on unlogged tables may reference only permanent or unlogged tables")));
76807681
break;
7682+
case RELPERSISTENCE_SESSION:
7683+
if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_SESSION)
7684+
ereport(ERROR,
7685+
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
7686+
errmsg("constraints on session tables may reference only session tables")));
7687+
break;
76817688
case RELPERSISTENCE_TEMP:
76827689
if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_TEMP)
76837690
ereport(ERROR,
@@ -14082,6 +14089,13 @@ ATPrepChangePersistence(Relation rel, bool toLogged)
1408214089
RelationGetRelationName(rel)),
1408314090
errtable(rel)));
1408414091
break;
14092+
case RELPERSISTENCE_SESSION:
14093+
ereport(ERROR,
14094+
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
14095+
errmsg("cannot change logged status of session table \"%s\"",
14096+
RelationGetRelationName(rel)),
14097+
errtable(rel)));
14098+
break;
1408514099
case RELPERSISTENCE_PERMANENT:
1408614100
if (toLogged)
1408714101
/* nothing to do */
@@ -14569,14 +14583,7 @@ PreCommit_on_commit_actions(void)
1456914583
/* Do nothing (there shouldn't be such entries, actually) */
1457014584
break;
1457114585
case ONCOMMIT_DELETE_ROWS:
14572-
14573-
/*
14574-
* If this transaction hasn't accessed any temporary
14575-
* relations, we can skip truncating ON COMMIT DELETE ROWS
14576-
* tables, as they must still be empty.
14577-
*/
14578-
if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE))
14579-
oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid);
14586+
oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid);
1458014587
break;
1458114588
case ONCOMMIT_DROP:
1458214589
oids_to_drop = lappend_oid(oids_to_drop, oc->relid);

src/backend/parser/gram.y

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3265,20 +3265,11 @@ OptTemp: TEMPORARY { $$ = RELPERSISTENCE_TEMP; }
32653265
| TEMP { $$ = RELPERSISTENCE_TEMP; }
32663266
| LOCAL TEMPORARY { $$ = RELPERSISTENCE_TEMP; }
32673267
| LOCAL TEMP { $$ = RELPERSISTENCE_TEMP; }
3268-
| GLOBAL TEMPORARY
3269-
{
3270-
ereport(WARNING,
3271-
(errmsg("GLOBAL is deprecated in temporary table creation"),
3272-
parser_errposition(@1)));
3273-
$$ = RELPERSISTENCE_TEMP;
3274-
}
3275-
| GLOBAL TEMP
3276-
{
3277-
ereport(WARNING,
3278-
(errmsg("GLOBAL is deprecated in temporary table creation"),
3279-
parser_errposition(@1)));
3280-
$$ = RELPERSISTENCE_TEMP;
3281-
}
3268+
| GLOBAL TEMPORARY { $$ = RELPERSISTENCE_SESSION; }
3269+
| GLOBAL TEMP { $$ = RELPERSISTENCE_SESSION; }
3270+
| SESSION { $$ = RELPERSISTENCE_SESSION; }
3271+
| SESSION TEMPORARY { $$ = RELPERSISTENCE_SESSION; }
3272+
| SESSION TEMP { $$ = RELPERSISTENCE_SESSION; }
32823273
| UNLOGGED { $$ = RELPERSISTENCE_UNLOGGED; }
32833274
| /*EMPTY*/ { $$ = RELPERSISTENCE_PERMANENT; }
32843275
;

src/backend/parser/parse_utilcmd.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,14 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column,
436436
seqstmt->sequence = makeRangeVar(snamespace, sname, -1);
437437
seqstmt->options = seqoptions;
438438

439+
/*
440+
* Why we should not always use persistence of parent table?
441+
* Although it is prohibited to have unlogged sequences,
442+
* unlogged tables with SERIAL fields are accepted!
443+
*/
444+
if (cxt->relation->relpersistence != RELPERSISTENCE_UNLOGGED)
445+
seqstmt->sequence->relpersistence = cxt->relation->relpersistence;
446+
439447
/*
440448
* If a sequence data type was specified, add it to the options. Prepend
441449
* to the list rather than append; in case a user supplied their own AS

src/backend/postmaster/autovacuum.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,7 +2069,8 @@ do_autovacuum(void)
20692069
* Check if it is a temp table (presumably, of some other backend's).
20702070
* We cannot safely process other backends' temp tables.
20712071
*/
2072-
if (classForm->relpersistence == RELPERSISTENCE_TEMP)
2072+
if (classForm->relpersistence == RELPERSISTENCE_TEMP ||
2073+
classForm->relpersistence == RELPERSISTENCE_SESSION)
20732074
{
20742075
/*
20752076
* We just ignore it if the owning backend is still active and
@@ -2154,7 +2155,8 @@ do_autovacuum(void)
21542155
/*
21552156
* We cannot safely process other backends' temp tables, so skip 'em.
21562157
*/
2157-
if (classForm->relpersistence == RELPERSISTENCE_TEMP)
2158+
if (classForm->relpersistence == RELPERSISTENCE_TEMP ||
2159+
classForm->relpersistence == RELPERSISTENCE_SESSION)
21582160
continue;
21592161

21602162
relid = classForm->oid;

0 commit comments

Comments
 (0)