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

Commit1c4c0fc

Browse files
committed
transfer_tables.patch
1 parentf7389cd commit1c4c0fc

File tree

31 files changed

+1358
-61
lines changed

31 files changed

+1358
-61
lines changed

‎contrib/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ SUBDIRS = \
3535
pg_query_state\
3636
pg_standby\
3737
pg_stat_statements\
38+
pg_transfer\
3839
pg_trgm\
3940
pgcrypto\
4041
pgrowlocks\

‎src/backend/catalog/catalog.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence)
393393
backend=BackendIdForTempRelations();
394394
break;
395395
caseRELPERSISTENCE_UNLOGGED:
396+
caseRELPERSISTENCE_CONSTANT:
396397
caseRELPERSISTENCE_PERMANENT:
397398
backend=InvalidBackendId;
398399
break;

‎src/backend/catalog/index.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3509,6 +3509,9 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
35093509
* REINDEX_REL_FORCE_INDEXES_PERMANENT: if true, set the persistence of the
35103510
* rebuilt indexes to permanent.
35113511
*
3512+
* REINDEX_REL_FORCE_INDEXES_CONSTANT: if true, set the persistence of the
3513+
* rebuilt indexes to constant.
3514+
*
35123515
* Returns true if any indexes were rebuilt (including toast table's index
35133516
* when relevant). Note that a CommandCounterIncrement will occur after each
35143517
* index rebuild.
@@ -3592,6 +3595,8 @@ reindex_relation(Oid relid, int flags, int options)
35923595
persistence=RELPERSISTENCE_UNLOGGED;
35933596
elseif (flags&REINDEX_REL_FORCE_INDEXES_PERMANENT)
35943597
persistence=RELPERSISTENCE_PERMANENT;
3598+
elseif (flags&REINDEX_REL_FORCE_INDEXES_CONSTANT)
3599+
persistence=RELPERSISTENCE_CONSTANT;
35953600
else
35963601
persistence=rel->rd_rel->relpersistence;
35973602

‎src/backend/catalog/storage.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ RelationCreateStorage(RelFileNode rnode, char relpersistence)
9393
needs_wal= false;
9494
break;
9595
caseRELPERSISTENCE_PERMANENT:
96+
caseRELPERSISTENCE_CONSTANT:
9697
backend=InvalidBackendId;
9798
needs_wal= true;
9899
break;

‎src/backend/commands/cluster.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,6 +1543,15 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
15431543
reindex_flags |=REINDEX_REL_FORCE_INDEXES_UNLOGGED;
15441544
elseif (newrelpersistence==RELPERSISTENCE_PERMANENT)
15451545
reindex_flags |=REINDEX_REL_FORCE_INDEXES_PERMANENT;
1546+
elseif (newrelpersistence==RELPERSISTENCE_CONSTANT)
1547+
{
1548+
/*
1549+
* Actually, there is no need in rebuilding CONSTANT indexes,
1550+
* but if someone forced CLUSTER or VACUUM FULL on CONSTANT
1551+
* relation, we must do it.
1552+
*/
1553+
reindex_flags |=REINDEX_REL_FORCE_INDEXES_CONSTANT;
1554+
}
15461555

15471556
reindex_relation(OIDOldHeap,reindex_flags,0);
15481557

‎src/backend/commands/sequence.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
125125
ereport(ERROR,
126126
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
127127
errmsg("unlogged sequences are not supported")));
128+
/* CONSTANT sequences are not implemented -- not clear if useful. */
129+
if (seq->sequence->relpersistence==RELPERSISTENCE_CONSTANT)
130+
ereport(ERROR,
131+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
132+
errmsg("CONSTANT sequences are not supported")));
128133

