Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
af4de814
Commit
af4de814
authored
Jul 11, 2004
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ALTER TABLE SET TABLESPACE. Gavin Sherry, some rework by Tom Lane.
parent
08d89db3
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
392 additions
and
63 deletions
+392
-63
doc/src/sgml/ref/alter_table.sgml
doc/src/sgml/ref/alter_table.sgml
+66
-34
src/backend/commands/cluster.c
src/backend/commands/cluster.c
+27
-16
src/backend/commands/tablecmds.c
src/backend/commands/tablecmds.c
+282
-6
src/backend/parser/gram.y
src/backend/parser/gram.y
+9
-1
src/include/commands/cluster.h
src/include/commands/cluster.h
+4
-3
src/include/nodes/parsenodes.h
src/include/nodes/parsenodes.h
+4
-3
No files found.
doc/src/sgml/ref/alter_table.sgml
View file @
af4de814
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.7
2 2004/06/02 21:04:40 momjian
Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.7
3 2004/07/11 23:13:51 tgl
Exp $
PostgreSQL documentation
-->
...
...
@@ -39,10 +39,11 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
ADD <replaceable class="PARAMETER">table_constraint</replaceable>
DROP CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ]
SET WITHOUT OIDS
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
CLUSTER ON <replaceable class="PARAMETER">index_name</replaceable>
SET WITHOUT CLUSTER
SET WITHOUT OIDS
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
SET TABLESPACE <replaceable class="PARAMETER">tablespace_name</replaceable>
</synopsis>
</refsynopsisdiv>
...
...
@@ -181,6 +182,29 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
</listitem>
</varlistentry>
<varlistentry>
<term><literal>CLUSTER</literal></term>
<listitem>
<para>
This form selects the default index for future
<xref linkend="SQL-CLUSTER" endterm="sql-cluster-title">
operations. It does not actually re-cluster the table.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>SET WITHOUT CLUSTER</literal></term>
<listitem>
<para>
This form removes the most recently used
<xref linkend="SQL-CLUSTER" endterm="sql-cluster-title">
index specification from the table. This affects
future cluster operations that don't specify an index.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>SET WITHOUT OIDS</literal></term>
<listitem>
...
...
@@ -211,24 +235,15 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
</varlistentry>
<varlistentry>
<term><literal>
CLUSTER
</literal></term>
<term><literal>
SET TABLESPACE
</literal></term>
<listitem>
<para>
This form selects the default index for future
<xref linkend="SQL-CLUSTER" endterm="sql-cluster-title">
operations.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>SET WITHOUT CLUSTER</literal></term>
<listitem>
<para>
This form removes the most recently used
<xref linkend="SQL-CLUSTER" endterm="sql-cluster-title">
index specification from the table. This affects
future cluster operations that don't specify an index.
This form changes the table's tablespace to the specified tablespace and
moves the data file(s) associated with the table to the new tablespace.
Indexes on the table, if any, are not moved; but they can be moved
separately with additional <literal>SET TABLESPACE</literal> commands.
See also
<xref linkend="SQL-CREATETABLESPACE" endterm="sql-createtablespace-title">.
</para>
</listitem>
</varlistentry>
...
...
@@ -293,29 +308,29 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
</varlistentry>
<varlistentry>
<term><replaceable class="PARAMETER">
type
</replaceable></term>
<term><replaceable class="PARAMETER">
new_column
</replaceable></term>
<listitem>
<para>
Data type of the new column, or new data type for an existing
column.
New name for an existing column.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="PARAMETER">new_
column
</replaceable></term>
<term><replaceable class="PARAMETER">new_
name
</replaceable></term>
<listitem>
<para>
New name for
an existing column
.
New name for
the table
.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="PARAMETER">
new_nam
e</replaceable></term>
<term><replaceable class="PARAMETER">
typ
e</replaceable></term>
<listitem>
<para>
New name for the table.
Data type of the new column, or new data type for an existing
column.
</para>
</listitem>
</varlistentry>
...
...
@@ -339,10 +354,21 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
</varlistentry>
<varlistentry>
<term><
replaceable class="PARAMETER">new_owner</replaceable
></term>
<term><
literal>CASCADE</literal
></term>
<listitem>
<para>
The user name of the new owner of the table.
Automatically drop objects that depend on the dropped column
or constraint (for example, views referencing the column).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>RESTRICT</literal></term>
<listitem>
<para>
Refuse to drop the column or constraint if there are any dependent
objects. This is the default behavior.
</para>
</listitem>
</varlistentry>
...
...
@@ -357,21 +383,19 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
</varlistentry>
<varlistentry>
<term><
literal>CASCADE</literal
></term>
<term><
replaceable class="PARAMETER">new_owner</replaceable
></term>
<listitem>
<para>
Automatically drop objects that depend on the dropped column
or constraint (for example, views referencing the column).
The user name of the new owner of the table.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><
literal>RESTRICT</literal
></term>
<term><
replaceable class="PARAMETER">tablespace_name</replaceable
></term>
<listitem>
<para>
Refuse to drop the column or constraint if there are any dependent
objects. This is the default behavior.
The tablespace name to which the table will be moved.
</para>
</listitem>
</varlistentry>
...
...
@@ -551,6 +575,14 @@ ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zip
ALTER TABLE distributors ADD PRIMARY KEY (dist_id);
</programlisting>
</para>
<para>
To move a table to a different tablespace:
<programlisting>
ALTER TABLE distributors SET TABLESPACE fasttablespace;
</programlisting>
</para>
</refsect1>
<refsect1>
...
...
src/backend/commands/cluster.c
View file @
af4de814
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.12
6 2004/06/18 06:13:22
tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.12
7 2004/07/11 23:13:53
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -485,6 +485,7 @@ static void
rebuild_relation
(
Relation
OldHeap
,
Oid
indexOid
)
{
Oid
tableOid
=
RelationGetRelid
(
OldHeap
);
Oid
tableSpace
=
OldHeap
->
rd_rel
->
reltablespace
;
Oid
OIDNewHeap
;
char
NewHeapName
[
NAMEDATALEN
];
ObjectAddress
object
;
...
...
@@ -505,7 +506,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid)
*/
snprintf
(
NewHeapName
,
sizeof
(
NewHeapName
),
"pg_temp_%u"
,
tableOid
);
OIDNewHeap
=
make_new_heap
(
tableOid
,
NewHeapName
);
OIDNewHeap
=
make_new_heap
(
tableOid
,
NewHeapName
,
tableSpace
);
/*
* We don't need CommandCounterIncrement() because make_new_heap did
...
...
@@ -520,8 +521,8 @@ rebuild_relation(Relation OldHeap, Oid indexOid)
/* To make the new heap's data visible (probably not needed?). */
CommandCounterIncrement
();
/* Swap the
relfilenod
es of the old and new heaps. */
swap_rel
filenod
es
(
tableOid
,
OIDNewHeap
);
/* Swap the
physical fil
es of the old and new heaps. */
swap_rel
ation_fil
es
(
tableOid
,
OIDNewHeap
);
CommandCounterIncrement
();
...
...
@@ -550,7 +551,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid)
* Create the new table that we will fill with correctly-ordered data.
*/
Oid
make_new_heap
(
Oid
OIDOldHeap
,
const
char
*
NewName
)
make_new_heap
(
Oid
OIDOldHeap
,
const
char
*
NewName
,
Oid
NewTableSpace
)
{
TupleDesc
OldHeapDesc
,
tupdesc
;
...
...
@@ -568,7 +569,7 @@ make_new_heap(Oid OIDOldHeap, const char *NewName)
OIDNewHeap
=
heap_create_with_catalog
(
NewName
,
RelationGetNamespace
(
OldHeap
),
OldHeap
->
rd_rel
->
reltables
pace
,
NewTableS
pace
,
tupdesc
,
OldHeap
->
rd_rel
->
relkind
,
OldHeap
->
rd_rel
->
relisshared
,
...
...
@@ -646,13 +647,16 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
}
/*
* Swap the relfilenodes for two given relations.
* Swap the physical files of two given relations.
*
* We swap the physical identity (reltablespace and relfilenode) while
* keeping the same logical identities of the two relations.
*
* Also swap any TOAST links, so that the toast data moves along with
* the main-table data.
*/
void
swap_rel
filenod
es
(
Oid
r1
,
Oid
r2
)
swap_rel
ation_fil
es
(
Oid
r1
,
Oid
r2
)
{
Relation
relRelation
,
rel
;
...
...
@@ -695,12 +699,16 @@ swap_relfilenodes(Oid r1, Oid r2)
relation_close
(
rel
,
NoLock
);
/*
* Actually swap the fi
lenode and TOAST fi
elds in the two tuples
* Actually swap the fields in the two tuples
*/
swaptemp
=
relform1
->
relfilenode
;
relform1
->
relfilenode
=
relform2
->
relfilenode
;
relform2
->
relfilenode
=
swaptemp
;
swaptemp
=
relform1
->
reltablespace
;
relform1
->
reltablespace
=
relform2
->
reltablespace
;
relform2
->
reltablespace
=
swaptemp
;
swaptemp
=
relform1
->
reltoastrelid
;
relform1
->
reltoastrelid
=
relform2
->
reltoastrelid
;
relform2
->
reltoastrelid
=
swaptemp
;
...
...
@@ -793,13 +801,16 @@ swap_relfilenodes(Oid r1, Oid r2)
/*
* Blow away the old relcache entries now. We need this kluge because
* relcache.c indexes relcache entries by rd_node as well as OID. It
* will get confused if it is asked to (re)build an entry with a new
* rd_node value when there is still another entry laying about with
* that same rd_node value. (Fortunately, since one of the entries is
* local in our transaction, it's sufficient to clear out our own
* relcache this way; the problem cannot arise for other backends when
* they see our update on the non-local relation.)
* relcache.c keeps a link to the smgr relation for the physical file,
* and that will be out of date as soon as we do CommandCounterIncrement.
* Whichever of the rels is the second to be cleared during cache
* invalidation will have a dangling reference to an already-deleted smgr
* relation. Rather than trying to avoid this by ordering operations
* just so, it's easiest to not have the relcache entries there at all.
* (Fortunately, since one of the entries is local in our transaction,
* it's sufficient to clear out our own relcache this way; the problem
* cannot arise for other backends when they see our update on the
* non-local relation.)
*/
RelationForgetRelation
(
r1
);
RelationForgetRelation
(
r2
);
...
...
src/backend/commands/tablecmds.c
View file @
af4de814
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.11
8 2004/07/01 00:50:10
tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.11
9 2004/07/11 23:13:53
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -52,6 +52,7 @@
#include "parser/parse_relation.h"
#include "parser/parse_type.h"
#include "rewrite/rewriteHandler.h"
#include "storage/smgr.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
...
...
@@ -120,6 +121,7 @@ typedef struct AlteredTableInfo
/* Information saved by Phases 1/2 for Phase 3: */
List
*
constraints
;
/* List of NewConstraint */
List
*
newvals
;
/* List of NewColumnValue */
Oid
newTableSpace
;
/* new tablespace; 0 means no change */
/* Objects to rebuild after completing ALTER TYPE operations */
List
*
changedConstraintOids
;
/* OIDs of constraints to rebuild */
List
*
changedConstraintDefs
;
/* string definitions of same */
...
...
@@ -237,6 +239,10 @@ static void ATPostAlterTypeParse(char *cmd, List **wqueue);
static
void
ATExecChangeOwner
(
Oid
relationOid
,
int32
newOwnerSysId
);
static
void
ATExecClusterOn
(
Relation
rel
,
const
char
*
indexName
);
static
void
ATExecDropCluster
(
Relation
rel
);
static
void
ATPrepSetTableSpace
(
AlteredTableInfo
*
tab
,
Relation
rel
,
char
*
tablespacename
);
static
void
ATExecSetTableSpace
(
Oid
tableOid
,
Oid
newTableSpace
);
static
void
copy_relation_data
(
Relation
rel
,
SMgrRelation
dst
);
static
int
ri_trigger_type
(
Oid
tgfoid
);
static
void
update_ri_trigger_args
(
Oid
relid
,
const
char
*
oldname
,
...
...
@@ -1946,6 +1952,11 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
}
pass
=
AT_PASS_DROP
;
break
;
case
AT_SetTableSpace
:
/* SET TABLESPACE */
/* This command never recurses */
ATPrepSetTableSpace
(
tab
,
rel
,
cmd
->
name
);
pass
=
AT_PASS_MISC
;
/* doesn't actually matter */
break
;
default:
/* oops */
elog
(
ERROR
,
"unrecognized alter table type: %d"
,
(
int
)
cmd
->
subtype
);
...
...
@@ -2097,6 +2108,11 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
* to do the real work
*/
break
;
case
AT_SetTableSpace
:
/* SET TABLESPACE */
/*
* Nothing to do here; Phase 3 does the work
*/
break
;
default:
/* oops */
elog
(
ERROR
,
"unrecognized alter table type: %d"
,
(
int
)
cmd
->
subtype
);
...
...
@@ -2132,6 +2148,7 @@ ATRewriteTables(List **wqueue)
/* Build a temporary relation and copy data */
Oid
OIDNewHeap
;
char
NewHeapName
[
NAMEDATALEN
];
Oid
NewTableSpace
;
Relation
OldHeap
;
ObjectAddress
object
;
...
...
@@ -2157,6 +2174,15 @@ ATRewriteTables(List **wqueue)
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
errmsg
(
"cannot rewrite temporary tables of other sessions"
)));
/*
* Select destination tablespace (same as original unless user
* requested a change)
*/
if
(
tab
->
newTableSpace
)
NewTableSpace
=
tab
->
newTableSpace
;
else
NewTableSpace
=
OldHeap
->
rd_rel
->
reltablespace
;
heap_close
(
OldHeap
,
NoLock
);
/*
...
...
@@ -2170,7 +2196,7 @@ ATRewriteTables(List **wqueue)
snprintf
(
NewHeapName
,
sizeof
(
NewHeapName
),
"pg_temp_%u"
,
tab
->
relid
);
OIDNewHeap
=
make_new_heap
(
tab
->
relid
,
NewHeapName
);
OIDNewHeap
=
make_new_heap
(
tab
->
relid
,
NewHeapName
,
NewTableSpace
);
/*
* Copy the heap data into the new table with the desired
...
...
@@ -2179,8 +2205,8 @@ ATRewriteTables(List **wqueue)
*/
ATRewriteTable
(
tab
,
OIDNewHeap
);
/* Swap the
relfilenod
es of the old and new heaps. */
swap_rel
filenod
es
(
tab
->
relid
,
OIDNewHeap
);
/* Swap the
physical fil
es of the old and new heaps. */
swap_rel
ation_fil
es
(
tab
->
relid
,
OIDNewHeap
);
CommandCounterIncrement
();
...
...
@@ -2203,13 +2229,20 @@ ATRewriteTables(List **wqueue)
*/
reindex_relation
(
tab
->
relid
,
false
);
}
else
if
(
tab
->
constraints
!=
NIL
)
else
{
/*
* Test the current data within the table against new constraints
* generated by ALTER TABLE commands, but don't rebuild data.
*/
if
(
tab
->
constraints
!=
NIL
)
ATRewriteTable
(
tab
,
InvalidOid
);
/*
* If we had SET TABLESPACE but no reason to reconstruct tuples,
* just do a block-by-block copy.
*/
if
(
tab
->
newTableSpace
)
ATExecSetTableSpace
(
tab
->
relid
,
tab
->
newTableSpace
);
}
}
...
...
@@ -5185,6 +5218,249 @@ ATExecDropCluster(Relation rel)
mark_index_clustered
(
rel
,
InvalidOid
);
}
/*
* ALTER TABLE SET TABLESPACE
*/
static
void
ATPrepSetTableSpace
(
AlteredTableInfo
*
tab
,
Relation
rel
,
char
*
tablespacename
)
{
Oid
tablespaceId
;
AclResult
aclresult
;
/*
* We do our own permission checking because we want to allow this on
* indexes.
*/
if
(
rel
->
rd_rel
->
relkind
!=
RELKIND_RELATION
&&
rel
->
rd_rel
->
relkind
!=
RELKIND_INDEX
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_WRONG_OBJECT_TYPE
),
errmsg
(
"
\"
%s
\"
is not a table or index"
,
RelationGetRelationName
(
rel
))));
/* Permissions checks */
if
(
!
pg_class_ownercheck
(
RelationGetRelid
(
rel
),
GetUserId
()))
aclcheck_error
(
ACLCHECK_NOT_OWNER
,
ACL_KIND_CLASS
,
RelationGetRelationName
(
rel
));
if
(
!
allowSystemTableMods
&&
IsSystemRelation
(
rel
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INSUFFICIENT_PRIVILEGE
),
errmsg
(
"permission denied:
\"
%s
\"
is a system catalog"
,
RelationGetRelationName
(
rel
))));
/* Check that the tablespace exists */
tablespaceId
=
get_tablespace_oid
(
tablespacename
);
if
(
!
OidIsValid
(
tablespaceId
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_UNDEFINED_OBJECT
),
errmsg
(
"tablespace
\"
%s
\"
does not exist"
,
tablespacename
)));
/* Check its permissions */
aclresult
=
pg_tablespace_aclcheck
(
tablespaceId
,
GetUserId
(),
ACL_CREATE
);
if
(
aclresult
!=
ACLCHECK_OK
)
aclcheck_error
(
aclresult
,
ACL_KIND_TABLESPACE
,
tablespacename
);
/* Save info for Phase 3 to do the real work */
if
(
OidIsValid
(
tab
->
newTableSpace
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_SYNTAX_ERROR
),
errmsg
(
"multiple SET TABLESPACE subcommands are not valid"
)));
tab
->
newTableSpace
=
tablespaceId
;
}
/*
* Execute ALTER TABLE SET TABLESPACE for cases where there is no tuple
* rewriting to be done, so we just want to copy the data as fast as possible.
*/
static
void
ATExecSetTableSpace
(
Oid
tableOid
,
Oid
newTableSpace
)
{
Relation
rel
;
Oid
oldTableSpace
;
Oid
reltoastrelid
;
Oid
reltoastidxid
;
RelFileNode
newrnode
;
SMgrRelation
dstrel
;
Relation
pg_class
;
HeapTuple
tuple
;
Form_pg_class
rd_rel
;
rel
=
relation_open
(
tableOid
,
NoLock
);
/*
* We can never allow moving of shared or nailed-in-cache relations,
* because we can't support changing their reltablespace values.
*/
if
(
rel
->
rd_rel
->
relisshared
||
rel
->
rd_isnailed
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
errmsg
(
"cannot move system relation
\"
%s
\"
"
,
RelationGetRelationName
(
rel
))));
/*
* Don't allow moving temp tables of other backends ... their
* local buffer manager is not going to cope.
*/
if
(
isOtherTempNamespace
(
RelationGetNamespace
(
rel
)))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_FEATURE_NOT_SUPPORTED
),
errmsg
(
"cannot move temporary tables of other sessions"
)));
/*
* No work if no change in tablespace.
*/
oldTableSpace
=
rel
->
rd_rel
->
reltablespace
;
if
(
newTableSpace
==
oldTableSpace
||
(
newTableSpace
==
MyDatabaseTableSpace
&&
oldTableSpace
==
0
))
{
relation_close
(
rel
,
NoLock
);
return
;
}
reltoastrelid
=
rel
->
rd_rel
->
reltoastrelid
;
reltoastidxid
=
rel
->
rd_rel
->
reltoastidxid
;
/* Get a modifiable copy of the relation's pg_class row */
pg_class
=
heap_openr
(
RelationRelationName
,
RowExclusiveLock
);
tuple
=
SearchSysCacheCopy
(
RELOID
,
ObjectIdGetDatum
(
tableOid
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
tuple
))
elog
(
ERROR
,
"cache lookup failed for relation %u"
,
tableOid
);
rd_rel
=
(
Form_pg_class
)
GETSTRUCT
(
tuple
);
/* create another storage file. Is it a little ugly ? */
/* NOTE: any conflict in relfilenode value will be caught here */
newrnode
=
rel
->
rd_node
;
newrnode
.
spcNode
=
newTableSpace
;
dstrel
=
smgropen
(
newrnode
);
smgrcreate
(
dstrel
,
rel
->
rd_istemp
,
false
);
/* schedule unlinking old physical file */
if
(
rel
->
rd_smgr
==
NULL
)
rel
->
rd_smgr
=
smgropen
(
rel
->
rd_node
);
smgrscheduleunlink
(
rel
->
rd_smgr
,
rel
->
rd_istemp
);
/* copy relation data to the new physical file */
copy_relation_data
(
rel
,
dstrel
);
/*
* Now drop smgr references. We need not smgrclose() the old file,
* since it will be dropped anyway at commit by the pending unlink.
* We do need to get rid of relcache's reference to it, however.
*/
smgrclose
(
dstrel
);
rel
->
rd_smgr
=
NULL
;
/* update the pg_class row */
rd_rel
->
reltablespace
=
(
newTableSpace
==
MyDatabaseTableSpace
)
?
InvalidOid
:
newTableSpace
;
simple_heap_update
(
pg_class
,
&
tuple
->
t_self
,
tuple
);
CatalogUpdateIndexes
(
pg_class
,
tuple
);
heap_freetuple
(
tuple
);
heap_close
(
pg_class
,
RowExclusiveLock
);
relation_close
(
rel
,
NoLock
);
/* Make sure the reltablespace change is visible */
CommandCounterIncrement
();
/* Move associated toast relation and/or index, too */
if
(
OidIsValid
(
reltoastrelid
))
ATExecSetTableSpace
(
reltoastrelid
,
newTableSpace
);
if
(
OidIsValid
(
reltoastidxid
))
ATExecSetTableSpace
(
reltoastidxid
,
newTableSpace
);
}
/*
* Copy data, block by block
*/
static
void
copy_relation_data
(
Relation
rel
,
SMgrRelation
dst
)
{
SMgrRelation
src
=
rel
->
rd_smgr
;
bool
use_wal
;
BlockNumber
nblocks
;
BlockNumber
blkno
;
char
buf
[
BLCKSZ
];
Page
page
=
(
Page
)
buf
;
/*
* Since we copy the data directly without looking at the shared buffers,
* we'd better first flush out any pages of the source relation that are
* in shared buffers. We assume no new pages will get loaded into
* buffers while we are holding exclusive lock on the rel.
*/
FlushRelationBuffers
(
rel
,
0
);
/*
* We need to log the copied data in WAL iff WAL archiving is enabled
* AND it's not a temp rel.
*
* XXX when WAL archiving is actually supported, this test will likely
* need to change; and the hardwired extern is cruddy anyway ...
*/
{
extern
char
XLOG_archive_dir
[];
use_wal
=
XLOG_archive_dir
[
0
]
&&
!
rel
->
rd_istemp
;
}
nblocks
=
RelationGetNumberOfBlocks
(
rel
);
for
(
blkno
=
0
;
blkno
<
nblocks
;
blkno
++
)
{
smgrread
(
src
,
blkno
,
buf
);
/* XLOG stuff */
if
(
use_wal
)
{
xl_heap_newpage
xlrec
;
XLogRecPtr
recptr
;
XLogRecData
rdata
[
2
];
/* NO ELOG(ERROR) from here till newpage op is logged */
START_CRIT_SECTION
();
xlrec
.
node
=
dst
->
smgr_rnode
;
xlrec
.
blkno
=
blkno
;
rdata
[
0
].
buffer
=
InvalidBuffer
;
rdata
[
0
].
data
=
(
char
*
)
&
xlrec
;
rdata
[
0
].
len
=
SizeOfHeapNewpage
;
rdata
[
0
].
next
=
&
(
rdata
[
1
]);
rdata
[
1
].
buffer
=
InvalidBuffer
;
rdata
[
1
].
data
=
(
char
*
)
page
;
rdata
[
1
].
len
=
BLCKSZ
;
rdata
[
1
].
next
=
NULL
;
recptr
=
XLogInsert
(
RM_HEAP_ID
,
XLOG_HEAP_NEWPAGE
,
rdata
);
PageSetLSN
(
page
,
recptr
);
PageSetSUI
(
page
,
ThisStartUpID
);
END_CRIT_SECTION
();
}
/*
* Now write the page. If not using WAL, say isTemp = true, to
* suppress duplicate fsync. If we are using WAL, it surely isn't a
* temp rel, so !use_wal is a sufficient condition.
*/
smgrwrite
(
dst
,
blkno
,
buf
,
!
use_wal
);
}
/*
* If we weren't using WAL, and the rel isn't temp, we must fsync it
* down to disk before it's safe to commit the transaction.
*/
if
(
!
use_wal
&&
!
rel
->
rd_istemp
)
smgrimmedsync
(
dst
);
}
/*
* ALTER TABLE CREATE TOAST TABLE
...
...
src/backend/parser/gram.y
View file @
af4de814
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.46
5 2004/06/28 01:19:11
tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.46
6 2004/07/11 23:13:54
tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -1286,6 +1286,14 @@ alter_table_cmd:
n->name = NULL;
$$ = (Node *)n;
}
/* ALTER TABLE <name> SET TABLESPACE <tablespacename> */
| SET TABLESPACE name
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_SetTableSpace;
n->name = $3;
$$ = (Node *)n;
}
;
alter_column_default:
...
...
src/include/commands/cluster.h
View file @
af4de814
...
...
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994-5, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/commands/cluster.h,v 1.2
3 2004/05/08 00:34:49
tgl Exp $
* $PostgreSQL: pgsql/src/include/commands/cluster.h,v 1.2
4 2004/07/11 23:13:56
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -21,7 +21,8 @@ extern void cluster(ClusterStmt *stmt);
extern
void
check_index_is_clusterable
(
Relation
OldHeap
,
Oid
indexOid
);
extern
void
mark_index_clustered
(
Relation
rel
,
Oid
indexOid
);
extern
Oid
make_new_heap
(
Oid
OIDOldHeap
,
const
char
*
NewName
);
extern
void
swap_relfilenodes
(
Oid
r1
,
Oid
r2
);
extern
Oid
make_new_heap
(
Oid
OIDOldHeap
,
const
char
*
NewName
,
Oid
NewTableSpace
);
extern
void
swap_relation_files
(
Oid
r1
,
Oid
r2
);
#endif
/* CLUSTER_H */
src/include/nodes/parsenodes.h
View file @
af4de814
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.26
0 2004/06/25 21:55:59
tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.26
1 2004/07/11 23:13:58
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -806,7 +806,8 @@ typedef enum AlterTableType
AT_ChangeOwner
,
/* change owner */
AT_ClusterOn
,
/* CLUSTER ON */
AT_DropCluster
,
/* SET WITHOUT CLUSTER */
AT_DropOids
/* SET WITHOUT OIDS */
AT_DropOids
,
/* SET WITHOUT OIDS */
AT_SetTableSpace
/* SET TABLESPACE */
}
AlterTableType
;
typedef
struct
AlterTableCmd
/* one subcommand of an ALTER TABLE */
...
...
@@ -814,7 +815,7 @@ typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */
NodeTag
type
;
AlterTableType
subtype
;
/* Type of table alteration to apply */
char
*
name
;
/* column or constraint name to act on, or
* new owner */
* new owner
or tablespace
*/
Node
*
def
;
/* definition of new column, column type,
* index, or constraint */
Node
*
transform
;
/* transformation expr for ALTER TYPE */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment