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
9b77f619
Commit
9b77f619
authored
Apr 01, 2002
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ALTER TABLE SET/DROP NOT NULL, from Christopher Kings-Lynne.
parent
838fe25a
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
506 additions
and
45 deletions
+506
-45
doc/src/sgml/ref/alter_table.sgml
doc/src/sgml/ref/alter_table.sgml
+17
-1
doc/src/sgml/release.sgml
doc/src/sgml/release.sgml
+2
-1
src/backend/commands/command.c
src/backend/commands/command.c
+315
-39
src/backend/parser/gram.y
src/backend/parser/gram.y
+19
-1
src/backend/tcop/utility.c
src/backend/tcop/utility.c
+11
-1
src/include/commands/command.h
src/include/commands/command.h
+7
-1
src/include/nodes/parsenodes.h
src/include/nodes/parsenodes.h
+3
-1
src/test/regress/expected/alter_table.out
src/test/regress/expected/alter_table.out
+71
-0
src/test/regress/sql/alter_table.sql
src/test/regress/sql/alter_table.sql
+61
-0
No files found.
doc/src/sgml/ref/alter_table.sgml
View file @
9b77f619
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.4
0 2002/03/06 20:42:38 momjian
Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.4
1 2002/04/01 04:35:37 tgl
Exp $
PostgreSQL documentation
-->
...
...
@@ -28,6 +28,8 @@ ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET DEFAULT <replaceable
class="PARAMETER">value</replaceable> | DROP DEFAULT }
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> { SET | DROP } NOT NULL
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
ALTER [ COLUMN ] <replaceable class="PARAMETER">column</replaceable> SET STATISTICS <replaceable class="PARAMETER">integer</replaceable>
ALTER TABLE [ ONLY ] <replaceable class="PARAMETER">table</replaceable> [ * ]
...
...
@@ -168,6 +170,9 @@ ALTER TABLE <replaceable class="PARAMETER">table</replaceable>
allow you to set or remove the default for the column. Note that defaults
only apply to subsequent <command>INSERT</command> commands; they do not
cause rows already in the table to change.
The <literal>ALTER COLUMN SET/DROP NOT NULL</literal> forms allow you to
change whether a column is marked to allow NULL values or to reject NULL
values.
The <literal>ALTER COLUMN SET STATISTICS</literal> form allows you to
set the statistics-gathering target for subsequent
<xref linkend="sql-analyze" endterm="sql-analyze-title"> operations.
...
...
@@ -279,6 +284,17 @@ ALTER TABLE distributors RENAME TO suppliers;
</programlisting>
</para>
<para>
To add a NOT NULL constraint to a column:
<programlisting>
ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
</programlisting>
To remove a NOT NULL constraint from a column:
<programlisting>
ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;
</programlisting>
</para>
<para>
To add a check constraint to a table:
<programlisting>
...
...
doc/src/sgml/release.sgml
View file @
9b77f619
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.12
8 2002/03/25 21:24:08 momjian
Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.12
9 2002/04/01 04:35:37 tgl
Exp $
-->
<appendix id="release">
...
...
@@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters.
-->
<literallayout><![CDATA[
ALTER TABLE ALTER COLUMN SET/DROP NOT NULL
EXPLAIN output comes out as a query result, not a NOTICE message
DOMAINs (types that are constrained versions of base types)
Access privileges on functions
...
...
src/backend/commands/command.c
View file @
9b77f619
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.1
69 2002/03/31 06:26:30
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.1
70 2002/04/01 04:35:38
tgl Exp $
*
* NOTES
* The PerformAddAttribute() code, like most of the relation
...
...
@@ -403,7 +403,7 @@ AlterTableAddColumn(Oid myrelid,
if
(
colDef
->
is_not_null
)
elog
(
ERROR
,
"Adding NOT NULL columns is not implemented."
"
\n\t
Add the column, then use ALTER TABLE
ADD CONSTRAINT
."
);
"
\n\t
Add the column, then use ALTER TABLE
... SET NOT NULL
."
);
pgclass
=
heap_openr
(
RelationRelationName
,
RowExclusiveLock
);
...
...
@@ -527,6 +527,288 @@ AlterTableAddColumn(Oid myrelid,
AlterTableCreateToastTable
(
myrelid
,
true
);
}
/*
* ALTER TABLE ALTER COLUMN DROP NOT NULL
*/
void
AlterTableAlterColumnDropNotNull
(
Oid
myrelid
,
bool
inh
,
const
char
*
colName
)
{
Relation
rel
;
HeapTuple
tuple
;
AttrNumber
attnum
;
Relation
attr_rel
;
List
*
indexoidlist
;
List
*
indexoidscan
;
rel
=
heap_open
(
myrelid
,
AccessExclusiveLock
);
if
(
rel
->
rd_rel
->
relkind
!=
RELKIND_RELATION
)
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
is not a table"
,
RelationGetRelationName
(
rel
));
if
(
!
allowSystemTableMods
&&
IsSystemRelationName
(
RelationGetRelationName
(
rel
)))
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
is a system catalog"
,
RelationGetRelationName
(
rel
));
if
(
!
pg_class_ownercheck
(
myrelid
,
GetUserId
()))
elog
(
ERROR
,
"ALTER TABLE:
\"
%s
\"
: permission denied"
,
RelationGetRelationName
(
rel
));
/*
* Propagate to children if desired
*/
if
(
inh
)
{
List
*
child
,
*
children
;
/* this routine is actually in the planner */
children
=
find_all_inheritors
(
myrelid
);
/*
* find_all_inheritors does the recursive search of the
* inheritance hierarchy, so all we have to do is process all of
* the relids in the list that it returns.
*/
foreach
(
child
,
children
)
{
Oid
childrelid
=
lfirsti
(
child
);
if
(
childrelid
==
myrelid
)
continue
;
AlterTableAlterColumnDropNotNull
(
childrelid
,
false
,
colName
);
}
}
/* -= now do the thing on this relation =- */
/*
* get the number of the attribute
*/
tuple
=
SearchSysCache
(
ATTNAME
,
ObjectIdGetDatum
(
myrelid
),
PointerGetDatum
(
colName
),
0
,
0
);
if
(
!
HeapTupleIsValid
(
tuple
))
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
has no column
\"
%s
\"
"
,
RelationGetRelationName
(
rel
),
colName
);
attnum
=
((
Form_pg_attribute
)
GETSTRUCT
(
tuple
))
->
attnum
;
ReleaseSysCache
(
tuple
);
/* Prevent them from altering a system attribute */
if
(
attnum
<
0
)
elog
(
ERROR
,
"ALTER TABLE: Cannot alter system attribute
\"
%s
\"
"
,
colName
);
/*
* Check that the attribute is not in a primary key
*/
/* Loop over all indices on the relation */
indexoidlist
=
RelationGetIndexList
(
rel
);
foreach
(
indexoidscan
,
indexoidlist
)
{
Oid
indexoid
=
lfirsti
(
indexoidscan
);
HeapTuple
indexTuple
;
Form_pg_index
indexStruct
;
int
i
;
indexTuple
=
SearchSysCache
(
INDEXRELID
,
ObjectIdGetDatum
(
indexoid
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
indexTuple
))
elog
(
ERROR
,
"ALTER TABLE: Index %u not found"
,
indexoid
);
indexStruct
=
(
Form_pg_index
)
GETSTRUCT
(
indexTuple
);
/* If the index is not a primary key, skip the check */
if
(
indexStruct
->
indisprimary
)
{
/*
* Loop over each attribute in the primary key and
* see if it matches the to-be-altered attribute
*/
for
(
i
=
0
;
i
<
INDEX_MAX_KEYS
&&
indexStruct
->
indkey
[
i
]
!=
InvalidAttrNumber
;
i
++
)
{
if
(
indexStruct
->
indkey
[
i
]
==
attnum
)
elog
(
ERROR
,
"ALTER TABLE: Attribute
\"
%s
\"
is in a primary key"
,
colName
);
}
}
ReleaseSysCache
(
indexTuple
);
}
freeList
(
indexoidlist
);
/*
* Okay, actually perform the catalog change
*/
attr_rel
=
heap_openr
(
AttributeRelationName
,
RowExclusiveLock
);
tuple
=
SearchSysCacheCopy
(
ATTNAME
,
ObjectIdGetDatum
(
myrelid
),
PointerGetDatum
(
colName
),
0
,
0
);
if
(
!
HeapTupleIsValid
(
tuple
))
/* shouldn't happen */
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
has no column
\"
%s
\"
"
,
RelationGetRelationName
(
rel
),
colName
);
((
Form_pg_attribute
)
GETSTRUCT
(
tuple
))
->
attnotnull
=
FALSE
;
simple_heap_update
(
attr_rel
,
&
tuple
->
t_self
,
tuple
);
/* keep the system catalog indices current */
if
(
RelationGetForm
(
attr_rel
)
->
relhasindex
)
{
Relation
idescs
[
Num_pg_attr_indices
];
CatalogOpenIndices
(
Num_pg_attr_indices
,
Name_pg_attr_indices
,
idescs
);
CatalogIndexInsert
(
idescs
,
Num_pg_attr_indices
,
attr_rel
,
tuple
);
CatalogCloseIndices
(
Num_pg_attr_indices
,
idescs
);
}
heap_close
(
attr_rel
,
RowExclusiveLock
);
heap_close
(
rel
,
NoLock
);
}
/*
* ALTER TABLE ALTER COLUMN SET NOT NULL
*/
void
AlterTableAlterColumnSetNotNull
(
Oid
myrelid
,
bool
inh
,
const
char
*
colName
)
{
Relation
rel
;
HeapTuple
tuple
;
AttrNumber
attnum
;
Relation
attr_rel
;
HeapScanDesc
scan
;
TupleDesc
tupdesc
;
rel
=
heap_open
(
myrelid
,
AccessExclusiveLock
);
if
(
rel
->
rd_rel
->
relkind
!=
RELKIND_RELATION
)
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
is not a table"
,
RelationGetRelationName
(
rel
));
if
(
!
allowSystemTableMods
&&
IsSystemRelationName
(
RelationGetRelationName
(
rel
)))
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
is a system catalog"
,
RelationGetRelationName
(
rel
));
if
(
!
pg_class_ownercheck
(
myrelid
,
GetUserId
()))
elog
(
ERROR
,
"ALTER TABLE:
\"
%s
\"
: permission denied"
,
RelationGetRelationName
(
rel
));
/*
* Propagate to children if desired
*/
if
(
inh
)
{
List
*
child
,
*
children
;
/* this routine is actually in the planner */
children
=
find_all_inheritors
(
myrelid
);
/*
* find_all_inheritors does the recursive search of the
* inheritance hierarchy, so all we have to do is process all of
* the relids in the list that it returns.
*/
foreach
(
child
,
children
)
{
Oid
childrelid
=
lfirsti
(
child
);
if
(
childrelid
==
myrelid
)
continue
;
AlterTableAlterColumnSetNotNull
(
childrelid
,
false
,
colName
);
}
}
/* -= now do the thing on this relation =- */
/*
* get the number of the attribute
*/
tuple
=
SearchSysCache
(
ATTNAME
,
ObjectIdGetDatum
(
myrelid
),
PointerGetDatum
(
colName
),
0
,
0
);
if
(
!
HeapTupleIsValid
(
tuple
))
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
has no column
\"
%s
\"
"
,
RelationGetRelationName
(
rel
),
colName
);
attnum
=
((
Form_pg_attribute
)
GETSTRUCT
(
tuple
))
->
attnum
;
ReleaseSysCache
(
tuple
);
/* Prevent them from altering a system attribute */
if
(
attnum
<
0
)
elog
(
ERROR
,
"ALTER TABLE: Cannot alter system attribute
\"
%s
\"
"
,
colName
);
/*
* Perform a scan to ensure that there are no NULL
* values already in the relation
*/
tupdesc
=
RelationGetDescr
(
rel
);
scan
=
heap_beginscan
(
rel
,
false
,
SnapshotNow
,
0
,
NULL
);
while
(
HeapTupleIsValid
(
tuple
=
heap_getnext
(
scan
,
0
)))
{
Datum
d
;
bool
isnull
;
d
=
heap_getattr
(
tuple
,
attnum
,
tupdesc
,
&
isnull
);
if
(
isnull
)
elog
(
ERROR
,
"ALTER TABLE: Attribute
\"
%s
\"
contains NULL values"
,
colName
);
}
heap_endscan
(
scan
);
/*
* Okay, actually perform the catalog change
*/
attr_rel
=
heap_openr
(
AttributeRelationName
,
RowExclusiveLock
);
tuple
=
SearchSysCacheCopy
(
ATTNAME
,
ObjectIdGetDatum
(
myrelid
),
PointerGetDatum
(
colName
),
0
,
0
);
if
(
!
HeapTupleIsValid
(
tuple
))
/* shouldn't happen */
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
has no column
\"
%s
\"
"
,
RelationGetRelationName
(
rel
),
colName
);
((
Form_pg_attribute
)
GETSTRUCT
(
tuple
))
->
attnotnull
=
TRUE
;
simple_heap_update
(
attr_rel
,
&
tuple
->
t_self
,
tuple
);
/* keep the system catalog indices current */
if
(
RelationGetForm
(
attr_rel
)
->
relhasindex
)
{
Relation
idescs
[
Num_pg_attr_indices
];
CatalogOpenIndices
(
Num_pg_attr_indices
,
Name_pg_attr_indices
,
idescs
);
CatalogIndexInsert
(
idescs
,
Num_pg_attr_indices
,
attr_rel
,
tuple
);
CatalogCloseIndices
(
Num_pg_attr_indices
,
idescs
);
}
heap_close
(
attr_rel
,
RowExclusiveLock
);
heap_close
(
rel
,
NoLock
);
}
/*
* ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
...
...
@@ -538,7 +820,7 @@ AlterTableAlterColumnDefault(Oid myrelid,
{
Relation
rel
;
HeapTuple
tuple
;
int16
attnum
;
AttrNumber
attnum
;
rel
=
heap_open
(
myrelid
,
AccessExclusiveLock
);
...
...
@@ -552,7 +834,7 @@ AlterTableAlterColumnDefault(Oid myrelid,
RelationGetRelationName
(
rel
));
if
(
!
pg_class_ownercheck
(
myrelid
,
GetUserId
()))
elog
(
ERROR
,
"ALTER TABLE:
\"
%s
\"
permission denied"
,
elog
(
ERROR
,
"ALTER TABLE:
\"
%s
\"
:
permission denied"
,
RelationGetRelationName
(
rel
));
/*
...
...
@@ -620,44 +902,36 @@ AlterTableAlterColumnDefault(Oid myrelid,
{
/* DROP DEFAULT */
Relation
attr_rel
;
ScanKeyData
scankeys
[
3
];
HeapScanDesc
scan
;
/* Fix the pg_attribute row */
attr_rel
=
heap_openr
(
AttributeRelationName
,
RowExclusiveLock
);
ScanKeyEntryInitialize
(
&
scankeys
[
0
],
0x0
,
Anum_pg_attribute_attrelid
,
F_OIDEQ
,
ObjectIdGetDatum
(
myrelid
));
ScanKeyEntryInitialize
(
&
scankeys
[
1
],
0x0
,
Anum_pg_attribute_attnum
,
F_INT2EQ
,
Int16GetDatum
(
attnum
));
ScanKeyEntryInitialize
(
&
scankeys
[
2
],
0x0
,
Anum_pg_attribute_atthasdef
,
F_BOOLEQ
,
BoolGetDatum
(
true
));
scan
=
heap_beginscan
(
attr_rel
,
false
,
SnapshotNow
,
3
,
scankeys
);
AssertState
(
scan
!=
NULL
);
tuple
=
SearchSysCacheCopy
(
ATTNAME
,
ObjectIdGetDatum
(
myrelid
),
PointerGetDatum
(
colName
),
0
,
0
);
if
(
!
HeapTupleIsValid
(
tuple
))
/* shouldn't happen */
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
has no column
\"
%s
\"
"
,
RelationGetRelationName
(
rel
),
colName
);
if
(
HeapTupleIsValid
(
tuple
=
heap_getnext
(
scan
,
0
)))
{
HeapTuple
newtuple
;
Relation
irelations
[
Num_pg_attr_indices
];
((
Form_pg_attribute
)
GETSTRUCT
(
tuple
))
->
atthasdef
=
FALSE
;
/* update to false */
newtuple
=
heap_copytuple
(
tuple
);
((
Form_pg_attribute
)
GETSTRUCT
(
newtuple
))
->
atthasdef
=
FALSE
;
simple_heap_update
(
attr_rel
,
&
tuple
->
t_self
,
newtuple
);
simple_heap_update
(
attr_rel
,
&
tuple
->
t_self
,
tuple
);
/* keep the system catalog indices current */
CatalogOpenIndices
(
Num_pg_attr_indices
,
Name_pg_attr_indices
,
irelations
);
CatalogIndexInsert
(
irelations
,
Num_pg_attr_indices
,
attr_rel
,
newtuple
);
CatalogCloseIndices
(
Num_pg_attr_indices
,
irelations
)
;
if
(
RelationGetForm
(
attr_rel
)
->
relhasindex
)
{
Relation
idescs
[
Num_pg_attr_indices
]
;
/* get rid of actual default definition */
drop_default
(
myrelid
,
attnum
);
CatalogOpenIndices
(
Num_pg_attr_indices
,
Name_pg_attr_indices
,
idescs
);
CatalogIndexInsert
(
idescs
,
Num_pg_attr_indices
,
attr_rel
,
tuple
);
CatalogCloseIndices
(
Num_pg_attr_indices
,
idescs
);
}
heap_endscan
(
scan
);
heap_close
(
attr_rel
,
NoLock
);
heap_close
(
attr_rel
,
RowExclusiveLock
);
/* get rid of actual default definition in pg_attrdef */
drop_default
(
myrelid
,
attnum
);
}
heap_close
(
rel
,
NoLock
);
...
...
@@ -722,7 +996,7 @@ AlterTableAlterColumnFlags(Oid myrelid,
RelationGetRelationName
(
rel
));
if
(
!
pg_class_ownercheck
(
myrelid
,
GetUserId
()))
elog
(
ERROR
,
"ALTER TABLE:
\"
%s
\"
permission denied"
,
elog
(
ERROR
,
"ALTER TABLE:
\"
%s
\"
:
permission denied"
,
RelationGetRelationName
(
rel
));
/*
...
...
@@ -1011,7 +1285,7 @@ AlterTableDropColumn(Oid myrelid,
RelationGetRelationName
(
rel
));
if
(
!
allowSystemTableMods
&&
IsSystemRelationName
(
RelationGetRelationName
(
rel
))
&&
IsSystemRelationName
(
RelationGetRelationName
(
rel
))
)
elog
(
ERROR
,
"ALTER TABLE: relation
\"
%s
\"
is a system catalog"
,
RelationGetRelationName
(
rel
));
...
...
@@ -1022,7 +1296,8 @@ AlterTableDropColumn(Oid myrelid,
* normally, only the owner of a class can change its schema.
*/
if
(
!
pg_class_ownercheck
(
myrelid
,
GetUserId
()))
elog
(
ERROR
,
"ALTER TABLE: permission denied"
);
elog
(
ERROR
,
"ALTER TABLE:
\"
%s
\"
: permission denied"
,
RelationGetRelationName
(
rel
));
heap_close
(
rel
,
NoLock
);
/* close rel but keep lock! */
...
...
@@ -1670,7 +1945,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
RelationGetRelationName
(
rel
));
if
(
!
pg_class_ownercheck
(
relOid
,
GetUserId
()))
elog
(
ERROR
,
"ALTER TABLE: permission denied"
);
elog
(
ERROR
,
"ALTER TABLE:
\"
%s
\"
: permission denied"
,
RelationGetRelationName
(
rel
));
/*
* lock the pg_class tuple for update (is that really needed?)
...
...
src/backend/parser/gram.y
View file @
9b77f619
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.29
8 2002/04/01 03:34:25
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.29
9 2002/04/01 04:35:38
tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -1122,6 +1122,24 @@ AlterTableStmt:
n->def = $7;
$$ = (Node *)n;
}
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> DROP NOT NULL */
| ALTER TABLE relation_expr ALTER opt_column ColId DROP NOT NULL_P
{
AlterTableStmt *n = makeNode(AlterTableStmt);
n->subtype = 'N';
n->relation = $3;
n->name = $6;
$$ = (Node *)n;
}
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET NOT NULL */
| ALTER TABLE relation_expr ALTER opt_column ColId SET NOT NULL_P
{
AlterTableStmt *n = makeNode(AlterTableStmt);
n->subtype = 'O';
n->relation = $3;
n->name = $6;
$$ = (Node *)n;
}
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <Iconst> */
| ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS Iconst
{
...
...
src/backend/tcop/utility.c
View file @
9b77f619
...
...
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.14
4 2002/03/31 07:49:30
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.14
5 2002/04/01 04:35:39
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -437,6 +437,16 @@ ProcessUtility(Node *parsetree,
stmt
->
name
,
stmt
->
def
);
break
;
case
'N'
:
/* ALTER COLUMN DROP NOT NULL */
AlterTableAlterColumnDropNotNull
(
RangeVarGetRelid
(
stmt
->
relation
,
false
),
interpretInhOption
(
stmt
->
relation
->
inhOpt
),
stmt
->
name
);
break
;
case
'O'
:
/* ALTER COLUMN SET NOT NULL */
AlterTableAlterColumnSetNotNull
(
RangeVarGetRelid
(
stmt
->
relation
,
false
),
interpretInhOption
(
stmt
->
relation
->
inhOpt
),
stmt
->
name
);
break
;
case
'S'
:
/* ALTER COLUMN STATISTICS */
case
'M'
:
/* ALTER COLUMN STORAGE */
/*
...
...
src/include/commands/command.h
View file @
9b77f619
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: command.h,v 1.3
6 2002/03/29 19:06:21
tgl Exp $
* $Id: command.h,v 1.3
7 2002/04/01 04:35:39
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -45,6 +45,12 @@ extern void AlterTableAddColumn(Oid myrelid, bool inherits, ColumnDef *colDef);
extern
void
AlterTableAlterColumnDefault
(
Oid
myrelid
,
bool
inh
,
const
char
*
colName
,
Node
*
newDefault
);
extern
void
AlterTableAlterColumnDropNotNull
(
Oid
myrelid
,
bool
inh
,
const
char
*
colName
);
extern
void
AlterTableAlterColumnSetNotNull
(
Oid
myrelid
,
bool
inh
,
const
char
*
colName
);
extern
void
AlterTableAlterColumnFlags
(
Oid
myrelid
,
bool
inh
,
const
char
*
colName
,
Node
*
flagValue
,
const
char
*
flagType
);
...
...
src/include/nodes/parsenodes.h
View file @
9b77f619
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: parsenodes.h,v 1.16
6 2002/03/29 19:06:23
tgl Exp $
* $Id: parsenodes.h,v 1.16
7 2002/04/01 04:35:40
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -728,6 +728,8 @@ typedef struct AlterTableStmt
char
subtype
;
/*------------
* A = add column
* T = alter column default
* N = alter column drop not null
* O = alter column set not null
* S = alter column statistics
* M = alter column storage
* D = drop column
...
...
src/test/regress/expected/alter_table.out
View file @
9b77f619
...
...
@@ -578,3 +578,74 @@ ERROR: Cannot insert a duplicate key into unique index atacc1_pkey
insert into atacc1 (test2, test) values (1, NULL);
ERROR: ExecAppend: Fail to add null value in not null attribute test
drop table atacc1;
-- alter table / alter column [set/drop] not null tests
-- try altering system catalogs, should fail
alter table pg_class alter column relname drop not null;
ERROR: ALTER TABLE: relation "pg_class" is a system catalog
alter table pg_class alter relname set not null;
ERROR: ALTER TABLE: relation "pg_class" is a system catalog
-- try altering non-existent table, should fail
alter table foo alter column bar set not null;
ERROR: Relation "foo" does not exist
alter table foo alter column bar drop not null;
ERROR: Relation "foo" does not exist
-- test setting columns to null and not null and vice versa
-- test checking for null values and primary key
create table atacc1 (test int not null);
alter table atacc1 add constraint "atacc1_pkey" primary key (test);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index 'atacc1_pkey' for table 'atacc1'
alter table atacc1 alter column test drop not null;
ERROR: ALTER TABLE: Attribute "test" is in a primary key
drop index atacc1_pkey;
alter table atacc1 alter column test drop not null;
insert into atacc1 values (null);
alter table atacc1 alter test set not null;
ERROR: ALTER TABLE: Attribute "test" contains NULL values
delete from atacc1;
alter table atacc1 alter test set not null;
-- try altering a non-existent column, should fail
alter table atacc1 alter bar set not null;
ERROR: ALTER TABLE: relation "atacc1" has no column "bar"
alter table atacc1 alter bar drop not null;
ERROR: ALTER TABLE: relation "atacc1" has no column "bar"
-- try altering the oid column, should fail
alter table atacc1 alter oid set not null;
ERROR: ALTER TABLE: Cannot alter system attribute "oid"
alter table atacc1 alter oid drop not null;
ERROR: ALTER TABLE: Cannot alter system attribute "oid"
-- try creating a view and altering that, should fail
create view myview as select * from atacc1;
alter table myview alter column test drop not null;
ERROR: ALTER TABLE: relation "myview" is not a table
alter table myview alter column test set not null;
ERROR: ALTER TABLE: relation "myview" is not a table
drop view myview;
drop table atacc1;
-- test inheritance
create table parent (a int);
create table child (b varchar(255)) inherits (parent);
alter table parent alter a set not null;
insert into parent values (NULL);
ERROR: ExecAppend: Fail to add null value in not null attribute a
insert into child (a, b) values (NULL, 'foo');
ERROR: ExecAppend: Fail to add null value in not null attribute a
alter table parent alter a drop not null;
insert into parent values (NULL);
insert into child (a, b) values (NULL, 'foo');
alter table only parent alter a set not null;
ERROR: ALTER TABLE: Attribute "a" contains NULL values
alter table child alter a set not null;
ERROR: ALTER TABLE: Attribute "a" contains NULL values
delete from parent;
alter table only parent alter a set not null;
insert into parent values (NULL);
ERROR: ExecAppend: Fail to add null value in not null attribute a
alter table child alter a set not null;
insert into child (a, b) values (NULL, 'foo');
ERROR: ExecAppend: Fail to add null value in not null attribute a
delete from child;
alter table child alter a set not null;
insert into child (a, b) values (NULL, 'foo');
ERROR: ExecAppend: Fail to add null value in not null attribute a
drop table child;
drop table parent;
src/test/regress/sql/alter_table.sql
View file @
9b77f619
...
...
@@ -452,3 +452,64 @@ insert into atacc1 (test2, test) values (3, 3);
insert
into
atacc1
(
test2
,
test
)
values
(
2
,
3
);
insert
into
atacc1
(
test2
,
test
)
values
(
1
,
NULL
);
drop
table
atacc1
;
-- alter table / alter column [set/drop] not null tests
-- try altering system catalogs, should fail
alter
table
pg_class
alter
column
relname
drop
not
null
;
alter
table
pg_class
alter
relname
set
not
null
;
-- try altering non-existent table, should fail
alter
table
foo
alter
column
bar
set
not
null
;
alter
table
foo
alter
column
bar
drop
not
null
;
-- test setting columns to null and not null and vice versa
-- test checking for null values and primary key
create
table
atacc1
(
test
int
not
null
);
alter
table
atacc1
add
constraint
"atacc1_pkey"
primary
key
(
test
);
alter
table
atacc1
alter
column
test
drop
not
null
;
drop
index
atacc1_pkey
;
alter
table
atacc1
alter
column
test
drop
not
null
;
insert
into
atacc1
values
(
null
);
alter
table
atacc1
alter
test
set
not
null
;
delete
from
atacc1
;
alter
table
atacc1
alter
test
set
not
null
;
-- try altering a non-existent column, should fail
alter
table
atacc1
alter
bar
set
not
null
;
alter
table
atacc1
alter
bar
drop
not
null
;
-- try altering the oid column, should fail
alter
table
atacc1
alter
oid
set
not
null
;
alter
table
atacc1
alter
oid
drop
not
null
;
-- try creating a view and altering that, should fail
create
view
myview
as
select
*
from
atacc1
;
alter
table
myview
alter
column
test
drop
not
null
;
alter
table
myview
alter
column
test
set
not
null
;
drop
view
myview
;
drop
table
atacc1
;
-- test inheritance
create
table
parent
(
a
int
);
create
table
child
(
b
varchar
(
255
))
inherits
(
parent
);
alter
table
parent
alter
a
set
not
null
;
insert
into
parent
values
(
NULL
);
insert
into
child
(
a
,
b
)
values
(
NULL
,
'foo'
);
alter
table
parent
alter
a
drop
not
null
;
insert
into
parent
values
(
NULL
);
insert
into
child
(
a
,
b
)
values
(
NULL
,
'foo'
);
alter
table
only
parent
alter
a
set
not
null
;
alter
table
child
alter
a
set
not
null
;
delete
from
parent
;
alter
table
only
parent
alter
a
set
not
null
;
insert
into
parent
values
(
NULL
);
alter
table
child
alter
a
set
not
null
;
insert
into
child
(
a
,
b
)
values
(
NULL
,
'foo'
);
delete
from
child
;
alter
table
child
alter
a
set
not
null
;
insert
into
child
(
a
,
b
)
values
(
NULL
,
'foo'
);
drop
table
child
;
drop
table
parent
;
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