129134
/*
130135
* If if_not_exists was given and a relation with the same name already

‎src/backend/commands/tablecmds.c

Lines changed: 126 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ typedef struct AlteredTableInfo
160160
boolnew_notnull;/* T if we added new NOT NULL constraints */
161161
intrewrite;/* Reason for forced rewrite, if any */
162162
OidnewTableSpace;/* new tablespace; 0 means no change */
163-
boolchgPersistence;/* T if SET LOGGED/UNLOGGED is used */
163+
boolchgPersistence;/* T if SET LOGGED/UNLOGGED/CONSTANT is used */
164164
charnewrelpersistence;/* if above is true */
165165
/* Objects to rebuild after completing ALTER TYPE operations */
166166
List*changedConstraintOids;/* OIDs of constraints to rebuild */
@@ -402,7 +402,8 @@ static void change_owner_recurse_to_sequences(Oid relationOid,
402402
staticObjectAddressATExecClusterOn(Relationrel,constchar*indexName,
403403
LOCKMODElockmode);
404404
staticvoidATExecDropCluster(Relationrel,LOCKMODElockmode);
405-
staticboolATPrepChangePersistence(Relationrel,booltoLogged);
405+
staticvoidATExecSetConstant(Relationrel,LOCKMODElockmode);
406+
staticboolATPrepChangePersistence(Relationrel,charnewrelpersistence);
406407
staticvoidATPrepSetTableSpace(AlteredTableInfo*tab,Relationrel,
407408
char*tablespacename,LOCKMODElockmode);
408409
staticvoidATExecSetTableSpace(OidtableOid,OidnewTableSpace,LOCKMODElockmode);
@@ -3036,6 +3037,7 @@ AlterTableGetLockLevel(List *cmds)
30363037

30373038
caseAT_SetLogged:
30383039
caseAT_SetUnLogged:
3040+
caseAT_SetConstant:
30393041
cmd_lockmode=AccessExclusiveLock;
30403042
break;
30413043

@@ -3258,7 +3260,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
32583260
break;
32593261
caseAT_SetLogged:/* SET LOGGED */
32603262
ATSimplePermissions(rel,ATT_TABLE);
3261-
tab->chgPersistence=ATPrepChangePersistence(rel,true);
3263+
tab->chgPersistence=ATPrepChangePersistence(rel,RELPERSISTENCE_PERMANENT);
32623264
/* force rewrite if necessary; see comment in ATRewriteTables */
32633265
if (tab->chgPersistence)
32643266
{
@@ -3269,7 +3271,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
32693271
break;
32703272
caseAT_SetUnLogged:/* SET UNLOGGED */
32713273
ATSimplePermissions(rel,ATT_TABLE);
3272-
tab->chgPersistence=ATPrepChangePersistence(rel,false);
3274+
tab->chgPersistence=ATPrepChangePersistence(rel,RELPERSISTENCE_UNLOGGED);
32733275
/* force rewrite if necessary; see comment in ATRewriteTables */
32743276
if (tab->chgPersistence)
32753277
{
@@ -3278,6 +3280,14 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
32783280
}
32793281
pass=AT_PASS_MISC;
32803282
break;
3283+
caseAT_SetConstant:/* SET CONSTANT */
3284+
ATSimplePermissions(rel,ATT_TABLE);
3285+
tab->chgPersistence=ATPrepChangePersistence(rel,RELPERSISTENCE_CONSTANT);
3286+
/* We do not rewrite relation, just freeze it in ATExecSetConstant. */
3287+
if (tab->chgPersistence)
3288+
tab->newrelpersistence=RELPERSISTENCE_CONSTANT;
3289+
pass=AT_PASS_MISC;
3290+
break;
32813291
caseAT_AddOids:/* SET WITH OIDS */
32823292
ATSimplePermissions(rel,ATT_TABLE |ATT_FOREIGN_TABLE);
32833293
if (!rel->rd_rel->relhasoids||recursing)
@@ -3579,6 +3589,9 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
35793589
caseAT_SetLogged:/* SET LOGGED */
35803590
caseAT_SetUnLogged:/* SET UNLOGGED */
35813591
break;
3592+
caseAT_SetConstant:/* SET CONSTANT */
3593+
ATExecSetConstant(rel,lockmode);
3594+
break;
35823595
caseAT_AddOids:/* SET WITH OIDS */
35833596
/* Use the ADD COLUMN code, unless prep decided to do nothing */
35843597
if (cmd->def!=NULL)
@@ -6312,6 +6325,12 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
63126325
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
63136326
errmsg("constraints on temporary tables must involve temporary tables of this session")));
63146327
break;
6328+
caseRELPERSISTENCE_CONSTANT:
6329+
ereport(ERROR,
6330+
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
6331+
errmsg("constraints on CONSTANT tables are not supported")));
6332+
break;
6333+
63156334
}
63166335

