!4136 Rename支持修改表的schema
Merge pull request !4136 from Cross-罗/rename_support_schema
This commit is contained in:
@ -5585,6 +5585,7 @@ static RenameStmt* _copyRenameStmt(const RenameStmt* from)
|
||||
COPY_NODE_FIELD(objarg);
|
||||
COPY_STRING_FIELD(subname);
|
||||
COPY_STRING_FIELD(newname);
|
||||
COPY_STRING_FIELD(newschema);
|
||||
COPY_SCALAR_FIELD(behavior);
|
||||
COPY_SCALAR_FIELD(missing_ok);
|
||||
COPY_NODE_FIELD(renameTargetList);
|
||||
|
||||
@ -1585,6 +1585,7 @@ static bool _equalRenameStmt(const RenameStmt* a, const RenameStmt* b)
|
||||
COMPARE_NODE_FIELD(objarg);
|
||||
COMPARE_STRING_FIELD(subname);
|
||||
COMPARE_STRING_FIELD(newname);
|
||||
COMPARE_STRING_FIELD(newschema);
|
||||
COMPARE_SCALAR_FIELD(behavior);
|
||||
COMPARE_SCALAR_FIELD(missing_ok);
|
||||
COMPARE_NODE_FIELD(renameTargetList);
|
||||
|
||||
@ -17696,23 +17696,25 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
|
||||
n->missing_ok = true;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER TABLE relation_expr RENAME TO name
|
||||
| ALTER TABLE relation_expr RENAME TO qualified_name
|
||||
{
|
||||
RenameStmt *n = makeNode(RenameStmt);
|
||||
n->renameType = OBJECT_TABLE;
|
||||
n->relation = $3;
|
||||
n->subname = NULL;
|
||||
n->newname = $6;
|
||||
n->newname = $6->relname;
|
||||
n->newschema = $6->schemaname;
|
||||
n->missing_ok = false;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER TABLE IF_P EXISTS relation_expr RENAME TO name
|
||||
| ALTER TABLE IF_P EXISTS relation_expr RENAME TO qualified_name
|
||||
{
|
||||
RenameStmt *n = makeNode(RenameStmt);
|
||||
n->renameType = OBJECT_TABLE;
|
||||
n->relation = $5;
|
||||
n->subname = NULL;
|
||||
n->newname = $8;
|
||||
n->newname = $8->relname;
|
||||
n->newschema = $8->schemaname;
|
||||
n->missing_ok = true;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
|
||||
@ -781,6 +781,8 @@ static int128 EvaluateAutoIncrement(Relation rel, TupleDesc desc, AttrNumber att
|
||||
static void SetRelAutoIncrement(Relation rel, TupleDesc desc, int128 autoinc);
|
||||
static Node* RecookAutoincAttrDefault(Relation rel, int attrno, Oid targettype, int targettypmod);
|
||||
static void check_unsupported_charset_for_column(Oid collation, const char* col_name);
|
||||
static void AlterTableNamespaceDependentProcess(Relation classRel ,Relation rel, Oid oldNspOid,
|
||||
Oid nspOid, ObjectAddresses* objsMoved, char* newrelname);
|
||||
|
||||
inline static bool CStoreSupportATCmd(AlterTableType cmdtype)
|
||||
{
|
||||
@ -6585,7 +6587,7 @@ ObjectAddress RenameRelation(RenameStmt* stmt)
|
||||
#endif
|
||||
|
||||
/* Do the work */
|
||||
RenameRelationInternal(relid, stmt->newname);
|
||||
RenameRelationInternal(relid, stmt->newname, stmt->newschema);
|
||||
/*
|
||||
* Record the changecsn of the table that defines the index
|
||||
*/
|
||||
@ -6610,13 +6612,22 @@ ObjectAddress RenameRelation(RenameStmt* stmt)
|
||||
* the sequence name should probably be removed from the
|
||||
* sequence, AFAIK there's no need for it to be there.
|
||||
*/
|
||||
void RenameRelationInternal(Oid myrelid, const char* newrelname)
|
||||
void RenameRelationInternal(Oid myrelid, const char* newrelname, char* newschema)
|
||||
{
|
||||
Relation targetrelation;
|
||||
Relation relrelation; /* for RELATION relation */
|
||||
HeapTuple reltup;
|
||||
Form_pg_class relform;
|
||||
Oid namespaceId;
|
||||
Oid oldNspOid = InvalidOid;
|
||||
bool needChangeNsp = false;
|
||||
ObjectAddresses* objsMoved = NULL;
|
||||
ObjectAddress thisobj;
|
||||
bool is_present = false;
|
||||
|
||||
thisobj.classId = RelationRelationId;
|
||||
thisobj.objectId = myrelid;
|
||||
thisobj.objectSubId = 0;
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, index, sequence or view,
|
||||
@ -6624,6 +6635,26 @@ void RenameRelationInternal(Oid myrelid, const char* newrelname)
|
||||
*/
|
||||
targetrelation = relation_open(myrelid, AccessExclusiveLock);
|
||||
|
||||
if (newschema != NULL) {
|
||||
if (targetrelation->rd_mlogoid != InvalidOid) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
(errmsg("Un-support feature"),
|
||||
errdetail("table owning matview doesn't support this ALTER yet."))));
|
||||
}
|
||||
|
||||
if (targetrelation->rd_rel->relkind == RELKIND_MATVIEW) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("ALTER MATERIALIZED VIEW is not yet supported.")));
|
||||
}
|
||||
|
||||
/* Permission check */
|
||||
if (!pg_class_ownercheck(RelationGetRelid(targetrelation), GetUserId())) {
|
||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(targetrelation));
|
||||
}
|
||||
}
|
||||
|
||||
if (RelationIsSubPartitioned(targetrelation)) {
|
||||
ereport(
|
||||
ERROR,
|
||||
@ -6655,6 +6686,24 @@ void RenameRelationInternal(Oid myrelid, const char* newrelname)
|
||||
|
||||
relform = (Form_pg_class)GETSTRUCT(reltup);
|
||||
|
||||
|
||||
oldNspOid = namespaceId;
|
||||
if (newschema != NULL) {
|
||||
/* Get and lock schema OID and check its permissions. */
|
||||
RangeVar* newrv = makeRangeVar(newschema, (char*)newrelname, -1);
|
||||
Oid newNspOid = RangeVarGetAndCheckCreationNamespace(newrv, NoLock, NULL, '\0');
|
||||
|
||||
needChangeNsp = (newNspOid != namespaceId);
|
||||
if (needChangeNsp) {
|
||||
/* common checks on switching namespaces */
|
||||
CheckSetNamespace(namespaceId, newNspOid, RelationRelationId, myrelid);
|
||||
ledger_check_switch_schema(namespaceId, newNspOid);
|
||||
objsMoved = new_object_addresses();
|
||||
namespaceId = newNspOid;
|
||||
is_present = object_address_present(&thisobj, objsMoved);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check relation name to ensure that it doesn't conflict with existing synonym.
|
||||
*/
|
||||
@ -6664,8 +6713,17 @@ void RenameRelationInternal(Oid myrelid, const char* newrelname)
|
||||
get_namespace_name(namespaceId))));
|
||||
}
|
||||
|
||||
if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
|
||||
ereport(ERROR, (errcode(ERRCODE_DUPLICATE_TABLE), errmsg("relation \"%s\" already exists", newrelname)));
|
||||
if (get_relname_relid(newrelname, namespaceId) != InvalidOid) {
|
||||
if (newschema != NULL) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DUPLICATE_TABLE),
|
||||
errmsg("relation \"%s\" already exists in schema \"%s\"",
|
||||
newrelname,
|
||||
newschema)));
|
||||
} else {
|
||||
ereport(ERROR, (errcode(ERRCODE_DUPLICATE_TABLE), errmsg("relation \"%s\" already exists", newrelname)));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (RelationIsTsStore(targetrelation)) {
|
||||
@ -6692,6 +6750,9 @@ void RenameRelationInternal(Oid myrelid, const char* newrelname)
|
||||
*/
|
||||
(void)namestrcpy(&(relform->relname), newrelname);
|
||||
|
||||
/* Update pg_class tuple with new nsp. */
|
||||
relform->relnamespace = namespaceId;
|
||||
|
||||
simple_heap_update(relrelation, &reltup->t_self, reltup);
|
||||
|
||||
/* keep the system catalog indexes current */
|
||||
@ -6708,14 +6769,33 @@ void RenameRelationInternal(Oid myrelid, const char* newrelname)
|
||||
renamePartitionedTable(myrelid, newrelname);
|
||||
}
|
||||
|
||||
if (needChangeNsp && !is_present) {
|
||||
if (changeDependencyFor(RelationRelationId, myrelid, NamespaceRelationId, oldNspOid, namespaceId) != 1) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("failed to change schema dependency for relation \"%s\"", NameStr(relform->relname))));
|
||||
}
|
||||
|
||||
add_exact_object_address(&thisobj, objsMoved);
|
||||
}
|
||||
|
||||
tableam_tops_free_tuple(reltup);
|
||||
heap_close(relrelation, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
* Also rename the associated type, if any.
|
||||
*/
|
||||
if (OidIsValid(targetrelation->rd_rel->reltype))
|
||||
RenameTypeInternal(targetrelation->rd_rel->reltype, newrelname, namespaceId);
|
||||
if (needChangeNsp && !is_present) {
|
||||
AlterTableNamespaceDependentProcess(relrelation, targetrelation, oldNspOid, namespaceId, objsMoved,
|
||||
(char*)newrelname);
|
||||
if (targetrelation->rd_isblockchain) {
|
||||
rename_hist_by_newnsp(myrelid, newschema);
|
||||
}
|
||||
free_object_addresses(objsMoved);
|
||||
} else {
|
||||
/*
|
||||
* Also rename the associated type, if any.
|
||||
*/
|
||||
if (OidIsValid(targetrelation->rd_rel->reltype))
|
||||
RenameTypeInternal(targetrelation->rd_rel->reltype, newrelname, oldNspOid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Also rename the associated constraint, if any.
|
||||
@ -21500,8 +21580,16 @@ void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid, Object
|
||||
|
||||
AlterRelationNamespaceInternal(classRel, RelationGetRelid(rel), oldNspOid, nspOid, true, objsMoved);
|
||||
|
||||
AlterTableNamespaceDependentProcess(classRel, rel, oldNspOid, nspOid, objsMoved, NULL);
|
||||
|
||||
heap_close(classRel, RowExclusiveLock);
|
||||
}
|
||||
|
||||
static void AlterTableNamespaceDependentProcess(Relation classRel ,Relation rel, Oid oldNspOid,
|
||||
Oid nspOid, ObjectAddresses* objsMoved, char* newrelname)
|
||||
{
|
||||
/* Fix the table's row type too */
|
||||
(void)AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false, false, objsMoved);
|
||||
(void)AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false, false, objsMoved, newrelname);
|
||||
|
||||
/* Change the table's set type too */
|
||||
TupleDesc tupDesc = rel->rd_att;
|
||||
@ -21518,8 +21606,6 @@ void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid, Object
|
||||
AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid, objsMoved, AccessExclusiveLock);
|
||||
AlterConstraintNamespaces(RelationGetRelid(rel), oldNspOid, nspOid, false, objsMoved);
|
||||
}
|
||||
|
||||
heap_close(classRel, RowExclusiveLock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -3653,7 +3653,7 @@ Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses* objsMoved)
|
||||
* Returns the type's old namespace OID.
|
||||
*/
|
||||
Oid AlterTypeNamespaceInternal(
|
||||
Oid typeOid, Oid nspOid, bool isImplicitArray, bool errorOnTableType, ObjectAddresses* objsMoved)
|
||||
Oid typeOid, Oid nspOid, bool isImplicitArray, bool errorOnTableType, ObjectAddresses* objsMoved, char* newTypeName)
|
||||
{
|
||||
Relation rel;
|
||||
HeapTuple tup;
|
||||
@ -3687,7 +3687,8 @@ Oid AlterTypeNamespaceInternal(
|
||||
CheckSetNamespace(oldNspOid, nspOid, TypeRelationId, typeOid);
|
||||
|
||||
/* check for duplicate name (more friendly than unique-index failure) */
|
||||
if (SearchSysCacheExists2(TYPENAMENSP, CStringGetDatum(NameStr(typform->typname)), ObjectIdGetDatum(nspOid)))
|
||||
char* checkTypeName = (newTypeName == NULL) ? NameStr(typform->typname) : newTypeName;
|
||||
if (SearchSysCacheExists2(TYPENAMENSP, CStringGetDatum(checkTypeName), ObjectIdGetDatum(nspOid)))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
||||
errmsg("type \"%s\" already exists in schema \"%s\"",
|
||||
@ -3709,6 +3710,9 @@ Oid AlterTypeNamespaceInternal(
|
||||
* tup is a copy, so we can scribble directly on it
|
||||
*/
|
||||
typform->typnamespace = nspOid;
|
||||
if (newTypeName != NULL) {
|
||||
(void)namestrcpy(&(typform->typname), newTypeName);
|
||||
}
|
||||
|
||||
simple_heap_update(rel, &tup->t_self, tup);
|
||||
CatalogUpdateIndexes(rel, tup);
|
||||
@ -3756,8 +3760,10 @@ Oid AlterTypeNamespaceInternal(
|
||||
add_exact_object_address(&thisobj, objsMoved);
|
||||
|
||||
/* Recursively alter the associated array type, if any */
|
||||
if (OidIsValid(arrayOid))
|
||||
AlterTypeNamespaceInternal(arrayOid, nspOid, true, true, objsMoved);
|
||||
if (OidIsValid(arrayOid)) {
|
||||
AlterTypeNamespaceInternal(arrayOid, nspOid, true, true, objsMoved,
|
||||
(newTypeName == NULL) ? NULL : makeArrayTypeName(newTypeName, nspOid));
|
||||
}
|
||||
|
||||
return oldNspOid;
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ extern ObjectAddress RenameConstraint(RenameStmt* stmt);
|
||||
|
||||
extern ObjectAddress RenameRelation(RenameStmt* stmt);
|
||||
|
||||
extern void RenameRelationInternal(Oid myrelid, const char* newrelname);
|
||||
extern void RenameRelationInternal(Oid myrelid, const char* newrelname, char* newschema = NULL);
|
||||
|
||||
extern void find_composite_type_dependencies(Oid typeOid, Relation origRelation, const char* origTypeName);
|
||||
|
||||
|
||||
@ -47,7 +47,8 @@ extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, bool hasDependEn
|
||||
extern ObjectAddress AlterTypeNamespace(List* names, const char* newschema, ObjectType objecttype);
|
||||
extern Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses* objsMoved);
|
||||
extern Oid AlterTypeNamespaceInternal(
|
||||
Oid typeOid, Oid nspOid, bool isImplicitArray, bool errorOnTableType, ObjectAddresses* objsMoved);
|
||||
Oid typeOid, Oid nspOid, bool isImplicitArray, bool errorOnTableType, ObjectAddresses* objsMoved,
|
||||
char* newTypeName = NULL);
|
||||
extern void AlterTypeOwnerByPkg(Oid pkgOid, Oid newOwnerId);
|
||||
extern void AlterTypeOwnerByFunc(Oid funcOid, Oid newOwnerId);
|
||||
|
||||
|
||||
@ -2380,6 +2380,7 @@ typedef struct RenameStmt {
|
||||
char* subname; /* name of contained object (column, rule,
|
||||
* trigger, etc) */
|
||||
char* newname; /* the new name */
|
||||
char* newschema; /* the new schema name */
|
||||
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
|
||||
bool missing_ok; /* skip error if missing? */
|
||||
List* renameTargetList = NULL;
|
||||
|
||||
@ -8796,5 +8796,293 @@ SELECT pg_get_tabledef('t1');
|
||||
(1 row)
|
||||
|
||||
drop table if exists t1 cascade;
|
||||
-- test about setting schema by RenameStmt
|
||||
CREATE SCHEMA test1;
|
||||
CREATE SCHEMA test2;
|
||||
CREATE TABLE test1.test(a int primary key, b int not null);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test"
|
||||
CREATE INDEX ON test1.test using btree(b);
|
||||
INSERT INTO test1.test VALUES (1, 1);
|
||||
\d+ test1.test
|
||||
Table "test1.test"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
--------+---------+-----------+---------+--------------+-------------
|
||||
a | integer | not null | plain | |
|
||||
b | integer | not null | plain | |
|
||||
Indexes:
|
||||
"test_pkey" PRIMARY KEY, btree (a) TABLESPACE pg_default
|
||||
"test_b_idx" btree (b) TABLESPACE pg_default
|
||||
Has OIDs: no
|
||||
Options: orientation=row, compression=no
|
||||
|
||||
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt');
|
||||
nspname | relname
|
||||
---------+------------
|
||||
test1 | test
|
||||
test1 | test_pkey
|
||||
test1 | test_b_idx
|
||||
(3 rows)
|
||||
|
||||
SELECT * FROM test1.test;
|
||||
a | b
|
||||
---+---
|
||||
1 | 1
|
||||
(1 row)
|
||||
|
||||
-- check about type
|
||||
SELECT n.nspname, t.typname FROM pg_type t, pg_namespace n where t.typnamespace = n.oid and t.typname in ('test','tttt');
|
||||
nspname | typname
|
||||
---------+---------
|
||||
test1 | test
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE test1.test RENAME TO test2.tttt;
|
||||
\d+ test1.test
|
||||
\d+ test2.tttt
|
||||
Table "test2.tttt"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
--------+---------+-----------+---------+--------------+-------------
|
||||
a | integer | not null | plain | |
|
||||
b | integer | not null | plain | |
|
||||
Indexes:
|
||||
"test_pkey" PRIMARY KEY, btree (a) TABLESPACE pg_default
|
||||
"test_b_idx" btree (b) TABLESPACE pg_default
|
||||
Has OIDs: no
|
||||
Options: orientation=row, compression=no
|
||||
|
||||
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt');
|
||||
nspname | relname
|
||||
---------+------------
|
||||
test2 | tttt
|
||||
test2 | test_pkey
|
||||
test2 | test_b_idx
|
||||
(3 rows)
|
||||
|
||||
INSERT INTO test2.tttt VALUES (2, 2);
|
||||
SELECT * FROM test1.test;
|
||||
ERROR: relation "test1.test" does not exist on datanode1
|
||||
LINE 1: SELECT * FROM test1.test;
|
||||
^
|
||||
SELECT * FROM test2.tttt;
|
||||
a | b
|
||||
---+---
|
||||
1 | 1
|
||||
2 | 2
|
||||
(2 rows)
|
||||
|
||||
-- check about type
|
||||
SELECT n.nspname, t.typname FROM pg_type t, pg_namespace n where t.typnamespace = n.oid and t.typname in ('test','tttt');
|
||||
nspname | typname
|
||||
---------+---------
|
||||
test2 | tttt
|
||||
(1 row)
|
||||
|
||||
-- just rename
|
||||
ALTER TABLE test2.tttt RENAME TO test2.ttt;
|
||||
SELECT * FROM test2.tttt;
|
||||
ERROR: relation "test2.tttt" does not exist on datanode1
|
||||
LINE 1: SELECT * FROM test2.tttt;
|
||||
^
|
||||
SELECT * FROM test2.ttt;
|
||||
a | b
|
||||
---+---
|
||||
1 | 1
|
||||
2 | 2
|
||||
(2 rows)
|
||||
|
||||
-- check about type
|
||||
SELECT n.nspname, t.typname FROM pg_type t, pg_namespace n where t.typnamespace = n.oid and t.typname = 'ttt';
|
||||
nspname | typname
|
||||
---------+---------
|
||||
test2 | ttt
|
||||
(1 row)
|
||||
|
||||
-- just move to other schema
|
||||
CREATE TABLE test1.t1 (a int);
|
||||
\d+ test1.t1
|
||||
Table "test1.t1"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
--------+---------+-----------+---------+--------------+-------------
|
||||
a | integer | | plain | |
|
||||
Has OIDs: no
|
||||
Options: orientation=row, compression=no
|
||||
|
||||
ALTER TABLE test1.t1 RENAME TO test2.t1;
|
||||
\d+ test1.t1
|
||||
\d+ test2.t1
|
||||
Table "test2.t1"
|
||||
Column | Type | Modifiers | Storage | Stats target | Description
|
||||
--------+---------+-----------+---------+--------------+-------------
|
||||
a | integer | | plain | |
|
||||
Has OIDs: no
|
||||
Options: orientation=row, compression=no
|
||||
|
||||
-- check about type
|
||||
SELECT n.nspname, t.typname FROM pg_type t, pg_namespace n where t.typnamespace = n.oid and t.typname = 't1';
|
||||
nspname | typname
|
||||
---------+---------
|
||||
test2 | t1
|
||||
(1 row)
|
||||
|
||||
-- test about partition table
|
||||
CREATE TABLE test1.sales_table1
|
||||
(
|
||||
order_no INTEGER NOT NULL,
|
||||
goods_name CHAR(20) NOT NULL,
|
||||
sales_date DATE NOT NULL,
|
||||
sales_volume INTEGER,
|
||||
sales_store CHAR(20)
|
||||
)
|
||||
PARTITION BY RANGE(sales_date)
|
||||
(
|
||||
PARTITION sales_table1_season1 VALUES LESS THAN('2021-04-01 00:00:00'),
|
||||
PARTITION sales_table1_season2 VALUES LESS THAN('2021-07-01 00:00:00'),
|
||||
PARTITION sales_table1_season3 VALUES LESS THAN('2021-10-01 00:00:00'),
|
||||
PARTITION sales_table1_season4 VALUES LESS THAN(MAXVALUE)
|
||||
);
|
||||
CREATE TABLE test1.sales_table2
|
||||
(
|
||||
order_no INTEGER NOT NULL,
|
||||
goods_name CHAR(20) NOT NULL,
|
||||
sales_date DATE NOT NULL,
|
||||
sales_volume INTEGER,
|
||||
sales_store CHAR(20)
|
||||
)
|
||||
PARTITION BY RANGE(sales_date)
|
||||
(
|
||||
PARTITION sales_table2_season1 VALUES LESS THAN('2021-04-01 00:00:00'),
|
||||
PARTITION sales_table2_season2 VALUES LESS THAN('2021-07-01 00:00:00'),
|
||||
PARTITION sales_table2_season3 VALUES LESS THAN('2021-10-01 00:00:00'),
|
||||
PARTITION sales_table2_season4 VALUES LESS THAN(MAXVALUE)
|
||||
);
|
||||
CREATE TABLE test1.sales_table3
|
||||
(
|
||||
order_no INTEGER NOT NULL,
|
||||
goods_name CHAR(20) NOT NULL,
|
||||
sales_date DATE NOT NULL,
|
||||
sales_volume INTEGER,
|
||||
sales_store CHAR(20)
|
||||
)
|
||||
PARTITION BY RANGE(sales_date)
|
||||
(
|
||||
PARTITION sales_table3_season1 VALUES LESS THAN('2021-04-01 00:00:00'),
|
||||
PARTITION sales_table3_season2 VALUES LESS THAN('2021-07-01 00:00:00'),
|
||||
PARTITION sales_table3_season3 VALUES LESS THAN('2021-10-01 00:00:00'),
|
||||
PARTITION sales_table3_season4 VALUES LESS THAN(MAXVALUE)
|
||||
);
|
||||
SELECT n.nspname, c.relname, p.relname AS partition_name
|
||||
FROM pg_class c, pg_namespace n, pg_partition p
|
||||
WHERE n.oid = c.relnamespace and c.oid = p.parentid and c.relname like '%sales_table%' ORDER BY 1, 2, 3;
|
||||
nspname | relname | partition_name
|
||||
---------+--------------+----------------------
|
||||
test1 | sales_table1 | sales_table1
|
||||
test1 | sales_table1 | sales_table1_season1
|
||||
test1 | sales_table1 | sales_table1_season2
|
||||
test1 | sales_table1 | sales_table1_season3
|
||||
test1 | sales_table1 | sales_table1_season4
|
||||
test1 | sales_table2 | sales_table2
|
||||
test1 | sales_table2 | sales_table2_season1
|
||||
test1 | sales_table2 | sales_table2_season2
|
||||
test1 | sales_table2 | sales_table2_season3
|
||||
test1 | sales_table2 | sales_table2_season4
|
||||
test1 | sales_table3 | sales_table3
|
||||
test1 | sales_table3 | sales_table3_season1
|
||||
test1 | sales_table3 | sales_table3_season2
|
||||
test1 | sales_table3 | sales_table3_season3
|
||||
test1 | sales_table3 | sales_table3_season4
|
||||
(15 rows)
|
||||
|
||||
ALTER TABLE test1.sales_table1 RENAME TO test2.sales_table1;
|
||||
ALTER TABLE test1.sales_table2 RENAME TO test2.sales_table3;
|
||||
ALTER TABLE test1.sales_table3 RENAME TO test1.sales_table4;
|
||||
SELECT n.nspname, c.relname, p.relname AS partition_name
|
||||
FROM pg_class c, pg_namespace n, pg_partition p
|
||||
WHERE n.oid = c.relnamespace and c.oid = p.parentid and c.relname like '%sales_table%' ORDER BY 1, 2, 3;
|
||||
nspname | relname | partition_name
|
||||
---------+--------------+----------------------
|
||||
test1 | sales_table4 | sales_table3_season1
|
||||
test1 | sales_table4 | sales_table3_season2
|
||||
test1 | sales_table4 | sales_table3_season3
|
||||
test1 | sales_table4 | sales_table3_season4
|
||||
test1 | sales_table4 | sales_table4
|
||||
test2 | sales_table1 | sales_table1
|
||||
test2 | sales_table1 | sales_table1_season1
|
||||
test2 | sales_table1 | sales_table1_season2
|
||||
test2 | sales_table1 | sales_table1_season3
|
||||
test2 | sales_table1 | sales_table1_season4
|
||||
test2 | sales_table3 | sales_table2_season1
|
||||
test2 | sales_table3 | sales_table2_season2
|
||||
test2 | sales_table3 | sales_table2_season3
|
||||
test2 | sales_table3 | sales_table2_season4
|
||||
test2 | sales_table3 | sales_table3
|
||||
(15 rows)
|
||||
|
||||
-- rename table with view or matview
|
||||
CREATE TABLE test1.test_table_view1 (a int);
|
||||
CREATE TABLE test1.test_table_view2 (a int);
|
||||
CREATE TABLE test1.test_table_matview1 (a int);
|
||||
CREATE TABLE test1.test_table_matview2 (a int);
|
||||
CREATE VIEW test1.test_view1 AS SELECT * FROM test1.test_table_view1;
|
||||
CREATE VIEW test1.test_view2 AS SELECT * FROM test1.test_table_view2;
|
||||
CREATE MATERIALIZED VIEW test1.test_matview1 AS SELECT * FROM test1.test_table_matview1;
|
||||
CREATE MATERIALIZED VIEW test1.test_matview2 AS SELECT * FROM test1.test_table_matview2;
|
||||
ALTER TABLE test1.test_table_view1 RENAME TO test2.test_table_view1; -- just move to other schema
|
||||
ALTER TABLE test1.test_table_view2 RENAME TO test2.test_table_view3; -- rename and move to other schema
|
||||
SELECT * FROM test1.test_view1;
|
||||
a
|
||||
---
|
||||
(0 rows)
|
||||
|
||||
SELECT pg_get_viewdef('test1.test_view1');
|
||||
pg_get_viewdef
|
||||
----------------------------------------
|
||||
SELECT * FROM test2.test_table_view1;
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test1.test_view2;
|
||||
a
|
||||
---
|
||||
(0 rows)
|
||||
|
||||
SELECT pg_get_viewdef('test1.test_view2');
|
||||
pg_get_viewdef
|
||||
---------------------------------------------------------
|
||||
SELECT * FROM test2.test_table_view3 test_table_view2;
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE test1.test_table_matview1 RENAME TO test2.test_table_matview1; -- just move to other schema
|
||||
ALTER TABLE test1.test_table_matview2 RENAME TO test2.test_table_matview3; -- rename and move to other schema
|
||||
SELECT * FROM test1.test_matview1;
|
||||
a
|
||||
---
|
||||
(0 rows)
|
||||
|
||||
SELECT pg_get_viewdef('test1.test_matview1');
|
||||
pg_get_viewdef
|
||||
-------------------------------------------
|
||||
SELECT * FROM test2.test_table_matview1;
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test1.test_matview2;
|
||||
a
|
||||
---
|
||||
(0 rows)
|
||||
|
||||
SELECT pg_get_viewdef('test1.test_matview2');
|
||||
pg_get_viewdef
|
||||
---------------------------------------------------------------
|
||||
SELECT * FROM test2.test_table_matview3 test_table_matview2;
|
||||
(1 row)
|
||||
|
||||
-- rename to a existed table
|
||||
CREATE TABLE test1.name1 (a int);
|
||||
CREATE TABLE test2.name1 (a int);
|
||||
CREATE TABLE test2.name2 (a int);
|
||||
ALTER TABLE test1.name1 RENAME TO test2.name1;
|
||||
ERROR: relation "name1" already exists in schema "test2"
|
||||
ALTER TABLE test1.name1 RENAME TO test2.name2;
|
||||
ERROR: relation "name2" already exists in schema "test2"
|
||||
ALTER TABLE test2.name1 RENAME TO test2.name2;
|
||||
ERROR: relation "name2" already exists in schema "test2"
|
||||
\c postgres
|
||||
drop database test_first_after_B;
|
||||
|
||||
@ -3256,5 +3256,133 @@ alter table t1 modify f1 int after f3, modify f5 bool first, modify f3 timestamp
|
||||
SELECT pg_get_tabledef('t1');
|
||||
drop table if exists t1 cascade;
|
||||
|
||||
-- test about setting schema by RenameStmt
|
||||
CREATE SCHEMA test1;
|
||||
CREATE SCHEMA test2;
|
||||
CREATE TABLE test1.test(a int primary key, b int not null);
|
||||
CREATE INDEX ON test1.test using btree(b);
|
||||
INSERT INTO test1.test VALUES (1, 1);
|
||||
\d+ test1.test
|
||||
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt');
|
||||
SELECT * FROM test1.test;
|
||||
-- check about type
|
||||
SELECT n.nspname, t.typname FROM pg_type t, pg_namespace n where t.typnamespace = n.oid and t.typname in ('test','tttt');
|
||||
ALTER TABLE test1.test RENAME TO test2.tttt;
|
||||
\d+ test1.test
|
||||
\d+ test2.tttt
|
||||
SELECT n.nspname, c.relname from pg_class c, pg_namespace n where n.oid = c.relnamespace and c.relname in ('test', 'test_pkey', 'test_b_idx', 'tttt');
|
||||
INSERT INTO test2.tttt VALUES (2, 2);
|
||||
SELECT * FROM test1.test;
|
||||
SELECT * FROM test2.tttt;
|
||||
-- check about type
|
||||
SELECT n.nspname, t.typname FROM pg_type t, pg_namespace n where t.typnamespace = n.oid and t.typname in ('test','tttt');
|
||||
|
||||
-- just rename
|
||||
ALTER TABLE test2.tttt RENAME TO test2.ttt;
|
||||
SELECT * FROM test2.tttt;
|
||||
SELECT * FROM test2.ttt;
|
||||
-- check about type
|
||||
SELECT n.nspname, t.typname FROM pg_type t, pg_namespace n where t.typnamespace = n.oid and t.typname = 'ttt';
|
||||
|
||||
-- just move to other schema
|
||||
CREATE TABLE test1.t1 (a int);
|
||||
\d+ test1.t1
|
||||
ALTER TABLE test1.t1 RENAME TO test2.t1;
|
||||
\d+ test1.t1
|
||||
\d+ test2.t1
|
||||
-- check about type
|
||||
SELECT n.nspname, t.typname FROM pg_type t, pg_namespace n where t.typnamespace = n.oid and t.typname = 't1';
|
||||
|
||||
-- test about partition table
|
||||
CREATE TABLE test1.sales_table1
|
||||
(
|
||||
order_no INTEGER NOT NULL,
|
||||
goods_name CHAR(20) NOT NULL,
|
||||
sales_date DATE NOT NULL,
|
||||
sales_volume INTEGER,
|
||||
sales_store CHAR(20)
|
||||
)
|
||||
PARTITION BY RANGE(sales_date)
|
||||
(
|
||||
PARTITION sales_table1_season1 VALUES LESS THAN('2021-04-01 00:00:00'),
|
||||
PARTITION sales_table1_season2 VALUES LESS THAN('2021-07-01 00:00:00'),
|
||||
PARTITION sales_table1_season3 VALUES LESS THAN('2021-10-01 00:00:00'),
|
||||
PARTITION sales_table1_season4 VALUES LESS THAN(MAXVALUE)
|
||||
);
|
||||
|
||||
CREATE TABLE test1.sales_table2
|
||||
(
|
||||
order_no INTEGER NOT NULL,
|
||||
goods_name CHAR(20) NOT NULL,
|
||||
sales_date DATE NOT NULL,
|
||||
sales_volume INTEGER,
|
||||
sales_store CHAR(20)
|
||||
)
|
||||
PARTITION BY RANGE(sales_date)
|
||||
(
|
||||
PARTITION sales_table2_season1 VALUES LESS THAN('2021-04-01 00:00:00'),
|
||||
PARTITION sales_table2_season2 VALUES LESS THAN('2021-07-01 00:00:00'),
|
||||
PARTITION sales_table2_season3 VALUES LESS THAN('2021-10-01 00:00:00'),
|
||||
PARTITION sales_table2_season4 VALUES LESS THAN(MAXVALUE)
|
||||
);
|
||||
|
||||
CREATE TABLE test1.sales_table3
|
||||
(
|
||||
order_no INTEGER NOT NULL,
|
||||
goods_name CHAR(20) NOT NULL,
|
||||
sales_date DATE NOT NULL,
|
||||
sales_volume INTEGER,
|
||||
sales_store CHAR(20)
|
||||
)
|
||||
PARTITION BY RANGE(sales_date)
|
||||
(
|
||||
PARTITION sales_table3_season1 VALUES LESS THAN('2021-04-01 00:00:00'),
|
||||
PARTITION sales_table3_season2 VALUES LESS THAN('2021-07-01 00:00:00'),
|
||||
PARTITION sales_table3_season3 VALUES LESS THAN('2021-10-01 00:00:00'),
|
||||
PARTITION sales_table3_season4 VALUES LESS THAN(MAXVALUE)
|
||||
);
|
||||
SELECT n.nspname, c.relname, p.relname AS partition_name
|
||||
FROM pg_class c, pg_namespace n, pg_partition p
|
||||
WHERE n.oid = c.relnamespace and c.oid = p.parentid and c.relname like '%sales_table%' ORDER BY 1, 2, 3;
|
||||
ALTER TABLE test1.sales_table1 RENAME TO test2.sales_table1;
|
||||
ALTER TABLE test1.sales_table2 RENAME TO test2.sales_table3;
|
||||
ALTER TABLE test1.sales_table3 RENAME TO test1.sales_table4;
|
||||
SELECT n.nspname, c.relname, p.relname AS partition_name
|
||||
FROM pg_class c, pg_namespace n, pg_partition p
|
||||
WHERE n.oid = c.relnamespace and c.oid = p.parentid and c.relname like '%sales_table%' ORDER BY 1, 2, 3;
|
||||
|
||||
-- rename table with view or matview
|
||||
CREATE TABLE test1.test_table_view1 (a int);
|
||||
CREATE TABLE test1.test_table_view2 (a int);
|
||||
CREATE TABLE test1.test_table_matview1 (a int);
|
||||
CREATE TABLE test1.test_table_matview2 (a int);
|
||||
|
||||
CREATE VIEW test1.test_view1 AS SELECT * FROM test1.test_table_view1;
|
||||
CREATE VIEW test1.test_view2 AS SELECT * FROM test1.test_table_view2;
|
||||
CREATE MATERIALIZED VIEW test1.test_matview1 AS SELECT * FROM test1.test_table_matview1;
|
||||
CREATE MATERIALIZED VIEW test1.test_matview2 AS SELECT * FROM test1.test_table_matview2;
|
||||
|
||||
ALTER TABLE test1.test_table_view1 RENAME TO test2.test_table_view1; -- just move to other schema
|
||||
ALTER TABLE test1.test_table_view2 RENAME TO test2.test_table_view3; -- rename and move to other schema
|
||||
SELECT * FROM test1.test_view1;
|
||||
SELECT pg_get_viewdef('test1.test_view1');
|
||||
SELECT * FROM test1.test_view2;
|
||||
SELECT pg_get_viewdef('test1.test_view2');
|
||||
|
||||
ALTER TABLE test1.test_table_matview1 RENAME TO test2.test_table_matview1; -- just move to other schema
|
||||
ALTER TABLE test1.test_table_matview2 RENAME TO test2.test_table_matview3; -- rename and move to other schema
|
||||
SELECT * FROM test1.test_matview1;
|
||||
SELECT pg_get_viewdef('test1.test_matview1');
|
||||
SELECT * FROM test1.test_matview2;
|
||||
SELECT pg_get_viewdef('test1.test_matview2');
|
||||
|
||||
-- rename to a existed table
|
||||
CREATE TABLE test1.name1 (a int);
|
||||
CREATE TABLE test2.name1 (a int);
|
||||
CREATE TABLE test2.name2 (a int);
|
||||
ALTER TABLE test1.name1 RENAME TO test2.name1;
|
||||
ALTER TABLE test1.name1 RENAME TO test2.name2;
|
||||
ALTER TABLE test2.name1 RENAME TO test2.name2;
|
||||
|
||||
\c postgres
|
||||
drop database test_first_after_B;
|
||||
Reference in New Issue
Block a user