mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
Included all yacc and lex files into the distribution.
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.62 1999/12/20 10:40:41 wieck Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.63 2000/01/16 20:04:55 petere Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The PortalExecutorHeapMemory crap needs to be eliminated
|
||||
@ -23,13 +23,16 @@
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/heapam.h"
|
||||
#include "access/skey.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/catname.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_attrdef.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/command.h"
|
||||
#include "executor/execdefs.h"
|
||||
#include "executor/executor.h"
|
||||
#include "catalog/heap.h"
|
||||
#include "miscadmin.h"
|
||||
#include "optimizer/prep.h"
|
||||
#include "utils/acl.h"
|
||||
@ -37,6 +40,7 @@
|
||||
#include "utils/syscache.h"
|
||||
#include "utils/temprel.h"
|
||||
|
||||
|
||||
/* ----------------
|
||||
* PortalExecutorHeapMemory stuff
|
||||
*
|
||||
@ -246,7 +250,8 @@ PerformPortalClose(char *name, CommandDest dest)
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* PerformAddAttribute
|
||||
* AlterTableAddColumn
|
||||
* (formerly known as PerformAddAttribute)
|
||||
*
|
||||
* adds an additional attribute to a relation
|
||||
*
|
||||
@ -276,8 +281,7 @@ PerformPortalClose(char *name, CommandDest dest)
|
||||
* ----------------
|
||||
*/
|
||||
void
|
||||
PerformAddAttribute(char *relationName,
|
||||
char *userName,
|
||||
AlterTableAddColumn(const char *relationName,
|
||||
bool inherits,
|
||||
ColumnDef *colDef)
|
||||
{
|
||||
@ -295,6 +299,7 @@ PerformAddAttribute(char *relationName,
|
||||
Relation idescs[Num_pg_attr_indices];
|
||||
Relation ridescs[Num_pg_class_indices];
|
||||
bool hasindex;
|
||||
List *rawDefaults = NIL;
|
||||
|
||||
/*
|
||||
* permissions checking. this would normally be done in utility.c,
|
||||
@ -303,19 +308,18 @@ PerformAddAttribute(char *relationName,
|
||||
* normally, only the owner of a class can change its schema.
|
||||
*/
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "PerformAddAttribute: class \"%s\" is a system catalog",
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
#ifndef NO_SECURITY
|
||||
if (!pg_ownercheck(userName, relationName, RELNAME))
|
||||
elog(ERROR, "PerformAddAttribute: you do not own class \"%s\"",
|
||||
relationName);
|
||||
if (!pg_ownercheck(UserName, relationName, RELNAME))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT release
|
||||
* until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
rel = heap_openr((char *)relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||
|
||||
@ -324,8 +328,10 @@ PerformAddAttribute(char *relationName,
|
||||
*/
|
||||
if (colDef->is_not_null)
|
||||
elog(ERROR, "Can't add a NOT NULL attribute to an existing relation");
|
||||
|
||||
if (colDef->raw_default || colDef->cooked_default)
|
||||
elog(ERROR, "ADD ATTRIBUTE: DEFAULT not yet implemented");
|
||||
elog(ERROR, "Adding columns with defaults is not implemented.");
|
||||
|
||||
|
||||
/*
|
||||
* if the first element in the 'schema' list is a "*" then we are
|
||||
@ -358,8 +364,8 @@ PerformAddAttribute(char *relationName,
|
||||
if (childrelid == myrelid)
|
||||
continue;
|
||||
rel = heap_open(childrelid, AccessExclusiveLock);
|
||||
PerformAddAttribute(RelationGetRelationName(rel),
|
||||
userName, false, colDef);
|
||||
AlterTableAddColumn(RelationGetRelationName(rel),
|
||||
false, colDef);
|
||||
heap_close(rel, AccessExclusiveLock);
|
||||
}
|
||||
}
|
||||
@ -372,7 +378,7 @@ PerformAddAttribute(char *relationName,
|
||||
0, 0, 0);
|
||||
|
||||
if (!HeapTupleIsValid(reltup))
|
||||
elog(ERROR, "PerformAddAttribute: relation \"%s\" not found",
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
|
||||
relationName);
|
||||
|
||||
/*
|
||||
@ -380,14 +386,14 @@ PerformAddAttribute(char *relationName,
|
||||
*/
|
||||
if (((Form_pg_class) GETSTRUCT(reltup))->relkind == RELKIND_INDEX)
|
||||
{
|
||||
elog(ERROR, "PerformAddAttribute: index relation \"%s\" not changed",
|
||||
elog(ERROR, "ALTER TABLE: index relation \"%s\" not changed",
|
||||
relationName);
|
||||
}
|
||||
|
||||
minattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts;
|
||||
maxatts = minattnum + 1;
|
||||
if (maxatts > MaxHeapAttributeNumber)
|
||||
elog(ERROR, "PerformAddAttribute: relations limited to %d attributes",
|
||||
elog(ERROR, "ALTER TABLE: relations limited to %d columns",
|
||||
MaxHeapAttributeNumber);
|
||||
|
||||
attrdesc = heap_openr(AttributeRelationName, RowExclusiveLock);
|
||||
@ -421,7 +427,7 @@ PerformAddAttribute(char *relationName,
|
||||
0, 0);
|
||||
|
||||
if (HeapTupleIsValid(tup))
|
||||
elog(ERROR, "PerformAddAttribute: attribute \"%s\" already exists in class \"%s\"",
|
||||
elog(ERROR, "ALTER TABLE: column name \"%s\" already exists in relation \"%s\"",
|
||||
colDef->colname, relationName);
|
||||
|
||||
/*
|
||||
@ -444,7 +450,7 @@ PerformAddAttribute(char *relationName,
|
||||
tform = (Form_pg_type) GETSTRUCT(typeTuple);
|
||||
|
||||
if (!HeapTupleIsValid(typeTuple))
|
||||
elog(ERROR, "Add: type \"%s\" nonexistent", typename);
|
||||
elog(ERROR, "ALTER TABLE: type \"%s\" does not exist", typename);
|
||||
namestrcpy(&(attribute->attname), colDef->colname);
|
||||
attribute->atttypid = typeTuple->t_data->t_oid;
|
||||
attribute->attlen = tform->typlen;
|
||||
@ -483,9 +489,223 @@ PerformAddAttribute(char *relationName,
|
||||
CatalogCloseIndices(Num_pg_class_indices, ridescs);
|
||||
|
||||
heap_freetuple(reltup);
|
||||
heap_close(rel, RowExclusiveLock);
|
||||
|
||||
heap_close(rel, NoLock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void drop_default(Oid relid, int16 attnum);
|
||||
|
||||
|
||||
/*
|
||||
* ALTER TABLE ALTER COLUMN SET/DROP DEFAULT
|
||||
*/
|
||||
void
|
||||
AlterTableAlterColumn(const char *relationName,
|
||||
bool inh, const char *colName,
|
||||
Node *newDefault)
|
||||
{
|
||||
Relation rel;
|
||||
HeapTuple tuple;
|
||||
int16 attnum;
|
||||
Oid myrelid;
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
relationName);
|
||||
#ifndef NO_SECURITY
|
||||
if (!pg_ownercheck(UserName, relationName, RELNAME))
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
#endif
|
||||
|
||||
/* XXX should heap_openr take const char * ? */
|
||||
rel = heap_openr((char *)relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
heap_close(rel, NoLock);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
rel = heap_open(childrelid, AccessExclusiveLock);
|
||||
AlterTableAlterColumn(RelationGetRelationName(rel),
|
||||
false, colName, newDefault);
|
||||
heap_close(rel, AccessExclusiveLock);
|
||||
}
|
||||
}
|
||||
|
||||
/* -= now do the thing on this relation =- */
|
||||
|
||||
/* reopen the business */
|
||||
rel = heap_openr((char *)relationName, AccessExclusiveLock);
|
||||
|
||||
/*
|
||||
* get the number of the attribute
|
||||
*/
|
||||
tuple = SearchSysCacheTuple(ATTNAME,
|
||||
ObjectIdGetDatum(myrelid),
|
||||
NameGetDatum(namein((char *)colName)),
|
||||
0, 0);
|
||||
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
{
|
||||
heap_close(rel, AccessExclusiveLock);
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
|
||||
relationName, colName);
|
||||
}
|
||||
|
||||
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
|
||||
|
||||
if (newDefault) /* SET DEFAULT */
|
||||
{
|
||||
List* rawDefaults = NIL;
|
||||
RawColumnDefault *rawEnt;
|
||||
|
||||
/* Get rid of the old one first */
|
||||
drop_default(myrelid, attnum);
|
||||
|
||||
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
|
||||
rawEnt->attnum = attnum;
|
||||
rawEnt->raw_default = newDefault;
|
||||
rawDefaults = lappend(rawDefaults, rawEnt);
|
||||
|
||||
/*
|
||||
* This function is intended for CREATE TABLE,
|
||||
* so it processes a _list_ of defaults, but we just do one.
|
||||
*/
|
||||
AddRelationRawConstraints(rel, rawDefaults, NIL);
|
||||
}
|
||||
|
||||
else /* DROP DEFAULT */
|
||||
{
|
||||
Relation attr_rel;
|
||||
ScanKeyData scankeys[3];
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
|
||||
attr_rel = heap_openr(AttributeRelationName, AccessExclusiveLock);
|
||||
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,
|
||||
TRUE);
|
||||
|
||||
scan = heap_beginscan(attr_rel, false, SnapshotNow, 3, scankeys);
|
||||
AssertState(scan!=NULL);
|
||||
|
||||
if (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
{
|
||||
HeapTuple newtuple;
|
||||
Relation irelations[Num_pg_attr_indices];
|
||||
|
||||
/* update to false */
|
||||
newtuple = heap_copytuple(tuple);
|
||||
((Form_pg_attribute) GETSTRUCT(newtuple))->atthasdef = FALSE;
|
||||
heap_update(attr_rel, &tuple->t_self, newtuple, NULL);
|
||||
|
||||
/* 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_class_indices, irelations);
|
||||
|
||||
/* get rid of actual default definition */
|
||||
drop_default(myrelid, attnum);
|
||||
}
|
||||
else
|
||||
elog(NOTICE, "ALTER TABLE: there was no default on column \"%s\" of relation \"%s\"",
|
||||
colName, relationName);
|
||||
heap_endscan(scan);
|
||||
heap_close(attr_rel, NoLock);
|
||||
}
|
||||
|
||||
heap_close(rel, NoLock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
drop_default(Oid relid, int16 attnum)
|
||||
{
|
||||
ScanKeyData scankeys[2];
|
||||
HeapScanDesc scan;
|
||||
Relation attrdef_rel;
|
||||
HeapTuple tuple;
|
||||
|
||||
attrdef_rel = heap_openr(AttrDefaultRelationName, AccessExclusiveLock);
|
||||
ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid, F_OIDEQ,
|
||||
ObjectIdGetDatum(relid));
|
||||
ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum, F_INT2EQ,
|
||||
Int16GetDatum(attnum));
|
||||
|
||||
scan = heap_beginscan(attrdef_rel, false, SnapshotNow, 2, scankeys);
|
||||
AssertState(scan!=NULL);
|
||||
|
||||
if (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
heap_delete(attrdef_rel, &tuple->t_self, NULL);
|
||||
|
||||
heap_endscan(scan);
|
||||
|
||||
heap_close(attrdef_rel, NoLock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ALTER TABLE DROP COLUMN
|
||||
*/
|
||||
void
|
||||
AlterTableDropColumn(const char *relationName,
|
||||
bool inh, const char *colName,
|
||||
int behavior)
|
||||
{
|
||||
elog(NOTICE, "ALTER TABLE / DROP COLUMN is not implemented");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
AlterTableAddConstraint(const char *relationName,
|
||||
bool inh, Node *newConstraint)
|
||||
{
|
||||
elog(NOTICE, "ALTER TABLE / ADD CONSTRAINT is not implemented");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AlterTableDropConstraint(const char *relationName,
|
||||
bool inh, const char *constrName,
|
||||
int behavior)
|
||||
{
|
||||
elog(NOTICE, "ALTER TABLE / DROP CONSTRAINT is not implemented");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* LOCK TABLE
|
||||
*
|
||||
*/
|
||||
void
|
||||
LockTableCommand(LockStmt *lockstmt)
|
||||
{
|
||||
|
Reference in New Issue
Block a user