63176336
/*
@@ -9350,6 +9369,74 @@ ATExecDropCluster(Relation rel, LOCKMODE lockmode)
93509369
mark_index_clustered(rel,InvalidOid, false);
93519370
}
93529371

9372+
9373+
staticvoid
9374+
setRelpersistenceConstant(Relationrel)
9375+
{
9376+
Relationpg_class;
9377+
Oidrelid;
9378+
HeapTupletuple;
9379+
9380+
relid=RelationGetRelid(rel);
9381+
9382+
pg_class=heap_open(RelationRelationId,RowExclusiveLock);
9383+
9384+
tuple=SearchSysCacheCopy1(RELOID,ObjectIdGetDatum(relid));
9385+
9386+
if (!HeapTupleIsValid(tuple))
9387+
elog(ERROR,"cache lookup failed for relation %u",relid);
9388+
9389+
((Form_pg_class)GETSTRUCT(tuple))->relpersistence=RELPERSISTENCE_CONSTANT;
9390+
simple_heap_update(pg_class,&tuple->t_self,tuple);
9391+
9392+
/* keep catalog indexes current */
9393+
CatalogUpdateIndexes(pg_class,tuple);
9394+
/* Invalidate cached info about relation. */
9395+
CacheInvalidateRelcache(rel);
9396+
9397+
heap_close(pg_class,RowExclusiveLock);
9398+
heap_freetuple(tuple);
9399+
}
9400+
9401+
/*
9402+
* Change relation relpersistence to RELPERSISTENCE_CONSTANT.
9403+
*/
9404+
staticvoid
9405+
ATExecSetConstant(Relationrel,LOCKMODElockmode)
9406+
{
9407+
List*index_oid_list;
9408+
ListCell*i;
9409+
9410+
if (rel->rd_rel->relkind!=RELKIND_RELATION
9411+
&&rel->rd_rel->relkind!=RELKIND_TOASTVALUE)
9412+
elog(ERROR,"cannot apply SET CONSTANT to relation %s, because it's not a table.",
9413+
NameStr(rel->rd_rel->relname));
9414+
setRelpersistenceConstant(rel);
9415+
9416+
/* Find all the indexes belonging to this relation */
9417+
index_oid_list=RelationGetIndexList(rel);
9418+
9419+
/* For each index, change its relpersistence */
9420+
foreach(i,index_oid_list)
9421+
{
9422+
RelationindexRelation=index_open(lfirst_oid(i),lockmode);
9423+
setRelpersistenceConstant(indexRelation);
9424+
index_close(indexRelation,NoLock);
9425+
}
9426+
9427+
list_free(index_oid_list);
9428+
9429+
/* If it has a toast table, change its relpersistence.
9430+
* And also recursevily for toast_index
9431+
*/
9432+
if (rel->rd_rel->reltoastrelid!=InvalidOid)
9433+
{
9434+
RelationtoastRelation=heap_open(rel->rd_rel->reltoastrelid,lockmode);
9435+
ATExecSetConstant(toastRelation,lockmode);
9436+
heap_close(toastRelation,NoLock);
9437+
}
9438+
}
9439+
93539440
/*
93549441
* ALTER TABLE SET TABLESPACE
93559442
*/
@@ -11290,46 +11377,55 @@ ATExecGenericOptions(Relation rel, List *options)
1129011377
}
1129111378

1129211379
/*
11293-
* Preparation phase for SET LOGGED/UNLOGGED
11380+
* Preparation phase for SET LOGGED/UNLOGGED/CONSTANT
1129411381
*
1129511382
* This verifies that we're not trying to change a temp table. Also,
1129611383
* existing foreign key constraints are checked to avoid ending up with
1129711384
* permanent tables referencing unlogged tables.
11385+
* Foreign key constraints on CONSTANT tables are not allowed.
1129811386
*
1129911387
* Return value is false if the operation is a no-op (in which case the
1130011388
* checks are skipped), otherwise true.
1130111389
*/
1130211390
staticbool
11303-
ATPrepChangePersistence(Relationrel,booltoLogged)
11391+
ATPrepChangePersistence(Relationrel,charnewrelpersistence)
1130411392
{
1130511393
Relationpg_constraint;
1130611394
HeapTupletuple;
1130711395
SysScanDescscan;
1130811396
ScanKeyDataskey[1];
11397+
booltoLogged= false;
11398+
11399+
/*
11400+
* When we track constraints, constant tables behaves just like
11401+
* permanent ones.
11402+
*/
11403+
if (newrelpersistence==RELPERSISTENCE_PERMANENT
11404+
||newrelpersistence==RELPERSISTENCE_CONSTANT)
11405+
toLogged= true;
11406+
11407+
/* Nothing to do */
11408+
if (rel->rd_rel->relpersistence==newrelpersistence)
11409+
return false;
1130911410

1131011411
/*
11311-
* Disallow changing status for a temp table. Also verify whether we can
11312-
* get away with doing nothing; in such cases we don't need to run the
11313-
* checks below, either.
11412+
* Disallow changing status for a temp and constant tables.
1131411413
*/
1131511414
switch (rel->rd_rel->relpersistence)
1131611415
{
1131711416
caseRELPERSISTENCE_TEMP:
1131811417
ereport(ERROR,
1131911418
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
11320-
errmsg("cannot changelogged status of table \"%s\" because it is temporary",
11419+
errmsg("cannot changepersistence of table \"%s\" because it is temporary",
1132111420
RelationGetRelationName(rel)),
1132211421
errtable(rel)));
1132311422
break;
11324-
caseRELPERSISTENCE_PERMANENT:
11325-
if (toLogged)
11326-
/* nothing to do */
11327-
return false;
11328-
break;
11329-
caseRELPERSISTENCE_UNLOGGED:
11330-
if (!toLogged)
11331-
/* nothing to do */
11332-
return false;
11423+
caseRELPERSISTENCE_CONSTANT:
11424+
ereport(ERROR,
11425+
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
11426+
errmsg("cannot change persistence of table \"%s\" because it is constant",
11427+
RelationGetRelationName(rel)),
11428+
errtable(rel)));
1133311429
break;
1133411430
}
1133511431

