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
39d74e34
Commit
39d74e34
authored
Mar 10, 2012
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for renaming constraints
reviewed by Josh Berkus and Dimitri Fontaine
parent
e914a144
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
306 additions
and
3 deletions
+306
-3
doc/src/sgml/ref/alter_table.sgml
doc/src/sgml/ref/alter_table.sgml
+13
-3
src/backend/commands/alter.c
src/backend/commands/alter.c
+4
-0
src/backend/commands/tablecmds.c
src/backend/commands/tablecmds.c
+102
-0
src/backend/parser/gram.y
src/backend/parser/gram.y
+10
-0
src/include/commands/tablecmds.h
src/include/commands/tablecmds.h
+2
-0
src/test/regress/expected/alter_table.out
src/test/regress/expected/alter_table.out
+135
-0
src/test/regress/sql/alter_table.sql
src/test/regress/sql/alter_table.sql
+40
-0
No files found.
doc/src/sgml/ref/alter_table.sgml
View file @
39d74e34
...
...
@@ -25,6 +25,8 @@ ALTER TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="PARAMETER">name</replacea
<replaceable class="PARAMETER">action</replaceable> [, ... ]
ALTER TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="PARAMETER">name</replaceable> [ * ]
RENAME [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> TO <replaceable class="PARAMETER">new_column</replaceable>
ALTER TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="PARAMETER">name</replaceable> [ * ]
RENAME CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> TO <replaceable class="PARAMETER">new_constraint_name</replaceable>
ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
...
...
@@ -569,8 +571,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
<listitem>
<para>
The <literal>RENAME</literal> forms change the name of a table
(or an index, sequence, or view)
or
the name of an individual column in
a table. There is no effect on the stored data.
(or an index, sequence, or view)
,
the name of an individual column in
a table
, or the name of a constraint of the table
. There is no effect on the stored data.
</para>
</listitem>
</varlistentry>
...
...
@@ -883,7 +885,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
<para>
If a table has any descendant tables, it is not permitted to add,
rename, or change the type of a column in the parent table without doing
rename, or change the type of a column, or rename an inherited constraint
in the parent table without doing
the same to the descendants. That is, <command>ALTER TABLE ONLY</command>
will be rejected. This ensures that the descendants always have
columns matching the parent.
...
...
@@ -982,6 +985,13 @@ ALTER TABLE distributors RENAME TO suppliers;
</programlisting>
</para>
<para>
To rename an existing constraint:
<programlisting>
ALTER TABLE distributors RENAME CONSTRAINT zipchk TO zip_check;
</programlisting>
</para>
<para>
To add a not-null constraint to a column:
<programlisting>
...
...
src/backend/commands/alter.c
View file @
39d74e34
...
...
@@ -57,6 +57,10 @@ ExecRenameStmt(RenameStmt *stmt)
RenameCollation
(
stmt
->
object
,
stmt
->
newname
);
break
;
case
OBJECT_CONSTRAINT
:
RenameConstraint
(
stmt
);
break
;
case
OBJECT_CONVERSION
:
RenameConversion
(
stmt
->
object
,
stmt
->
newname
);
break
;
...
...
src/backend/commands/tablecmds.c
View file @
39d74e34
...
...
@@ -2327,6 +2327,108 @@ renameatt(RenameStmt *stmt)
stmt
->
behavior
);
}
/*
* same logic as renameatt_internal
*/
static
void
rename_constraint_internal
(
Oid
myrelid
,
const
char
*
oldconname
,
const
char
*
newconname
,
bool
recurse
,
bool
recursing
,
int
expected_parents
)
{
Relation
targetrelation
;
Oid
constraintOid
;
HeapTuple
tuple
;
Form_pg_constraint
con
;
targetrelation
=
relation_open
(
myrelid
,
AccessExclusiveLock
);
/* don't tell it whether we're recursing; we allow changing typed tables here */
renameatt_check
(
myrelid
,
RelationGetForm
(
targetrelation
),
false
);
constraintOid
=
get_constraint_oid
(
myrelid
,
oldconname
,
false
);
tuple
=
SearchSysCache1
(
CONSTROID
,
ObjectIdGetDatum
(
constraintOid
));
if
(
!
HeapTupleIsValid
(
tuple
))
elog
(
ERROR
,
"cache lookup failed for constraint %u"
,
constraintOid
);
con
=
(
Form_pg_constraint
)
GETSTRUCT
(
tuple
);
if
(
con
->
contype
==
CONSTRAINT_CHECK
&&
!
con
->
conisonly
)
{
if
(
recurse
)
{
List
*
child_oids
,
*
child_numparents
;
ListCell
*
lo
,
*
li
;
child_oids
=
find_all_inheritors
(
myrelid
,
AccessExclusiveLock
,
&
child_numparents
);
forboth
(
lo
,
child_oids
,
li
,
child_numparents
)
{
Oid
childrelid
=
lfirst_oid
(
lo
);
int
numparents
=
lfirst_int
(
li
);
if
(
childrelid
==
myrelid
)
continue
;
rename_constraint_internal
(
childrelid
,
oldconname
,
newconname
,
false
,
true
,
numparents
);
}
}
else
{
if
(
expected_parents
==
0
&&
find_inheritance_children
(
myrelid
,
NoLock
)
!=
NIL
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_TABLE_DEFINITION
),
errmsg
(
"inherited constraint
\"
%s
\"
must be renamed in child tables too"
,
oldconname
)));
}
if
(
con
->
coninhcount
>
expected_parents
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_TABLE_DEFINITION
),
errmsg
(
"cannot rename inherited constraint
\"
%s
\"
"
,
oldconname
)));
}
if
(
con
->
conindid
&&
(
con
->
contype
==
CONSTRAINT_PRIMARY
||
con
->
contype
==
CONSTRAINT_UNIQUE
||
con
->
contype
==
CONSTRAINT_EXCLUSION
))
/* rename the index; this renames the constraint as well */
RenameRelationInternal
(
con
->
conindid
,
newconname
);
else
RenameConstraintById
(
constraintOid
,
newconname
);
ReleaseSysCache
(
tuple
);
relation_close
(
targetrelation
,
NoLock
);
/* close rel but keep lock */
}
void
RenameConstraint
(
RenameStmt
*
stmt
)
{
Oid
relid
;
/* lock level taken here should match rename_constraint_internal */
relid
=
RangeVarGetRelidExtended
(
stmt
->
relation
,
AccessExclusiveLock
,
false
,
false
,
RangeVarCallbackForRenameAttribute
,
NULL
);
rename_constraint_internal
(
relid
,
stmt
->
subname
,
stmt
->
newname
,
interpretInhOption
(
stmt
->
relation
->
inhOpt
),
/* recursive? */
false
,
/* recursing? */
0
/* expected inhcount */
);
}
/*
* Execute ALTER TABLE/INDEX/SEQUENCE/VIEW/FOREIGN TABLE RENAME
*/
...
...
src/backend/parser/gram.y
View file @
39d74e34
...
...
@@ -6731,6 +6731,16 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
n->missing_ok = true;
$$ = (Node *)n;
}
| ALTER TABLE relation_expr RENAME CONSTRAINT name TO name
{
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_CONSTRAINT;
n->relationType = OBJECT_TABLE;
n->relation = $3;
n->subname = $6;
n->newname = $8;
$$ = (Node *)n;
}
| ALTER FOREIGN TABLE relation_expr RENAME opt_column name TO name
{
RenameStmt *n = makeNode(RenameStmt);
...
...
src/include/commands/tablecmds.h
View file @
39d74e34
...
...
@@ -48,6 +48,8 @@ extern void SetRelationHasSubclass(Oid relationId, bool relhassubclass);
extern
void
renameatt
(
RenameStmt
*
stmt
);
extern
void
RenameConstraint
(
RenameStmt
*
stmt
);
extern
void
RenameRelation
(
RenameStmt
*
stmt
);
extern
void
RenameRelationInternal
(
Oid
myrelid
,
...
...
src/test/regress/expected/alter_table.out
View file @
39d74e34
...
...
@@ -160,6 +160,141 @@ DROP VIEW tmp_view_new;
-- toast-like relation name
alter table stud_emp rename to pg_toast_stud_emp;
alter table pg_toast_stud_emp rename to stud_emp;
-- renaming index should rename constraint as well
ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1);
NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "onek_unique1_constraint" for table "onek"
ALTER INDEX onek_unique1_constraint RENAME TO onek_unique1_constraint_foo;
ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo;
-- renaming constraint
ALTER TABLE onek ADD CONSTRAINT onek_check_constraint CHECK (unique1 >= 0);
ALTER TABLE onek RENAME CONSTRAINT onek_check_constraint TO onek_check_constraint_foo;
ALTER TABLE onek DROP CONSTRAINT onek_check_constraint_foo;
-- renaming constraint should rename index as well
ALTER TABLE onek ADD CONSTRAINT onek_unique1_constraint UNIQUE (unique1);
NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "onek_unique1_constraint" for table "onek"
DROP INDEX onek_unique1_constraint; -- to see whether it's there
ERROR: cannot drop index onek_unique1_constraint because constraint onek_unique1_constraint on table onek requires it
HINT: You can drop constraint onek_unique1_constraint on table onek instead.
ALTER TABLE onek RENAME CONSTRAINT onek_unique1_constraint TO onek_unique1_constraint_foo;
DROP INDEX onek_unique1_constraint_foo; -- to see whether it's there
ERROR: cannot drop index onek_unique1_constraint_foo because constraint onek_unique1_constraint_foo on table onek requires it
HINT: You can drop constraint onek_unique1_constraint_foo on table onek instead.
ALTER TABLE onek DROP CONSTRAINT onek_unique1_constraint_foo;
-- renaming constraints vs. inheritance
CREATE TABLE constraint_rename_test (a int CONSTRAINT con1 CHECK (a > 0), b int, c int);
\d constraint_rename_test
Table "public.constraint_rename_test"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | integer |
c | integer |
Check constraints:
"con1" CHECK (a > 0)
CREATE TABLE constraint_rename_test2 (a int CONSTRAINT con1 CHECK (a > 0), d int) INHERITS (constraint_rename_test);
NOTICE: merging column "a" with inherited definition
NOTICE: merging constraint "con1" with inherited definition
\d constraint_rename_test2
Table "public.constraint_rename_test2"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | integer |
c | integer |
d | integer |
Check constraints:
"con1" CHECK (a > 0)
Inherits: constraint_rename_test
ALTER TABLE constraint_rename_test2 RENAME CONSTRAINT con1 TO con1foo; -- fail
ERROR: cannot rename inherited constraint "con1"
ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con1 TO con1foo; -- fail
ERROR: inherited constraint "con1" must be renamed in child tables too
ALTER TABLE constraint_rename_test RENAME CONSTRAINT con1 TO con1foo; -- ok
\d constraint_rename_test
Table "public.constraint_rename_test"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | integer |
c | integer |
Check constraints:
"con1foo" CHECK (a > 0)
Number of child tables: 1 (Use \d+ to list them.)
\d constraint_rename_test2
Table "public.constraint_rename_test2"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | integer |
c | integer |
d | integer |
Check constraints:
"con1foo" CHECK (a > 0)
Inherits: constraint_rename_test
ALTER TABLE ONLY constraint_rename_test ADD CONSTRAINT con2 CHECK (b > 0);
ALTER TABLE ONLY constraint_rename_test RENAME CONSTRAINT con2 TO con2foo; -- ok
ALTER TABLE constraint_rename_test RENAME CONSTRAINT con2foo TO con2bar; -- ok
\d constraint_rename_test
Table "public.constraint_rename_test"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | integer |
c | integer |
Check constraints:
"con2bar" (ONLY) CHECK (b > 0)
"con1foo" CHECK (a > 0)
Number of child tables: 1 (Use \d+ to list them.)
\d constraint_rename_test2
Table "public.constraint_rename_test2"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | integer |
c | integer |
d | integer |
Check constraints:
"con1foo" CHECK (a > 0)
Inherits: constraint_rename_test
ALTER TABLE constraint_rename_test ADD CONSTRAINT con3 PRIMARY KEY (a);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "con3" for table "constraint_rename_test"
ALTER TABLE constraint_rename_test RENAME CONSTRAINT con3 TO con3foo; -- ok
\d constraint_rename_test
Table "public.constraint_rename_test"
Column | Type | Modifiers
--------+---------+-----------
a | integer | not null
b | integer |
c | integer |
Indexes:
"con3foo" PRIMARY KEY, btree (a)
Check constraints:
"con2bar" (ONLY) CHECK (b > 0)
"con1foo" CHECK (a > 0)
Number of child tables: 1 (Use \d+ to list them.)
\d constraint_rename_test2
Table "public.constraint_rename_test2"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | integer |
c | integer |
d | integer |
Check constraints:
"con1foo" CHECK (a > 0)
Inherits: constraint_rename_test
DROP TABLE constraint_rename_test2;
DROP TABLE constraint_rename_test;
ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a);
NOTICE: relation "constraint_rename_test" does not exist, skipping
-- FOREIGN KEY CONSTRAINT adding TEST
CREATE TABLE tmp2 (a int primary key);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "tmp2_pkey" for table "tmp2"
...
...
src/test/regress/sql/alter_table.sql
View file @
39d74e34
...
...
@@ -191,6 +191,46 @@ DROP VIEW tmp_view_new;
alter
table
stud_emp
rename
to
pg_toast_stud_emp
;
alter
table
pg_toast_stud_emp
rename
to
stud_emp
;
-- renaming index should rename constraint as well
ALTER
TABLE
onek
ADD
CONSTRAINT
onek_unique1_constraint
UNIQUE
(
unique1
);
ALTER
INDEX
onek_unique1_constraint
RENAME
TO
onek_unique1_constraint_foo
;
ALTER
TABLE
onek
DROP
CONSTRAINT
onek_unique1_constraint_foo
;
-- renaming constraint
ALTER
TABLE
onek
ADD
CONSTRAINT
onek_check_constraint
CHECK
(
unique1
>=
0
);
ALTER
TABLE
onek
RENAME
CONSTRAINT
onek_check_constraint
TO
onek_check_constraint_foo
;
ALTER
TABLE
onek
DROP
CONSTRAINT
onek_check_constraint_foo
;
-- renaming constraint should rename index as well
ALTER
TABLE
onek
ADD
CONSTRAINT
onek_unique1_constraint
UNIQUE
(
unique1
);
DROP
INDEX
onek_unique1_constraint
;
-- to see whether it's there
ALTER
TABLE
onek
RENAME
CONSTRAINT
onek_unique1_constraint
TO
onek_unique1_constraint_foo
;
DROP
INDEX
onek_unique1_constraint_foo
;
-- to see whether it's there
ALTER
TABLE
onek
DROP
CONSTRAINT
onek_unique1_constraint_foo
;
-- renaming constraints vs. inheritance
CREATE
TABLE
constraint_rename_test
(
a
int
CONSTRAINT
con1
CHECK
(
a
>
0
),
b
int
,
c
int
);
\
d
constraint_rename_test
CREATE
TABLE
constraint_rename_test2
(
a
int
CONSTRAINT
con1
CHECK
(
a
>
0
),
d
int
)
INHERITS
(
constraint_rename_test
);
\
d
constraint_rename_test2
ALTER
TABLE
constraint_rename_test2
RENAME
CONSTRAINT
con1
TO
con1foo
;
-- fail
ALTER
TABLE
ONLY
constraint_rename_test
RENAME
CONSTRAINT
con1
TO
con1foo
;
-- fail
ALTER
TABLE
constraint_rename_test
RENAME
CONSTRAINT
con1
TO
con1foo
;
-- ok
\
d
constraint_rename_test
\
d
constraint_rename_test2
ALTER
TABLE
ONLY
constraint_rename_test
ADD
CONSTRAINT
con2
CHECK
(
b
>
0
);
ALTER
TABLE
ONLY
constraint_rename_test
RENAME
CONSTRAINT
con2
TO
con2foo
;
-- ok
ALTER
TABLE
constraint_rename_test
RENAME
CONSTRAINT
con2foo
TO
con2bar
;
-- ok
\
d
constraint_rename_test
\
d
constraint_rename_test2
ALTER
TABLE
constraint_rename_test
ADD
CONSTRAINT
con3
PRIMARY
KEY
(
a
);
ALTER
TABLE
constraint_rename_test
RENAME
CONSTRAINT
con3
TO
con3foo
;
-- ok
\
d
constraint_rename_test
\
d
constraint_rename_test2
DROP
TABLE
constraint_rename_test2
;
DROP
TABLE
constraint_rename_test
;
ALTER
TABLE
IF
EXISTS
constraint_rename_test
ADD
CONSTRAINT
con4
UNIQUE
(
a
);
-- FOREIGN KEY CONSTRAINT adding TEST
CREATE
TABLE
tmp2
(
a
int
primary
key
);
...
...
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