@@ -11363,15 +11459,23 @@ ATPrepChangePersistence(Relation rel, bool toLogged)
1136311459
Relationforeignrel;
1136411460

1136511461
/* the opposite end of what we used as scankey */
11366-
foreignrelid=toLogged?con->confrelid :con->conrelid;
11462+
foreignrelid=toLogged?con->confrelid :con->conrelid;
1136711463

1136811464
/* ignore if self-referencing */
1136911465
if (RelationGetRelid(rel)==foreignrelid)
1137011466
continue;
1137111467

1137211468
foreignrel=relation_open(foreignrelid,AccessShareLock);
1137311469

11374-
if (toLogged)
11470+
if (newrelpersistence==RELPERSISTENCE_CONSTANT)
11471+
ereport(ERROR,
11472+
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
11473+
errmsg("could not change table \"%s\" to constant because it references table \"%s\"",
11474+
RelationGetRelationName(rel),
11475+
RelationGetRelationName(foreignrel)),
11476+
errtableconstraint(rel,NameStr(con->conname))));
11477+
11478+
if (newrelpersistence==RELPERSISTENCE_PERMANENT)
1137511479
{
1137611480
if (foreignrel->rd_rel->relpersistence!=RELPERSISTENCE_PERMANENT)
1137711481
ereport(ERROR,
@@ -11381,7 +11485,7 @@ ATPrepChangePersistence(Relation rel, bool toLogged)
1138111485
RelationGetRelationName(foreignrel)),
1138211486
errtableconstraint(rel,NameStr(con->conname))));
1138311487
}
11384-
else
11488+
if (newrelpersistence==RELPERSISTENCE_UNLOGGED)
1138511489
{
1138611490
if (foreignrel->rd_rel->relpersistence==RELPERSISTENCE_PERMANENT)
1138711491
ereport(ERROR,

‎src/backend/commands/view.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,11 @@ DefineView(ViewStmt *stmt, const char *queryString)
505505
ereport(ERROR,
506506
(errcode(ERRCODE_SYNTAX_ERROR),
507507
errmsg("views cannot be unlogged because they do not have storage")));
508+
/* CONSTANT views are not sensible. */
509+
if (stmt->view->relpersistence==RELPERSISTENCE_CONSTANT)
510+
ereport(ERROR,
511+
(errcode(ERRCODE_SYNTAX_ERROR),
512+
errmsg("views cannot be CONSTANT because they do not have storage")));
508513

509514
/*
510515
* If the user didn't explicitly ask for a temporary view, check whether

‎src/backend/optimizer/util/pathnode.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2977,6 +2977,16 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel,
29772977
Assert(returningLists==NIL||
29782978
list_length(resultRelations)==list_length(returningLists));
29792979

2980+
foreach(lc,resultRelations)
2981+
{
2982+
Indexrti=lfirst_int(lc);
2983+
RangeTblEntry*rte=planner_rt_fetch(rti,root);
2984+
2985+
/* RELPERSISTENCE_CONSTANT */
2986+
if (rte->relpersistence=='c')
2987+
elog(ERROR,"This operation is not allowed on CONSTANT relations");
2988+
}
2989+
29802990
pathnode->path.pathtype=T_ModifyTable;
29812991
pathnode->path.parent=rel;
29822992
/* pathtarget is not interesting, just make it minimally valid */

‎src/backend/optimizer/util/plancat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
107107
relation=heap_open(relationObjectId,NoLock);
108108

109109
/* Temporary and unlogged relations are inaccessible during recovery. */
110-
if (!RelationNeedsWAL(relation)&&RecoveryInProgress())
110+
if (!RelationNeedsWAL(relation)&&RecoveryInProgress())
111111
ereport(ERROR,
112112
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
113113
errmsg("cannot access temporary or unlogged relations during recovery")));

‎src/backend/parser/analyze.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2470,7 +2470,11 @@ transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
24702470
ereport(ERROR,
24712471
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
24722472
errmsg("materialized views cannot be UNLOGGED")));
2473-
2473+
/* Constant materialized views are not implemented. */
2474+
if (stmt->into->rel->relpersistence==RELPERSISTENCE_CONSTANT)
2475+
ereport(ERROR,
2476+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2477+
errmsg("materialized views cannot be CONSTANT")));
24742478
/*
24752479
* At runtime, we'll need a copy of the parsed-but-not-rewritten Query
24762480
* for purposes of creating the view's ON SELECT rule. We stash that

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp