mirror of
https://github.com/postgres/postgres.git
synced 2025-12-22 17:42:17 +03:00
Ye-old pgindent run. Same 4-space tabs.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/recipe.c,v 1.10 2000/01/26 05:56:17 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/_deadcode/Attic/recipe.c,v 1.11 2000/04/12 17:15:06 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -702,7 +702,7 @@ getParamTypes(TgElement * elem, Oid *typev)
|
||||
if (parameterCount == FUNC_MAX_ARGS)
|
||||
{
|
||||
elog(ERROR,
|
||||
"getParamTypes: Ingredients cannot take > %d arguments",FUNC_MAX_ARGS);
|
||||
"getParamTypes: Ingredients cannot take > %d arguments", FUNC_MAX_ARGS);
|
||||
}
|
||||
t = elem->inTypes->val[j];
|
||||
if (strcmp(t, "opaque") == 0)
|
||||
@@ -810,7 +810,7 @@ tg_parseSubQuery(TgRecipe * r, TgNode * n, TeeInfo * teeInfo)
|
||||
{
|
||||
TgElement *elem;
|
||||
char *funcName;
|
||||
Oid typev[FUNC_MAX_ARGS], /* eight arguments maximum */
|
||||
Oid typev[FUNC_MAX_ARGS], /* eight arguments maximum */
|
||||
relid;
|
||||
int i,
|
||||
parameterCount;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.58 2000/01/26 05:56:12 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.59 2000/04/12 17:14:57 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -155,12 +155,13 @@ Async_Notify(char *relname)
|
||||
/* no point in making duplicate entries in the list ... */
|
||||
if (!AsyncExistsPendingNotify(relname))
|
||||
{
|
||||
|
||||
/*
|
||||
* We allocate list memory from the global malloc pool to ensure
|
||||
* that it will live until we want to use it. This is probably not
|
||||
* necessary any longer, since we will use it before the end of the
|
||||
* transaction. DLList only knows how to use malloc() anyway, but we
|
||||
* could probably palloc() the strings...
|
||||
* that it will live until we want to use it. This is probably
|
||||
* not necessary any longer, since we will use it before the end
|
||||
* of the transaction. DLList only knows how to use malloc()
|
||||
* anyway, but we could probably palloc() the strings...
|
||||
*/
|
||||
notifyName = strdup(relname);
|
||||
DLAddHead(pendingNotifies, DLNewElem(notifyName));
|
||||
@@ -466,6 +467,7 @@ AtCommit_Notify()
|
||||
|
||||
if (listenerPID == MyProcPid)
|
||||
{
|
||||
|
||||
/*
|
||||
* Self-notify: no need to bother with table update.
|
||||
* Indeed, we *must not* clear the notification field in
|
||||
@@ -491,6 +493,7 @@ AtCommit_Notify()
|
||||
*/
|
||||
if (kill(listenerPID, SIGUSR2) < 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* Get rid of pg_listener entry if it refers to a PID
|
||||
* that no longer exists. Presumably, that backend
|
||||
@@ -514,7 +517,7 @@ AtCommit_Notify()
|
||||
if (RelationGetForm(lRel)->relhasindex)
|
||||
{
|
||||
Relation idescs[Num_pg_listener_indices];
|
||||
|
||||
|
||||
CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple);
|
||||
CatalogCloseIndices(Num_pg_listener_indices, idescs);
|
||||
@@ -780,7 +783,7 @@ ProcessIncomingNotify(void)
|
||||
if (RelationGetForm(lRel)->relhasindex)
|
||||
{
|
||||
Relation idescs[Num_pg_listener_indices];
|
||||
|
||||
|
||||
CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple);
|
||||
CatalogCloseIndices(Num_pg_listener_indices, idescs);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.50 2000/01/26 05:56:13 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.51 2000/04/12 17:14:57 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -104,8 +104,8 @@ cluster(char *oldrelname, char *oldindexname)
|
||||
* Like vacuum, cluster spans transactions, so I'm going to handle it
|
||||
* in the same way: commit and restart transactions where needed.
|
||||
*
|
||||
* We grab exclusive access to the target rel and index for the
|
||||
* duration of the initial transaction.
|
||||
* We grab exclusive access to the target rel and index for the duration
|
||||
* of the initial transaction.
|
||||
*/
|
||||
|
||||
OldHeap = heap_openr(oldrelname, AccessExclusiveLock);
|
||||
@@ -115,7 +115,7 @@ cluster(char *oldrelname, char *oldindexname)
|
||||
LockRelation(OldIndex, AccessExclusiveLock);
|
||||
OIDOldIndex = RelationGetRelid(OldIndex);
|
||||
|
||||
heap_close(OldHeap, NoLock); /* do NOT give up the locks */
|
||||
heap_close(OldHeap, NoLock);/* do NOT give up the locks */
|
||||
index_close(OldIndex);
|
||||
|
||||
/*
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.70 2000/03/09 05:00:23 inoue Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.71 2000/04/12 17:14:57 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The PortalExecutorHeapMemory crap needs to be eliminated
|
||||
@@ -51,7 +51,7 @@
|
||||
#include "access/genam.h"
|
||||
#include "optimizer/clauses.h"
|
||||
#include "../parser/parse.h"
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
|
||||
/* ----------------
|
||||
* PortalExecutorHeapMemory stuff
|
||||
@@ -262,7 +262,7 @@ PerformPortalClose(char *name, CommandDest dest)
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
* AlterTableAddColumn
|
||||
* AlterTableAddColumn
|
||||
* (formerly known as PerformAddAttribute)
|
||||
*
|
||||
* adds an additional attribute to a relation
|
||||
@@ -327,8 +327,8 @@ AlterTableAddColumn(const char *relationName,
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT release
|
||||
* until end of transaction.
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
@@ -341,7 +341,7 @@ AlterTableAddColumn(const char *relationName,
|
||||
elog(ERROR, "Can't add a NOT NULL attribute to an existing relation");
|
||||
|
||||
if (colDef->raw_default || colDef->cooked_default)
|
||||
elog(ERROR, "Adding columns with defaults is not implemented.");
|
||||
elog(ERROR, "Adding columns with defaults is not implemented.");
|
||||
|
||||
|
||||
/*
|
||||
@@ -370,7 +370,7 @@ AlterTableAddColumn(const char *relationName,
|
||||
*/
|
||||
foreach(child, children)
|
||||
{
|
||||
Oid childrelid = lfirsti(child);
|
||||
Oid childrelid = lfirsti(child);
|
||||
|
||||
if (childrelid == myrelid)
|
||||
continue;
|
||||
@@ -514,13 +514,13 @@ static void drop_default(Oid relid, int16 attnum);
|
||||
*/
|
||||
void
|
||||
AlterTableAlterColumn(const char *relationName,
|
||||
bool inh, const char *colName,
|
||||
Node *newDefault)
|
||||
bool inh, const char *colName,
|
||||
Node *newDefault)
|
||||
{
|
||||
Relation rel;
|
||||
HeapTuple tuple;
|
||||
int16 attnum;
|
||||
Oid myrelid;
|
||||
Relation rel;
|
||||
HeapTuple tuple;
|
||||
int16 attnum;
|
||||
Oid myrelid;
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelationName(relationName))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||
@@ -530,121 +530,122 @@ AlterTableAlterColumn(const char *relationName,
|
||||
elog(ERROR, "ALTER TABLE: permission denied");
|
||||
#endif
|
||||
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
heap_close(rel, NoLock);
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
heap_close(rel, NoLock);
|
||||
|
||||
/*
|
||||
* Propagate to children if desired
|
||||
*/
|
||||
/*
|
||||
* Propagate to children if desired
|
||||
*/
|
||||
if (inh)
|
||||
{
|
||||
List *child,
|
||||
*children;
|
||||
{
|
||||
List *child,
|
||||
*children;
|
||||
|
||||
/* this routine is actually in the planner */
|
||||
children = find_all_inheritors(myrelid);
|
||||
/* 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)
|
||||
/*
|
||||
* 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);
|
||||
Oid childrelid = lfirsti(child);
|
||||
|
||||
if (childrelid == myrelid)
|
||||
continue;
|
||||
rel = heap_open(childrelid, AccessExclusiveLock);
|
||||
AlterTableAlterColumn(RelationGetRelationName(rel),
|
||||
false, colName, newDefault);
|
||||
heap_close(rel, AccessExclusiveLock);
|
||||
}
|
||||
}
|
||||
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 =- */
|
||||
/* -= now do the thing on this relation =- */
|
||||
|
||||
/* reopen the business */
|
||||
rel = heap_openr((char *)relationName, AccessExclusiveLock);
|
||||
/* 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);
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
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;
|
||||
attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
|
||||
|
||||
if (newDefault) /* SET DEFAULT */
|
||||
{
|
||||
List* rawDefaults = NIL;
|
||||
RawColumnDefault *rawEnt;
|
||||
if (newDefault) /* SET DEFAULT */
|
||||
{
|
||||
List *rawDefaults = NIL;
|
||||
RawColumnDefault *rawEnt;
|
||||
|
||||
/* Get rid of the old one first */
|
||||
drop_default(myrelid, attnum);
|
||||
/* Get rid of the old one first */
|
||||
drop_default(myrelid, attnum);
|
||||
|
||||
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
|
||||
rawEnt->attnum = attnum;
|
||||
rawEnt->raw_default = newDefault;
|
||||
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);
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
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);
|
||||
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);
|
||||
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];
|
||||
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);
|
||||
/* 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_attr_indices, irelations);
|
||||
/* 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);
|
||||
|
||||
/* get rid of actual default definition */
|
||||
drop_default(myrelid, attnum);
|
||||
}
|
||||
/* get rid of actual default definition */
|
||||
drop_default(myrelid, attnum);
|
||||
}
|
||||
|
||||
heap_endscan(scan);
|
||||
heap_close(attr_rel, NoLock);
|
||||
}
|
||||
heap_endscan(scan);
|
||||
heap_close(attr_rel, NoLock);
|
||||
}
|
||||
|
||||
heap_close(rel, NoLock);
|
||||
}
|
||||
@@ -654,33 +655,33 @@ AlterTableAlterColumn(const char *relationName,
|
||||
static void
|
||||
drop_default(Oid relid, int16 attnum)
|
||||
{
|
||||
ScanKeyData scankeys[2];
|
||||
HeapScanDesc scan;
|
||||
Relation attrdef_rel;
|
||||
HeapTuple tuple;
|
||||
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));
|
||||
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);
|
||||
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);
|
||||
if (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
heap_delete(attrdef_rel, &tuple->t_self, NULL);
|
||||
|
||||
heap_endscan(scan);
|
||||
heap_endscan(scan);
|
||||
|
||||
heap_close(attrdef_rel, NoLock);
|
||||
heap_close(attrdef_rel, NoLock);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _DROP_COLUMN_HACK__
|
||||
/*
|
||||
* ALTER TABLE DROP COLUMN trial implementation
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -690,17 +691,17 @@ typedef struct SysScanDescData
|
||||
{
|
||||
Relation heap_rel;
|
||||
Relation irel;
|
||||
HeapScanDesc scan;
|
||||
IndexScanDesc iscan;
|
||||
HeapTupleData tuple;
|
||||
HeapScanDesc scan;
|
||||
IndexScanDesc iscan;
|
||||
HeapTupleData tuple;
|
||||
Buffer buffer;
|
||||
} SysScanDescData, *SysScanDesc;
|
||||
|
||||
} SysScanDescData, *SysScanDesc;
|
||||
|
||||
static void *
|
||||
systable_beginscan(Relation rel, const char *indexRelname, int nkeys, ScanKey entry)
|
||||
{
|
||||
bool hasindex = (rel->rd_rel->relhasindex && !IsIgnoringSystemIndexes());
|
||||
SysScanDesc sysscan;
|
||||
bool hasindex = (rel->rd_rel->relhasindex && !IsIgnoringSystemIndexes());
|
||||
SysScanDesc sysscan;
|
||||
|
||||
sysscan = (SysScanDesc) palloc(sizeof(SysScanDescData));
|
||||
sysscan->heap_rel = rel;
|
||||
@@ -710,7 +711,7 @@ systable_beginscan(Relation rel, const char *indexRelname, int nkeys, ScanKey en
|
||||
sysscan->buffer = InvalidBuffer;
|
||||
if (hasindex)
|
||||
{
|
||||
sysscan->irel = index_openr((char *)indexRelname);
|
||||
sysscan->irel = index_openr((char *) indexRelname);
|
||||
sysscan->iscan = index_beginscan(sysscan->irel, false, nkeys, entry);
|
||||
}
|
||||
else
|
||||
@@ -720,7 +721,7 @@ systable_beginscan(Relation rel, const char *indexRelname, int nkeys, ScanKey en
|
||||
static void
|
||||
systable_endscan(void *scan)
|
||||
{
|
||||
SysScanDesc sysscan = (SysScanDesc) scan;
|
||||
SysScanDesc sysscan = (SysScanDesc) scan;
|
||||
|
||||
if (sysscan->irel)
|
||||
{
|
||||
@@ -736,9 +737,9 @@ systable_endscan(void *scan)
|
||||
static HeapTuple
|
||||
systable_getnext(void *scan)
|
||||
{
|
||||
SysScanDesc sysscan = (SysScanDesc) scan;
|
||||
SysScanDesc sysscan = (SysScanDesc) scan;
|
||||
HeapTuple htup = (HeapTuple) NULL;
|
||||
RetrieveIndexResult indexRes;
|
||||
RetrieveIndexResult indexRes;
|
||||
|
||||
if (sysscan->irel)
|
||||
{
|
||||
@@ -774,50 +775,55 @@ find_attribute_walker(Node *node, int attnum)
|
||||
return false;
|
||||
if (IsA(node, Var))
|
||||
{
|
||||
Var *var = (Var *) node;
|
||||
Var *var = (Var *) node;
|
||||
|
||||
if (var->varlevelsup == 0 && var->varno == 1 &&
|
||||
var->varattno == attnum)
|
||||
return true;
|
||||
}
|
||||
return expression_tree_walker(node, find_attribute_walker, (void *)attnum);
|
||||
return expression_tree_walker(node, find_attribute_walker, (void *) attnum);
|
||||
}
|
||||
static bool
|
||||
find_attribute_in_node(Node *node, int attnum)
|
||||
{
|
||||
return expression_tree_walker(node, find_attribute_walker, (void *)attnum);
|
||||
return expression_tree_walker(node, find_attribute_walker, (void *) attnum);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove/check references for the column
|
||||
*/
|
||||
static bool
|
||||
RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
|
||||
{
|
||||
Relation indexRelation, rcrel;
|
||||
ScanKeyData entry;
|
||||
HeapScanDesc scan;
|
||||
void *sysscan;
|
||||
HeapTuple htup, indexTuple;
|
||||
Form_pg_index index;
|
||||
Form_pg_relcheck relcheck;
|
||||
Form_pg_class pgcform = (Form_pg_class) NULL;
|
||||
int i;
|
||||
Relation indexRelation,
|
||||
rcrel;
|
||||
ScanKeyData entry;
|
||||
HeapScanDesc scan;
|
||||
void *sysscan;
|
||||
HeapTuple htup,
|
||||
indexTuple;
|
||||
Form_pg_index index;
|
||||
Form_pg_relcheck relcheck;
|
||||
Form_pg_class pgcform = (Form_pg_class) NULL;
|
||||
int i;
|
||||
bool checkok = true;
|
||||
|
||||
|
||||
|
||||
if (!checkonly)
|
||||
pgcform = (Form_pg_class) GETSTRUCT (reltup);
|
||||
pgcform = (Form_pg_class) GETSTRUCT(reltup);
|
||||
|
||||
/*
|
||||
* Remove/check constraints here
|
||||
* Remove/check constraints here
|
||||
*/
|
||||
ScanKeyEntryInitialize(&entry, (bits16) 0x0, Anum_pg_relcheck_rcrelid,
|
||||
(RegProcedure) F_OIDEQ, ObjectIdGetDatum(reloid));
|
||||
(RegProcedure) F_OIDEQ, ObjectIdGetDatum(reloid));
|
||||
rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
|
||||
sysscan = systable_beginscan(rcrel, RelCheckIndex,1 ,&entry);
|
||||
sysscan = systable_beginscan(rcrel, RelCheckIndex, 1, &entry);
|
||||
|
||||
while (HeapTupleIsValid(htup = systable_getnext(sysscan)))
|
||||
{
|
||||
char *ccbin;
|
||||
Node *node;
|
||||
char *ccbin;
|
||||
Node *node;
|
||||
|
||||
relcheck = (Form_pg_relcheck) GETSTRUCT(htup);
|
||||
ccbin = textout(&relcheck->rcbin);
|
||||
@@ -843,15 +849,15 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
|
||||
heap_close(rcrel, NoLock);
|
||||
|
||||
/*
|
||||
* What to do with triggers/rules/views/procedues ?
|
||||
* What to do with triggers/rules/views/procedues ?
|
||||
*/
|
||||
|
||||
/*
|
||||
* Remove/check indexes
|
||||
* Remove/check indexes
|
||||
*/
|
||||
indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
|
||||
ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, F_OIDEQ,
|
||||
ObjectIdGetDatum(reloid));
|
||||
ObjectIdGetDatum(reloid));
|
||||
scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
|
||||
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
|
||||
{
|
||||
@@ -870,8 +876,8 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
|
||||
else
|
||||
{
|
||||
htup = SearchSysCacheTuple(RELOID,
|
||||
ObjectIdGetDatum(index->indexrelid),
|
||||
0, 0, 0);
|
||||
ObjectIdGetDatum(index->indexrelid),
|
||||
0, 0, 0);
|
||||
RemoveIndex(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname));
|
||||
}
|
||||
break;
|
||||
@@ -883,33 +889,38 @@ RemoveColumnReferences(Oid reloid, int attnum, bool checkonly, HeapTuple reltup)
|
||||
|
||||
return checkok;
|
||||
}
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
|
||||
/*
|
||||
* ALTER TABLE DROP COLUMN
|
||||
*/
|
||||
void
|
||||
AlterTableDropColumn(const char *relationName,
|
||||
bool inh, const char *colName,
|
||||
int behavior)
|
||||
bool inh, const char *colName,
|
||||
int behavior)
|
||||
{
|
||||
#ifdef _DROP_COLUMN_HACK__
|
||||
Relation rel, attrdesc, adrel;
|
||||
Oid myrelid, attoid;
|
||||
Relation rel,
|
||||
attrdesc,
|
||||
adrel;
|
||||
Oid myrelid,
|
||||
attoid;
|
||||
HeapTuple reltup;
|
||||
HeapTupleData classtuple;
|
||||
HeapTupleData classtuple;
|
||||
Buffer buffer;
|
||||
Form_pg_attribute attribute;
|
||||
HeapTuple tup;
|
||||
Relation idescs[Num_pg_attr_indices];
|
||||
int attnum;
|
||||
int attnum;
|
||||
bool hasindex;
|
||||
char dropColname[32];
|
||||
void *sysscan;
|
||||
ScanKeyData scankeys[2];
|
||||
void *sysscan;
|
||||
ScanKeyData scankeys[2];
|
||||
|
||||
if (inh)
|
||||
if (inh)
|
||||
elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet");
|
||||
|
||||
/*
|
||||
* permissions checking. this would normally be done in utility.c,
|
||||
* but this particular routine is recursive.
|
||||
@@ -925,25 +936,25 @@ AlterTableDropColumn(const char *relationName,
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT release
|
||||
* until end of transaction.
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
myrelid = RelationGetRelid(rel);
|
||||
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||
|
||||
/*
|
||||
* What to do when rel has inheritors ?
|
||||
* What to do when rel has inheritors ?
|
||||
*/
|
||||
if (length(find_all_inheritors(myrelid)) > 1)
|
||||
elog(ERROR, "ALTER TABLE: cannot drop a column on table that is inherited from");
|
||||
|
||||
|
||||
/*
|
||||
* lock the pg_class tuple for update
|
||||
* lock the pg_class tuple for update
|
||||
*/
|
||||
reltup = SearchSysCacheTuple(RELNAME, PointerGetDatum(relationName),
|
||||
0, 0, 0);
|
||||
0, 0, 0);
|
||||
|
||||
if (!HeapTupleIsValid(reltup))
|
||||
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
|
||||
@@ -976,19 +987,20 @@ AlterTableDropColumn(const char *relationName,
|
||||
* Get the target pg_attribute tuple
|
||||
*/
|
||||
tup = SearchSysCacheTupleCopy(ATTNAME,
|
||||
ObjectIdGetDatum(reltup->t_data->t_oid),
|
||||
PointerGetDatum(colName), 0, 0);
|
||||
ObjectIdGetDatum(reltup->t_data->t_oid),
|
||||
PointerGetDatum(colName), 0, 0);
|
||||
if (!HeapTupleIsValid(tup))
|
||||
elog(ERROR, "ALTER TABLE: column name \"%s\" doesn't exist in table \"%s\"",
|
||||
colName, relationName);
|
||||
colName, relationName);
|
||||
|
||||
attribute = (Form_pg_attribute) GETSTRUCT(tup);
|
||||
if (attribute->attnum <= 0)
|
||||
elog(ERROR, "ALTER TABLE: column name \"%s\" was already dropped", colName);
|
||||
attnum = attribute->attnum;
|
||||
attoid = tup->t_data->t_oid;
|
||||
|
||||
/*
|
||||
* Check constraints/indices etc here
|
||||
* Check constraints/indices etc here
|
||||
*/
|
||||
if (behavior != CASCADE)
|
||||
{
|
||||
@@ -997,7 +1009,7 @@ AlterTableDropColumn(const char *relationName,
|
||||
}
|
||||
|
||||
/*
|
||||
* change the target pg_attribute tuple
|
||||
* change the target pg_attribute tuple
|
||||
*/
|
||||
sprintf(dropColname, "*already Dropped*%d", attnum);
|
||||
namestrcpy(&(attribute->attname), dropColname);
|
||||
@@ -1009,7 +1021,7 @@ AlterTableDropColumn(const char *relationName,
|
||||
{
|
||||
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_attr_indices,
|
||||
attrdesc, tup);
|
||||
attrdesc, tup);
|
||||
CatalogCloseIndices(Num_pg_attr_indices, idescs);
|
||||
}
|
||||
heap_close(attrdesc, NoLock);
|
||||
@@ -1020,15 +1032,17 @@ AlterTableDropColumn(const char *relationName,
|
||||
/* delete attrdef */
|
||||
adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
|
||||
ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid,
|
||||
F_OIDEQ, ObjectIdGetDatum(myrelid));
|
||||
/* Oops pg_attrdef doesn't have (adrelid,adnum) index
|
||||
ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum,
|
||||
F_INT2EQ, Int16GetDatum(attnum));
|
||||
sysscan = systable_beginscan(adrel, AttrDefaultIndex, 2, scankeys);
|
||||
*/
|
||||
F_OIDEQ, ObjectIdGetDatum(myrelid));
|
||||
|
||||
/*
|
||||
* Oops pg_attrdef doesn't have (adrelid,adnum) index
|
||||
* ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum,
|
||||
* F_INT2EQ, Int16GetDatum(attnum)); sysscan =
|
||||
* systable_beginscan(adrel, AttrDefaultIndex, 2, scankeys);
|
||||
*/
|
||||
sysscan = systable_beginscan(adrel, AttrDefaultIndex, 1, scankeys);
|
||||
while (HeapTupleIsValid(tup = systable_getnext(sysscan)))
|
||||
{
|
||||
{
|
||||
if (((Form_pg_attrdef) GETSTRUCT(tup))->adnum == attnum)
|
||||
{
|
||||
heap_delete(adrel, &tup->t_self, NULL);
|
||||
@@ -1037,8 +1051,9 @@ AlterTableDropColumn(const char *relationName,
|
||||
}
|
||||
systable_endscan(sysscan);
|
||||
heap_close(adrel, NoLock);
|
||||
|
||||
/*
|
||||
* Remove objects which reference this column
|
||||
* Remove objects which reference this column
|
||||
*/
|
||||
if (behavior == CASCADE)
|
||||
{
|
||||
@@ -1055,8 +1070,8 @@ AlterTableDropColumn(const char *relationName,
|
||||
heap_freetuple(reltup);
|
||||
heap_close(rel, NoLock);
|
||||
#else
|
||||
elog(ERROR, "ALTER TABLE / DROP COLUMN is not implemented");
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
elog(ERROR, "ALTER TABLE / DROP COLUMN is not implemented");
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
}
|
||||
|
||||
|
||||
@@ -1066,76 +1081,80 @@ AlterTableDropColumn(const char *relationName,
|
||||
*/
|
||||
void
|
||||
AlterTableAddConstraint(const char *relationName,
|
||||
bool inh, Node *newConstraint)
|
||||
bool inh, Node *newConstraint)
|
||||
{
|
||||
if (newConstraint == NULL)
|
||||
if (newConstraint == NULL)
|
||||
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT passed invalid constraint.");
|
||||
|
||||
switch (nodeTag(newConstraint))
|
||||
switch (nodeTag(newConstraint))
|
||||
{
|
||||
case T_Constraint:
|
||||
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT is not implemented");
|
||||
case T_FkConstraint:
|
||||
{
|
||||
FkConstraint *fkconstraint=(FkConstraint *)newConstraint;
|
||||
Relation rel;
|
||||
FkConstraint *fkconstraint = (FkConstraint *) newConstraint;
|
||||
Relation rel;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
Trigger trig;
|
||||
List *list;
|
||||
int count;
|
||||
HeapTuple tuple;
|
||||
Trigger trig;
|
||||
List *list;
|
||||
int count;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Grab an exclusive lock on the pk table, so that someone
|
||||
* doesn't delete rows out from under us.
|
||||
* doesn't delete rows out from under us.
|
||||
*/
|
||||
|
||||
rel = heap_openr(fkconstraint->pktable_name, AccessExclusiveLock);
|
||||
heap_close(rel, NoLock);
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the fk table, and then scan through
|
||||
* each tuple, calling the RI_FKey_Match_Ins (insert trigger)
|
||||
* as if that tuple had just been inserted. If any of those
|
||||
* fail, it should elog(ERROR) and that's that.
|
||||
/*
|
||||
* Grab an exclusive lock on the fk table, and then scan
|
||||
* through each tuple, calling the RI_FKey_Match_Ins
|
||||
* (insert trigger) as if that tuple had just been
|
||||
* inserted. If any of those fail, it should elog(ERROR)
|
||||
* and that's that.
|
||||
*/
|
||||
rel = heap_openr(relationName, AccessExclusiveLock);
|
||||
trig.tgoid = 0;
|
||||
trig.tgname = "<unknown>";
|
||||
trig.tgfoid = 0;
|
||||
trig.tgfoid = 0;
|
||||
trig.tgtype = 0;
|
||||
trig.tgenabled = TRUE;
|
||||
trig.tgisconstraint = TRUE;
|
||||
trig.tginitdeferred = FALSE;
|
||||
trig.tgdeferrable = FALSE;
|
||||
|
||||
trig.tgargs = (char **)palloc(
|
||||
sizeof(char *) * (4 + length(fkconstraint->fk_attrs)
|
||||
+ length(fkconstraint->pk_attrs)));
|
||||
|
||||
trig.tgargs = (char **) palloc(
|
||||
sizeof(char *) * (4 + length(fkconstraint->fk_attrs)
|
||||
+ length(fkconstraint->pk_attrs)));
|
||||
|
||||
trig.tgargs[0] = "<unnamed>";
|
||||
trig.tgargs[1] = (char *)relationName;
|
||||
trig.tgargs[1] = (char *) relationName;
|
||||
trig.tgargs[2] = fkconstraint->pktable_name;
|
||||
trig.tgargs[3] = fkconstraint->match_type;
|
||||
count = 4;
|
||||
foreach (list, fkconstraint->fk_attrs)
|
||||
foreach(list, fkconstraint->fk_attrs)
|
||||
{
|
||||
Ident *fk_at = lfirst(list);
|
||||
Ident *fk_at = lfirst(list);
|
||||
|
||||
trig.tgargs[count++] = fk_at->name;
|
||||
}
|
||||
foreach (list, fkconstraint->pk_attrs)
|
||||
foreach(list, fkconstraint->pk_attrs)
|
||||
{
|
||||
Ident *pk_at = lfirst(list);
|
||||
Ident *pk_at = lfirst(list);
|
||||
|
||||
trig.tgargs[count++] = pk_at->name;
|
||||
}
|
||||
trig.tgnargs = count;
|
||||
|
||||
scan = heap_beginscan(rel, false, SnapshotNow, 0, NULL);
|
||||
AssertState(scan!=NULL);
|
||||
AssertState(scan != NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
|
||||
{
|
||||
TriggerData newtrigdata;
|
||||
|
||||
newtrigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW;
|
||||
newtrigdata.tg_relation = rel;
|
||||
newtrigdata.tg_trigtuple = tuple;
|
||||
@@ -1149,7 +1168,8 @@ AlterTableAddConstraint(const char *relationName,
|
||||
/* Make a call to the check function */
|
||||
}
|
||||
heap_endscan(scan);
|
||||
heap_close(rel, NoLock); /* close rel but keep lock! */
|
||||
heap_close(rel, NoLock); /* close rel but keep
|
||||
* lock! */
|
||||
|
||||
pfree(trig.tgargs);
|
||||
}
|
||||
@@ -1166,10 +1186,10 @@ AlterTableAddConstraint(const char *relationName,
|
||||
*/
|
||||
void
|
||||
AlterTableDropConstraint(const char *relationName,
|
||||
bool inh, const char *constrName,
|
||||
int behavior)
|
||||
bool inh, const char *constrName,
|
||||
int behavior)
|
||||
{
|
||||
elog(ERROR, "ALTER TABLE / DROP CONSTRAINT is not implemented");
|
||||
elog(ERROR, "ALTER TABLE / DROP CONSTRAINT is not implemented");
|
||||
}
|
||||
|
||||
|
||||
@@ -1186,7 +1206,7 @@ LockTableCommand(LockStmt *lockstmt)
|
||||
int aclresult;
|
||||
|
||||
rel = heap_openr(lockstmt->relname, NoLock);
|
||||
if (! RelationIsValid(rel))
|
||||
if (!RelationIsValid(rel))
|
||||
elog(ERROR, "Relation '%s' does not exist", lockstmt->relname);
|
||||
|
||||
if (lockstmt->mode == AccessShareLock)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.103 2000/03/23 21:38:58 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.104 2000/04/12 17:14:58 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -64,8 +64,8 @@ static int CountTuples(Relation relation);
|
||||
* Static communication variables ... pretty grotty, but COPY has
|
||||
* never been reentrant...
|
||||
*/
|
||||
int lineno = 0; /* used by elog() -- dz */
|
||||
static bool fe_eof;
|
||||
int lineno = 0; /* used by elog() -- dz */
|
||||
static bool fe_eof;
|
||||
|
||||
/*
|
||||
* These static variables are used to avoid incurring overhead for each
|
||||
@@ -76,9 +76,11 @@ static bool fe_eof;
|
||||
* to attribute_buf's data buffer!
|
||||
* encoding, if needed, can be set once at the start of the copy operation.
|
||||
*/
|
||||
static StringInfoData attribute_buf;
|
||||
static StringInfoData attribute_buf;
|
||||
|
||||
#ifdef MULTIBYTE
|
||||
static int encoding;
|
||||
static int encoding;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -113,11 +115,11 @@ CopySendData(void *databuf, int datasize, FILE *fp)
|
||||
fe_eof = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
fwrite(databuf, datasize, 1, fp);
|
||||
if (ferror(fp))
|
||||
elog(ERROR, "CopySendData: %s", strerror(errno));
|
||||
}
|
||||
if (ferror(fp))
|
||||
elog(ERROR, "CopySendData: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -194,7 +196,8 @@ CopyPeekChar(FILE *fp)
|
||||
{
|
||||
if (!fp)
|
||||
{
|
||||
int ch = pq_peekbyte();
|
||||
int ch = pq_peekbyte();
|
||||
|
||||
if (ch == EOF)
|
||||
fe_eof = true;
|
||||
return ch;
|
||||
@@ -280,15 +283,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
|
||||
* Open and lock the relation, using the appropriate lock type.
|
||||
*
|
||||
* Note: AccessExclusive is probably overkill for copying to a relation,
|
||||
* but that's what the code grabs on the rel's indices. If this lock is
|
||||
* relaxed then I think the index locks need relaxed also.
|
||||
* but that's what the code grabs on the rel's indices. If this lock
|
||||
* is relaxed then I think the index locks need relaxed also.
|
||||
*/
|
||||
rel = heap_openr(relname, (from ? AccessExclusiveLock : AccessShareLock));
|
||||
|
||||
result = pg_aclcheck(relname, UserName, required_access);
|
||||
if (result != ACLCHECK_OK)
|
||||
elog(ERROR, "%s: %s", relname, aclcheck_error_strings[result]);
|
||||
if (!pipe && !superuser())
|
||||
if (!pipe && !superuser())
|
||||
elog(ERROR, "You must have Postgres superuser privilege to do a COPY "
|
||||
"directly to or from a file. Anyone can COPY to stdout or "
|
||||
"from stdin. Psql's \\copy command also works for anyone.");
|
||||
@@ -345,13 +348,13 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
|
||||
}
|
||||
else
|
||||
{
|
||||
mode_t oumask; /* Pre-existing umask value */
|
||||
mode_t oumask; /* Pre-existing umask value */
|
||||
|
||||
oumask = umask((mode_t) 022);
|
||||
oumask = umask((mode_t) 022);
|
||||
|
||||
if (*filename != '/')
|
||||
elog(ERROR, "Relative path not allowed for server side"
|
||||
" COPY command.");
|
||||
" COPY command.");
|
||||
|
||||
#ifndef __CYGWIN32__
|
||||
fp = AllocateFile(filename, "w");
|
||||
@@ -369,9 +372,7 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
|
||||
}
|
||||
|
||||
if (!pipe)
|
||||
{
|
||||
FreeFile(fp);
|
||||
}
|
||||
else if (!from)
|
||||
{
|
||||
if (!binary)
|
||||
@@ -382,9 +383,10 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
|
||||
pfree(attribute_buf.data);
|
||||
|
||||
/*
|
||||
* Close the relation. If reading, we can release the AccessShareLock
|
||||
* we got; if writing, we should hold the lock until end of transaction
|
||||
* to ensure that updates will be committed before lock is released.
|
||||
* Close the relation. If reading, we can release the AccessShareLock
|
||||
* we got; if writing, we should hold the lock until end of
|
||||
* transaction to ensure that updates will be committed before lock is
|
||||
* released.
|
||||
*/
|
||||
heap_close(rel, (from ? NoLock : AccessShareLock));
|
||||
}
|
||||
@@ -399,9 +401,11 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
|
||||
|
||||
int32 attr_count,
|
||||
i;
|
||||
|
||||
#ifdef _DROP_COLUMN_HACK__
|
||||
bool *valid;
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
bool *valid;
|
||||
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
Form_pg_attribute *attr;
|
||||
FmgrInfo *out_functions;
|
||||
Oid out_func_oid;
|
||||
@@ -435,7 +439,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
|
||||
typmod = (int32 *) palloc(attr_count * sizeof(int32));
|
||||
#ifdef _DROP_COLUMN_HACK__
|
||||
valid = (bool *) palloc(attr_count * sizeof(bool));
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
for (i = 0; i < attr_count; i++)
|
||||
{
|
||||
#ifdef _DROP_COLUMN_HACK__
|
||||
@@ -446,7 +450,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
|
||||
}
|
||||
else
|
||||
valid[i] = true;
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
out_func_oid = (Oid) GetOutputFunction(attr[i]->atttypid);
|
||||
fmgr_info(out_func_oid, &out_functions[i]);
|
||||
elements[i] = GetTypeElement(attr[i]->atttypid);
|
||||
@@ -493,7 +497,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
|
||||
CopySendChar('\n', fp);
|
||||
continue;
|
||||
}
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
if (!isnull)
|
||||
{
|
||||
string = (char *) (*fmgr_faddr(&out_functions[i]))
|
||||
@@ -502,7 +506,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
|
||||
pfree(string);
|
||||
}
|
||||
else
|
||||
CopySendString(null_print, fp); /* null indicator */
|
||||
CopySendString(null_print, fp); /* null indicator */
|
||||
|
||||
if (i == attr_count - 1)
|
||||
CopySendChar('\n', fp);
|
||||
@@ -723,7 +727,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
|
||||
#ifdef _DROP_COLUMN_HACK__
|
||||
if (COLUMN_IS_DROPPED(attr[i]))
|
||||
continue;
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid);
|
||||
fmgr_info(in_func_oid, &in_functions[i]);
|
||||
elements[i] = GetTypeElement(attr[i]->atttypid);
|
||||
@@ -756,7 +760,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
|
||||
byval[i] = 'n';
|
||||
continue;
|
||||
}
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
byval[i] = (bool) IsTypeByVal(attr[i]->atttypid);
|
||||
}
|
||||
|
||||
@@ -765,7 +769,8 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
|
||||
|
||||
while (!done)
|
||||
{
|
||||
if (QueryCancel) {
|
||||
if (QueryCancel)
|
||||
{
|
||||
lineno = 0;
|
||||
CancelQuery();
|
||||
}
|
||||
@@ -796,7 +801,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
|
||||
nulls[i] = 'n';
|
||||
continue;
|
||||
}
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
string = CopyReadAttribute(fp, &isnull, delim, &newline, null_print);
|
||||
if (isnull)
|
||||
{
|
||||
@@ -937,7 +942,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
|
||||
*/
|
||||
slot->val = tuple;
|
||||
/* SetSlotContents(slot, tuple); */
|
||||
if (! ExecQual((List *) indexPred[i], econtext, false))
|
||||
if (!ExecQual((List *) indexPred[i], econtext, false))
|
||||
continue;
|
||||
#endif /* OMIT_PARTIAL_INDEX */
|
||||
}
|
||||
@@ -1189,6 +1194,7 @@ static char *
|
||||
CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print)
|
||||
{
|
||||
int c;
|
||||
|
||||
#ifdef MULTIBYTE
|
||||
int mblen;
|
||||
unsigned char s[2];
|
||||
@@ -1222,9 +1228,7 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_
|
||||
break;
|
||||
}
|
||||
if (strchr(delim, c))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (c == '\\')
|
||||
{
|
||||
c = CopyGetChar(fp);
|
||||
@@ -1272,13 +1276,16 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_
|
||||
c = val & 0377;
|
||||
}
|
||||
break;
|
||||
/* This is a special hack to parse `\N' as <backslash-N>
|
||||
rather then just 'N' to provide compatibility with
|
||||
the default NULL output. -- pe */
|
||||
case 'N':
|
||||
appendStringInfoCharMacro(&attribute_buf, '\\');
|
||||
c = 'N';
|
||||
break;
|
||||
|
||||
/*
|
||||
* This is a special hack to parse `\N' as
|
||||
* <backslash-N> rather then just 'N' to provide
|
||||
* compatibility with the default NULL output. -- pe
|
||||
*/
|
||||
case 'N':
|
||||
appendStringInfoCharMacro(&attribute_buf, '\\');
|
||||
c = 'N';
|
||||
break;
|
||||
case 'b':
|
||||
c = '\b';
|
||||
break;
|
||||
@@ -1332,8 +1339,8 @@ CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strcmp(attribute_buf.data, null_print)==0)
|
||||
*isnull = true;
|
||||
if (strcmp(attribute_buf.data, null_print) == 0)
|
||||
*isnull = true;
|
||||
|
||||
return attribute_buf.data;
|
||||
|
||||
@@ -1346,10 +1353,12 @@ CopyAttributeOut(FILE *fp, char *server_string, char *delim)
|
||||
{
|
||||
char *string;
|
||||
char c;
|
||||
|
||||
#ifdef MULTIBYTE
|
||||
char *string_start;
|
||||
int mblen;
|
||||
int i;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MULTIBYTE
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.56 2000/01/29 16:58:34 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.57 2000/04/12 17:14:58 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
static bool checkAttrExists(const char *attributeName,
|
||||
const char *attributeType, List *schema);
|
||||
const char *attributeType, List *schema);
|
||||
static List *MergeAttributes(List *schema, List *supers, List **supconstr);
|
||||
static void StoreCatalogInheritance(Oid relationId, List *supers);
|
||||
|
||||
@@ -145,14 +145,14 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
||||
StoreCatalogInheritance(relationId, inheritList);
|
||||
|
||||
/*
|
||||
* Now add any newly specified column default values
|
||||
* and CHECK constraints to the new relation. These are passed
|
||||
* to us in the form of raw parsetrees; we need to transform
|
||||
* them to executable expression trees before they can be added.
|
||||
* The most convenient way to do that is to apply the parser's
|
||||
* transformExpr routine, but transformExpr doesn't work unless
|
||||
* we have a pre-existing relation. So, the transformation has
|
||||
* to be postponed to this final step of CREATE TABLE.
|
||||
* Now add any newly specified column default values and CHECK
|
||||
* constraints to the new relation. These are passed to us in the
|
||||
* form of raw parsetrees; we need to transform them to executable
|
||||
* expression trees before they can be added. The most convenient way
|
||||
* to do that is to apply the parser's transformExpr routine, but
|
||||
* transformExpr doesn't work unless we have a pre-existing relation.
|
||||
* So, the transformation has to be postponed to this final step of
|
||||
* CREATE TABLE.
|
||||
*
|
||||
* First, scan schema to find new column defaults.
|
||||
*/
|
||||
@@ -181,21 +181,24 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
||||
return;
|
||||
|
||||
/*
|
||||
* We must bump the command counter to make the newly-created
|
||||
* relation tuple visible for opening.
|
||||
* We must bump the command counter to make the newly-created relation
|
||||
* tuple visible for opening.
|
||||
*/
|
||||
CommandCounterIncrement();
|
||||
|
||||
/*
|
||||
* Open the new relation.
|
||||
*/
|
||||
rel = heap_openr(relname, AccessExclusiveLock);
|
||||
|
||||
/*
|
||||
* Parse and add the defaults/constraints.
|
||||
*/
|
||||
AddRelationRawConstraints(rel, rawDefaults, stmt->constraints);
|
||||
|
||||
/*
|
||||
* Clean up. We keep lock on new relation (although it shouldn't
|
||||
* be visible to anyone else anyway, until commit).
|
||||
* Clean up. We keep lock on new relation (although it shouldn't be
|
||||
* visible to anyone else anyway, until commit).
|
||||
*/
|
||||
heap_close(rel, NoLock);
|
||||
}
|
||||
@@ -220,13 +223,13 @@ RemoveRelation(char *name)
|
||||
|
||||
/*
|
||||
* TruncateRelation --
|
||||
* Removes all the rows from a relation
|
||||
* Removes all the rows from a relation
|
||||
*
|
||||
* Exceptions:
|
||||
* BadArg if name is invalid
|
||||
* BadArg if name is invalid
|
||||
*
|
||||
* Note:
|
||||
* Rows are removed, indices are truncated and reconstructed.
|
||||
* Rows are removed, indices are truncated and reconstructed.
|
||||
*/
|
||||
void
|
||||
TruncateRelation(char *name)
|
||||
@@ -284,6 +287,7 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
|
||||
|
||||
foreach(rest, lnext(entry))
|
||||
{
|
||||
|
||||
/*
|
||||
* check for duplicated names within the new relation
|
||||
*/
|
||||
@@ -352,11 +356,12 @@ MergeAttributes(List *schema, List *supers, List **supconstr)
|
||||
* check validity
|
||||
*
|
||||
*/
|
||||
if (checkAttrExists(attributeName, attributeType, schema))
|
||||
elog(ERROR, "CREATE TABLE: attribute \"%s\" already exists in inherited schema",
|
||||
attributeName);
|
||||
if (checkAttrExists(attributeName, attributeType, schema))
|
||||
elog(ERROR, "CREATE TABLE: attribute \"%s\" already exists in inherited schema",
|
||||
attributeName);
|
||||
|
||||
if (checkAttrExists(attributeName, attributeType, inhSchema))
|
||||
|
||||
/*
|
||||
* this entry already exists
|
||||
*/
|
||||
@@ -499,7 +504,7 @@ StoreCatalogInheritance(Oid relationId, List *supers)
|
||||
if (RelationGetForm(relation)->relhasindex)
|
||||
{
|
||||
Relation idescs[Num_pg_inherits_indices];
|
||||
|
||||
|
||||
CatalogOpenIndices(Num_pg_inherits_indices, Name_pg_inherits_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_inherits_indices, relation, tuple);
|
||||
CatalogCloseIndices(Num_pg_inherits_indices, idescs);
|
||||
@@ -642,8 +647,9 @@ checkAttrExists(const char *attributeName, const char *attributeType, List *sche
|
||||
{
|
||||
ColumnDef *def = lfirst(s);
|
||||
|
||||
if (strcmp(attributeName, def->colname)==0)
|
||||
if (strcmp(attributeName, def->colname) == 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* attribute exists. Make sure the types are the same.
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.52 2000/03/26 18:32:28 petere Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.53 2000/04/12 17:14:58 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -33,9 +33,9 @@
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "commands/comment.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/bufmgr.h" /* for DropBuffers */
|
||||
#include "storage/fd.h" /* for closeAllVfds */
|
||||
#include "storage/sinval.h" /* for DatabaseHasActiveBackends */
|
||||
#include "storage/bufmgr.h" /* for DropBuffers */
|
||||
#include "storage/fd.h" /* for closeAllVfds */
|
||||
#include "storage/sinval.h" /* for DatabaseHasActiveBackends */
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/elog.h"
|
||||
#include "utils/palloc.h"
|
||||
@@ -45,10 +45,10 @@
|
||||
|
||||
/* non-export function prototypes */
|
||||
static bool
|
||||
get_user_info(const char *name, int4 *use_sysid, bool *use_super, bool *use_createdb);
|
||||
get_user_info(const char *name, int4 *use_sysid, bool *use_super, bool *use_createdb);
|
||||
|
||||
static bool
|
||||
get_db_info(const char *name, char *dbpath, Oid *dbIdP, int4 *ownerIdP);
|
||||
get_db_info(const char *name, char *dbpath, Oid *dbIdP, int4 *ownerIdP);
|
||||
|
||||
|
||||
|
||||
@@ -61,99 +61,104 @@ createdb(const char *dbname, const char *dbpath, int encoding)
|
||||
{
|
||||
char buf[2 * MAXPGPATH + 100];
|
||||
char *loc;
|
||||
char locbuf[512];
|
||||
char locbuf[512];
|
||||
int4 user_id;
|
||||
bool use_super, use_createdb;
|
||||
bool use_super,
|
||||
use_createdb;
|
||||
Relation pg_database_rel;
|
||||
HeapTuple tuple;
|
||||
TupleDesc pg_database_dsc;
|
||||
Datum new_record[Natts_pg_database];
|
||||
char new_record_nulls[Natts_pg_database] = { ' ', ' ', ' ', ' ' };
|
||||
TupleDesc pg_database_dsc;
|
||||
Datum new_record[Natts_pg_database];
|
||||
char new_record_nulls[Natts_pg_database] = {' ', ' ', ' ', ' '};
|
||||
|
||||
if (!get_user_info(GetPgUserName(), &user_id, &use_super, &use_createdb))
|
||||
elog(ERROR, "current user name is invalid");
|
||||
if (!get_user_info(GetPgUserName(), &user_id, &use_super, &use_createdb))
|
||||
elog(ERROR, "current user name is invalid");
|
||||
|
||||
if (!use_createdb && !use_super)
|
||||
elog(ERROR, "CREATE DATABASE: permission denied");
|
||||
if (!use_createdb && !use_super)
|
||||
elog(ERROR, "CREATE DATABASE: permission denied");
|
||||
|
||||
if (get_db_info(dbname, NULL, NULL, NULL))
|
||||
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname);
|
||||
if (get_db_info(dbname, NULL, NULL, NULL))
|
||||
elog(ERROR, "CREATE DATABASE: database \"%s\" already exists", dbname);
|
||||
|
||||
/* don't call this in a transaction block */
|
||||
/* don't call this in a transaction block */
|
||||
if (IsTransactionBlock())
|
||||
elog(ERROR, "CREATE DATABASE: may not be called in a transaction block");
|
||||
elog(ERROR, "CREATE DATABASE: may not be called in a transaction block");
|
||||
|
||||
/* Generate directory name for the new database */
|
||||
if (dbpath == NULL || strcmp(dbpath, dbname)==0)
|
||||
strcpy(locbuf, dbname);
|
||||
else
|
||||
snprintf(locbuf, sizeof(locbuf), "%s/%s", dbpath, dbname);
|
||||
if (dbpath == NULL || strcmp(dbpath, dbname) == 0)
|
||||
strcpy(locbuf, dbname);
|
||||
else
|
||||
snprintf(locbuf, sizeof(locbuf), "%s/%s", dbpath, dbname);
|
||||
|
||||
loc = ExpandDatabasePath(locbuf);
|
||||
loc = ExpandDatabasePath(locbuf);
|
||||
|
||||
if (loc == NULL)
|
||||
elog(ERROR,
|
||||
"The database path '%s' is invalid. "
|
||||
"The database path '%s' is invalid. "
|
||||
"This may be due to a character that is not allowed or because the chosen "
|
||||
"path isn't permitted for databases", dbpath);
|
||||
"path isn't permitted for databases", dbpath);
|
||||
|
||||
/* close virtual file descriptors so the kernel has more available for
|
||||
the system() calls */
|
||||
/*
|
||||
* close virtual file descriptors so the kernel has more available for
|
||||
* the system() calls
|
||||
*/
|
||||
closeAllVfds();
|
||||
|
||||
/*
|
||||
* Insert a new tuple into pg_database
|
||||
*/
|
||||
/*
|
||||
* Insert a new tuple into pg_database
|
||||
*/
|
||||
pg_database_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
|
||||
pg_database_dsc = RelationGetDescr(pg_database_rel);
|
||||
|
||||
/* Form tuple */
|
||||
new_record[Anum_pg_database_datname-1] = NameGetDatum(namein(dbname));
|
||||
new_record[Anum_pg_database_datdba-1] = Int32GetDatum(user_id);
|
||||
new_record[Anum_pg_database_encoding-1] = Int32GetDatum(encoding);
|
||||
new_record[Anum_pg_database_datpath-1] = PointerGetDatum(textin(locbuf));
|
||||
/* Form tuple */
|
||||
new_record[Anum_pg_database_datname - 1] = NameGetDatum(namein(dbname));
|
||||
new_record[Anum_pg_database_datdba - 1] = Int32GetDatum(user_id);
|
||||
new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding);
|
||||
new_record[Anum_pg_database_datpath - 1] = PointerGetDatum(textin(locbuf));
|
||||
|
||||
tuple = heap_formtuple(pg_database_dsc, new_record, new_record_nulls);
|
||||
tuple = heap_formtuple(pg_database_dsc, new_record, new_record_nulls);
|
||||
|
||||
/*
|
||||
* Update table
|
||||
*/
|
||||
heap_insert(pg_database_rel, tuple);
|
||||
/*
|
||||
* Update table
|
||||
*/
|
||||
heap_insert(pg_database_rel, tuple);
|
||||
|
||||
/*
|
||||
* Update indexes (there aren't any currently)
|
||||
*/
|
||||
/*
|
||||
* Update indexes (there aren't any currently)
|
||||
*/
|
||||
#ifdef Num_pg_database_indices
|
||||
if (RelationGetForm(pg_database_rel)->relhasindex) {
|
||||
Relation idescs[Num_pg_database_indices];
|
||||
|
||||
CatalogOpenIndices(Num_pg_database_indices,
|
||||
Name_pg_database_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_database_indices, pg_database_rel,
|
||||
tuple);
|
||||
CatalogCloseIndices(Num_pg_database_indices, idescs);
|
||||
}
|
||||
if (RelationGetForm(pg_database_rel)->relhasindex)
|
||||
{
|
||||
Relation idescs[Num_pg_database_indices];
|
||||
|
||||
CatalogOpenIndices(Num_pg_database_indices,
|
||||
Name_pg_database_indices, idescs);
|
||||
CatalogIndexInsert(idescs, Num_pg_database_indices, pg_database_rel,
|
||||
tuple);
|
||||
CatalogCloseIndices(Num_pg_database_indices, idescs);
|
||||
}
|
||||
#endif
|
||||
|
||||
heap_close(pg_database_rel, NoLock);
|
||||
|
||||
/* Copy the template database to the new location */
|
||||
/* Copy the template database to the new location */
|
||||
|
||||
if (mkdir(loc, S_IRWXU) != 0) {
|
||||
if (mkdir(loc, S_IRWXU) != 0)
|
||||
elog(ERROR, "CREATE DATABASE: unable to create database directory '%s': %s", loc, strerror(errno));
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "cp %s%cbase%ctemplate1%c* '%s'",
|
||||
DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR, loc);
|
||||
if (system(buf) != 0) {
|
||||
int ret;
|
||||
snprintf(buf, sizeof(buf), "rm -rf '%s'", loc);
|
||||
ret = system(buf);
|
||||
if (ret == 0)
|
||||
elog(ERROR, "CREATE DATABASE: could not initialize database directory");
|
||||
else
|
||||
elog(ERROR, "CREATE DATABASE: Could not initialize database directory. Delete failed as well");
|
||||
}
|
||||
if (system(buf) != 0)
|
||||
{
|
||||
int ret;
|
||||
|
||||
snprintf(buf, sizeof(buf), "rm -rf '%s'", loc);
|
||||
ret = system(buf);
|
||||
if (ret == 0)
|
||||
elog(ERROR, "CREATE DATABASE: could not initialize database directory");
|
||||
else
|
||||
elog(ERROR, "CREATE DATABASE: Could not initialize database directory. Delete failed as well");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,18 +170,19 @@ createdb(const char *dbname, const char *dbpath, int encoding)
|
||||
void
|
||||
dropdb(const char *dbname)
|
||||
{
|
||||
int4 user_id, db_owner;
|
||||
bool use_super;
|
||||
int4 user_id,
|
||||
db_owner;
|
||||
bool use_super;
|
||||
Oid db_id;
|
||||
char *path,
|
||||
dbpath[MAXPGPATH],
|
||||
buf[MAXPGPATH + 100];
|
||||
Relation pgdbrel;
|
||||
HeapScanDesc pgdbscan;
|
||||
ScanKeyData key;
|
||||
ScanKeyData key;
|
||||
HeapTuple tup;
|
||||
|
||||
AssertArg(dbname);
|
||||
AssertArg(dbname);
|
||||
|
||||
if (strcmp(dbname, "template1") == 0)
|
||||
elog(ERROR, "DROP DATABASE: May not be executed on the template1 database");
|
||||
@@ -185,46 +191,49 @@ dropdb(const char *dbname)
|
||||
elog(ERROR, "DROP DATABASE: Cannot be executed on the currently open database");
|
||||
|
||||
if (IsTransactionBlock())
|
||||
elog(ERROR, "DROP DATABASE: May not be called in a transaction block");
|
||||
elog(ERROR, "DROP DATABASE: May not be called in a transaction block");
|
||||
|
||||
if (!get_user_info(GetPgUserName(), &user_id, &use_super, NULL))
|
||||
elog(ERROR, "Current user name is invalid");
|
||||
if (!get_user_info(GetPgUserName(), &user_id, &use_super, NULL))
|
||||
elog(ERROR, "Current user name is invalid");
|
||||
|
||||
if (!get_db_info(dbname, dbpath, &db_id, &db_owner))
|
||||
elog(ERROR, "DROP DATABASE: Database \"%s\" does not exist", dbname);
|
||||
if (!get_db_info(dbname, dbpath, &db_id, &db_owner))
|
||||
elog(ERROR, "DROP DATABASE: Database \"%s\" does not exist", dbname);
|
||||
|
||||
if (user_id != db_owner && !use_super)
|
||||
elog(ERROR, "DROP DATABASE: Permission denied");
|
||||
if (user_id != db_owner && !use_super)
|
||||
elog(ERROR, "DROP DATABASE: Permission denied");
|
||||
|
||||
path = ExpandDatabasePath(dbpath);
|
||||
if (path == NULL)
|
||||
elog(ERROR,
|
||||
"The database path '%s' is invalid. "
|
||||
"The database path '%s' is invalid. "
|
||||
"This may be due to a character that is not allowed or because the chosen "
|
||||
"path isn't permitted for databases", path);
|
||||
"path isn't permitted for databases", path);
|
||||
|
||||
/* close virtual file descriptors so the kernel has more available for
|
||||
the system() calls */
|
||||
/*
|
||||
* close virtual file descriptors so the kernel has more available for
|
||||
* the system() calls
|
||||
*/
|
||||
closeAllVfds();
|
||||
|
||||
/*
|
||||
* Obtain exclusive lock on pg_database. We need this to ensure
|
||||
* that no new backend starts up in the target database while we
|
||||
* are deleting it. (Actually, a new backend might still manage to
|
||||
* start up, because it will read pg_database without any locking
|
||||
* to discover the database's OID. But it will detect its error
|
||||
* in ReverifyMyDatabase and shut down before any serious damage
|
||||
* is done. See postinit.c.)
|
||||
* Obtain exclusive lock on pg_database. We need this to ensure that
|
||||
* no new backend starts up in the target database while we are
|
||||
* deleting it. (Actually, a new backend might still manage to start
|
||||
* up, because it will read pg_database without any locking to
|
||||
* discover the database's OID. But it will detect its error in
|
||||
* ReverifyMyDatabase and shut down before any serious damage is done.
|
||||
* See postinit.c.)
|
||||
*/
|
||||
pgdbrel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
|
||||
|
||||
/*
|
||||
* Check for active backends in the target database.
|
||||
*/
|
||||
if (DatabaseHasActiveBackends(db_id)) {
|
||||
if (DatabaseHasActiveBackends(db_id))
|
||||
{
|
||||
heap_close(pgdbrel, AccessExclusiveLock);
|
||||
elog(ERROR, "DROP DATABASE: Database \"%s\" is being accessed by other users", dbname);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the database's tuple by OID (should be unique, we trust).
|
||||
@@ -238,8 +247,11 @@ dropdb(const char *dbname)
|
||||
if (!HeapTupleIsValid(tup))
|
||||
{
|
||||
heap_close(pgdbrel, AccessExclusiveLock);
|
||||
/* This error should never come up since the existence of the
|
||||
database is checked earlier */
|
||||
|
||||
/*
|
||||
* This error should never come up since the existence of the
|
||||
* database is checked earlier
|
||||
*/
|
||||
elog(ERROR, "DROP DATABASE: Database \"%s\" doesn't exist despite earlier reports to the contrary",
|
||||
dbname);
|
||||
}
|
||||
@@ -270,7 +282,7 @@ dropdb(const char *dbname)
|
||||
*/
|
||||
snprintf(buf, sizeof(buf), "rm -rf '%s'", path);
|
||||
if (system(buf) != 0)
|
||||
elog(NOTICE, "DROP DATABASE: The database directory '%s' could not be removed", path);
|
||||
elog(NOTICE, "DROP DATABASE: The database directory '%s' could not be removed", path);
|
||||
}
|
||||
|
||||
|
||||
@@ -285,11 +297,11 @@ get_db_info(const char *name, char *dbpath, Oid *dbIdP, int4 *ownerIdP)
|
||||
Relation relation;
|
||||
HeapTuple tuple;
|
||||
ScanKeyData scanKey;
|
||||
HeapScanDesc scan;
|
||||
HeapScanDesc scan;
|
||||
|
||||
AssertArg(name);
|
||||
AssertArg(name);
|
||||
|
||||
relation = heap_openr(DatabaseRelationName, AccessExclusiveLock/*???*/);
|
||||
relation = heap_openr(DatabaseRelationName, AccessExclusiveLock /* ??? */ );
|
||||
|
||||
ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname,
|
||||
F_NAMEEQ, NameGetDatum(name));
|
||||
@@ -302,76 +314,76 @@ get_db_info(const char *name, char *dbpath, Oid *dbIdP, int4 *ownerIdP)
|
||||
|
||||
if (HeapTupleIsValid(tuple))
|
||||
{
|
||||
text *tmptext;
|
||||
bool isnull;
|
||||
|
||||
/* oid of the database */
|
||||
if (dbIdP)
|
||||
*dbIdP = tuple->t_data->t_oid;
|
||||
/* uid of the owner */
|
||||
if (ownerIdP)
|
||||
{
|
||||
*ownerIdP = (int4) heap_getattr(tuple,
|
||||
Anum_pg_database_datdba,
|
||||
RelationGetDescr(relation),
|
||||
&isnull);
|
||||
if (isnull)
|
||||
*ownerIdP = -1; /* hopefully no one has that id already ;) */
|
||||
}
|
||||
/* database path (as registered in pg_database) */
|
||||
if (dbpath)
|
||||
{
|
||||
tmptext = (text *) heap_getattr(tuple,
|
||||
Anum_pg_database_datpath,
|
||||
RelationGetDescr(relation),
|
||||
&isnull);
|
||||
text *tmptext;
|
||||
bool isnull;
|
||||
|
||||
if (!isnull)
|
||||
{
|
||||
Assert(VARSIZE(tmptext) - VARHDRSZ < MAXPGPATH);
|
||||
/* oid of the database */
|
||||
if (dbIdP)
|
||||
*dbIdP = tuple->t_data->t_oid;
|
||||
/* uid of the owner */
|
||||
if (ownerIdP)
|
||||
{
|
||||
*ownerIdP = (int4) heap_getattr(tuple,
|
||||
Anum_pg_database_datdba,
|
||||
RelationGetDescr(relation),
|
||||
&isnull);
|
||||
if (isnull)
|
||||
*ownerIdP = -1; /* hopefully no one has that id already ;) */
|
||||
}
|
||||
/* database path (as registered in pg_database) */
|
||||
if (dbpath)
|
||||
{
|
||||
tmptext = (text *) heap_getattr(tuple,
|
||||
Anum_pg_database_datpath,
|
||||
RelationGetDescr(relation),
|
||||
&isnull);
|
||||
|
||||
strncpy(dbpath, VARDATA(tmptext), VARSIZE(tmptext) - VARHDRSZ);
|
||||
*(dbpath + VARSIZE(tmptext) - VARHDRSZ) = '\0';
|
||||
}
|
||||
else
|
||||
strcpy(dbpath, "");
|
||||
}
|
||||
if (!isnull)
|
||||
{
|
||||
Assert(VARSIZE(tmptext) - VARHDRSZ < MAXPGPATH);
|
||||
|
||||
strncpy(dbpath, VARDATA(tmptext), VARSIZE(tmptext) - VARHDRSZ);
|
||||
*(dbpath + VARSIZE(tmptext) - VARHDRSZ) = '\0';
|
||||
}
|
||||
else
|
||||
strcpy(dbpath, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dbIdP)
|
||||
*dbIdP = InvalidOid;
|
||||
}
|
||||
{
|
||||
if (dbIdP)
|
||||
*dbIdP = InvalidOid;
|
||||
}
|
||||
|
||||
heap_endscan(scan);
|
||||
|
||||
/* We will keep the lock on the relation until end of transaction. */
|
||||
heap_close(relation, NoLock);
|
||||
|
||||
return HeapTupleIsValid(tuple);
|
||||
return HeapTupleIsValid(tuple);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool
|
||||
get_user_info(const char * name, int4 *use_sysid, bool *use_super, bool *use_createdb)
|
||||
get_user_info(const char *name, int4 *use_sysid, bool *use_super, bool *use_createdb)
|
||||
{
|
||||
HeapTuple utup;
|
||||
HeapTuple utup;
|
||||
|
||||
AssertArg(name);
|
||||
utup = SearchSysCacheTuple(SHADOWNAME,
|
||||
PointerGetDatum(name),
|
||||
0, 0, 0);
|
||||
|
||||
if (!HeapTupleIsValid(utup))
|
||||
return false;
|
||||
if (!HeapTupleIsValid(utup))
|
||||
return false;
|
||||
|
||||
if (use_sysid)
|
||||
*use_sysid = ((Form_pg_shadow) GETSTRUCT(utup))->usesysid;
|
||||
if (use_super)
|
||||
*use_super = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
|
||||
if (use_createdb)
|
||||
*use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb;
|
||||
if (use_sysid)
|
||||
*use_sysid = ((Form_pg_shadow) GETSTRUCT(utup))->usesysid;
|
||||
if (use_super)
|
||||
*use_super = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
|
||||
if (use_createdb)
|
||||
*use_createdb = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.39 2000/04/07 13:39:24 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.40 2000/04/12 17:14:58 momjian Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@@ -137,12 +137,13 @@ compute_full_attributes(List *parameters, int32 *byte_pct_p,
|
||||
|
||||
foreach(pl, parameters)
|
||||
{
|
||||
DefElem *param = (DefElem *) lfirst(pl);
|
||||
DefElem *param = (DefElem *) lfirst(pl);
|
||||
|
||||
if (strcasecmp(param->defname, "iscachable") == 0)
|
||||
*canCache_p = true;
|
||||
else if (strcasecmp(param->defname, "trusted") == 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* we don't have untrusted functions any more. The 4.2
|
||||
* implementation is lousy anyway so I took it out. -ay 10/94
|
||||
@@ -233,12 +234,14 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
|
||||
*/
|
||||
|
||||
bool returnsSet;
|
||||
|
||||
/* The function returns a set of values, as opposed to a singleton. */
|
||||
|
||||
bool lanisPL = false;
|
||||
|
||||
/*
|
||||
* The following are optional user-supplied attributes of the function.
|
||||
* The following are optional user-supplied attributes of the
|
||||
* function.
|
||||
*/
|
||||
int32 byte_pct,
|
||||
perbyte_cpu,
|
||||
@@ -256,7 +259,7 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
|
||||
elog(ERROR,
|
||||
"Only users with Postgres superuser privilege are "
|
||||
"permitted to create a function "
|
||||
"in the '%s' language. Others may use the 'sql' language "
|
||||
"in the '%s' language. Others may use the 'sql' language "
|
||||
"or the created procedural languages.",
|
||||
languageName);
|
||||
}
|
||||
@@ -316,17 +319,17 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
|
||||
interpret_AS_clause(languageName, stmt->as, &prosrc_str, &probin_str);
|
||||
|
||||
/*
|
||||
* And now that we have all the parameters, and know we're
|
||||
* permitted to do so, go ahead and create the function.
|
||||
* And now that we have all the parameters, and know we're permitted
|
||||
* to do so, go ahead and create the function.
|
||||
*/
|
||||
ProcedureCreate(stmt->funcname,
|
||||
returnsSet,
|
||||
prorettype,
|
||||
languageName,
|
||||
prosrc_str, /* converted to text later */
|
||||
probin_str, /* converted to text later */
|
||||
prosrc_str, /* converted to text later */
|
||||
probin_str, /* converted to text later */
|
||||
canCache,
|
||||
true, /* (obsolete "trusted") */
|
||||
true, /* (obsolete "trusted") */
|
||||
byte_pct,
|
||||
perbyte_cpu,
|
||||
percall_cpu,
|
||||
@@ -378,7 +381,7 @@ DefineOperator(char *oprName,
|
||||
if (!strcasecmp(defel->defname, "leftarg"))
|
||||
{
|
||||
if ((nodeTag(defel->arg) == T_TypeName)
|
||||
&& (((TypeName *)defel->arg)->setof))
|
||||
&& (((TypeName *) defel->arg)->setof))
|
||||
elog(ERROR, "setof type not implemented for leftarg");
|
||||
|
||||
typeName1 = defGetString(defel);
|
||||
@@ -388,7 +391,7 @@ DefineOperator(char *oprName,
|
||||
else if (!strcasecmp(defel->defname, "rightarg"))
|
||||
{
|
||||
if ((nodeTag(defel->arg) == T_TypeName)
|
||||
&& (((TypeName *)defel->arg)->setof))
|
||||
&& (((TypeName *) defel->arg)->setof))
|
||||
elog(ERROR, "setof type not implemented for rightarg");
|
||||
|
||||
typeName2 = defGetString(defel);
|
||||
@@ -698,16 +701,16 @@ DefineType(char *typeName, List *parameters)
|
||||
static char *
|
||||
defGetString(DefElem *def)
|
||||
{
|
||||
char *string;
|
||||
char *string;
|
||||
|
||||
if (nodeTag(def->arg) == T_String)
|
||||
string = strVal(def->arg);
|
||||
else if (nodeTag(def->arg) == T_TypeName)
|
||||
string = ((TypeName *)def->arg)->name;
|
||||
string = ((TypeName *) def->arg)->name;
|
||||
else
|
||||
string = NULL;
|
||||
#if 0
|
||||
elog(ERROR, "Define: \"%s\" = what?", def->defname);
|
||||
elog(ERROR, "Define: \"%s\" = what?", def->defname);
|
||||
#endif
|
||||
|
||||
return string;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.55 2000/03/14 23:06:12 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.56 2000/04/12 17:14:58 momjian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -209,7 +209,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
|
||||
switch (nodeTag(plan))
|
||||
{
|
||||
case T_IndexScan:
|
||||
if (ScanDirectionIsBackward(((IndexScan *)plan)->indxorderdir))
|
||||
if (ScanDirectionIsBackward(((IndexScan *) plan)->indxorderdir))
|
||||
appendStringInfo(str, " Backward");
|
||||
appendStringInfo(str, " using ");
|
||||
i = 0;
|
||||
@@ -219,7 +219,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
|
||||
Assert(relation);
|
||||
appendStringInfo(str, "%s%s",
|
||||
(++i > 1) ? ", " : "",
|
||||
stringStringInfo(RelationGetRelationName(relation)));
|
||||
stringStringInfo(RelationGetRelationName(relation)));
|
||||
/* drop relcache refcount from RelationIdGetRelation */
|
||||
RelationDecrementReferenceCount(relation);
|
||||
}
|
||||
@@ -238,17 +238,17 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es)
|
||||
|| (length(rte->ref->attrs) > 0))
|
||||
{
|
||||
appendStringInfo(str, " %s",
|
||||
stringStringInfo(rte->ref->relname));
|
||||
stringStringInfo(rte->ref->relname));
|
||||
|
||||
if (length(rte->ref->attrs) > 0)
|
||||
{
|
||||
List *c;
|
||||
int firstEntry = true;
|
||||
List *c;
|
||||
int firstEntry = true;
|
||||
|
||||
appendStringInfo(str, " (");
|
||||
foreach (c, rte->ref->attrs)
|
||||
foreach(c, rte->ref->attrs)
|
||||
{
|
||||
if (! firstEntry)
|
||||
if (!firstEntry)
|
||||
{
|
||||
appendStringInfo(str, ", ");
|
||||
firstEntry = false;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.22 2000/02/25 02:58:48 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.23 2000/04/12 17:14:58 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -34,9 +34,9 @@
|
||||
#include "parser/parse_func.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "miscadmin.h" /* ReindexDatabase() */
|
||||
#include "utils/portal.h" /* ReindexDatabase() */
|
||||
#include "catalog/catalog.h" /* ReindexDatabase() */
|
||||
#include "miscadmin.h" /* ReindexDatabase() */
|
||||
#include "utils/portal.h" /* ReindexDatabase() */
|
||||
#include "catalog/catalog.h" /* ReindexDatabase() */
|
||||
|
||||
#define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL)
|
||||
|
||||
@@ -45,11 +45,11 @@ static void CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid);
|
||||
static void CheckPredExpr(Node *predicate, List *rangeTable, Oid baseRelOid);
|
||||
static void CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid);
|
||||
static void FuncIndexArgs(IndexElem *funcIndex, FuncIndexInfo *funcInfo,
|
||||
AttrNumber *attNumP, Oid *opOidP, Oid relId);
|
||||
AttrNumber *attNumP, Oid *opOidP, Oid relId);
|
||||
static void NormIndexAttrs(List *attList, AttrNumber *attNumP,
|
||||
Oid *opOidP, Oid relId);
|
||||
Oid *opOidP, Oid relId);
|
||||
static void ProcessAttrTypename(IndexElem *attribute,
|
||||
Oid defType, int32 defTypmod);
|
||||
Oid defType, int32 defTypmod);
|
||||
static Oid GetAttrOpClass(IndexElem *attribute, Oid attrType);
|
||||
static char *GetDefaultOpClass(Oid atttypid);
|
||||
|
||||
@@ -133,7 +133,7 @@ DefineIndex(char *heapRelationName,
|
||||
*/
|
||||
foreach(pl, parameterList)
|
||||
{
|
||||
DefElem *param = (DefElem *) lfirst(pl);
|
||||
DefElem *param = (DefElem *) lfirst(pl);
|
||||
|
||||
if (!strcasecmp(param->defname, "islossy"))
|
||||
lossy = TRUE;
|
||||
@@ -174,7 +174,7 @@ DefineIndex(char *heapRelationName,
|
||||
namestrcpy(&fInfo.funcName, funcIndex->name);
|
||||
|
||||
attributeNumberA = (AttrNumber *) palloc(nargs *
|
||||
sizeof attributeNumberA[0]);
|
||||
sizeof attributeNumberA[0]);
|
||||
|
||||
classObjectId = (Oid *) palloc(sizeof(Oid));
|
||||
|
||||
@@ -192,7 +192,7 @@ DefineIndex(char *heapRelationName,
|
||||
else
|
||||
{
|
||||
attributeNumberA = (AttrNumber *) palloc(numberOfAttributes *
|
||||
sizeof attributeNumberA[0]);
|
||||
sizeof attributeNumberA[0]);
|
||||
|
||||
classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
|
||||
|
||||
@@ -490,7 +490,7 @@ NormIndexAttrs(List *attList, /* list of IndexElem's */
|
||||
|
||||
atttuple = SearchSysCacheTupleCopy(ATTNAME,
|
||||
ObjectIdGetDatum(relId),
|
||||
PointerGetDatum(attribute->name),
|
||||
PointerGetDatum(attribute->name),
|
||||
0, 0);
|
||||
if (!HeapTupleIsValid(atttuple))
|
||||
elog(ERROR, "DefineIndex: attribute \"%s\" not found",
|
||||
@@ -608,7 +608,7 @@ RemoveIndex(char *name)
|
||||
* ...
|
||||
*/
|
||||
void
|
||||
ReindexIndex(const char *name, bool force /* currently unused */)
|
||||
ReindexIndex(const char *name, bool force /* currently unused */ )
|
||||
{
|
||||
HeapTuple tuple;
|
||||
|
||||
@@ -667,28 +667,35 @@ ReindexTable(const char *name, bool force)
|
||||
* "ERROR" if table nonexistent.
|
||||
* ...
|
||||
*/
|
||||
extern Oid MyDatabaseId;
|
||||
extern Oid MyDatabaseId;
|
||||
void
|
||||
ReindexDatabase(const char *dbname, bool force, bool all)
|
||||
{
|
||||
Relation relation, relationRelation;
|
||||
HeapTuple usertuple, dbtuple, tuple;
|
||||
HeapScanDesc scan;
|
||||
int4 user_id, db_owner;
|
||||
Relation relation,
|
||||
relationRelation;
|
||||
HeapTuple usertuple,
|
||||
dbtuple,
|
||||
tuple;
|
||||
HeapScanDesc scan;
|
||||
int4 user_id,
|
||||
db_owner;
|
||||
bool superuser;
|
||||
Oid db_id;
|
||||
char *username;
|
||||
ScanKeyData scankey;
|
||||
PortalVariableMemory pmem;
|
||||
MemoryContext old;
|
||||
int relcnt, relalc, i, oncealc = 200;
|
||||
Oid *relids = (Oid *) NULL;
|
||||
Oid db_id;
|
||||
char *username;
|
||||
ScanKeyData scankey;
|
||||
PortalVariableMemory pmem;
|
||||
MemoryContext old;
|
||||
int relcnt,
|
||||
relalc,
|
||||
i,
|
||||
oncealc = 200;
|
||||
Oid *relids = (Oid *) NULL;
|
||||
|
||||
AssertArg(dbname);
|
||||
|
||||
username = GetPgUserName();
|
||||
usertuple = SearchSysCacheTuple(SHADOWNAME, PointerGetDatum(username),
|
||||
0, 0, 0);
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(usertuple))
|
||||
elog(ERROR, "Current user '%s' is invalid.", username);
|
||||
user_id = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesysid;
|
||||
@@ -696,7 +703,7 @@ ReindexDatabase(const char *dbname, bool force, bool all)
|
||||
|
||||
relation = heap_openr(DatabaseRelationName, AccessShareLock);
|
||||
ScanKeyEntryInitialize(&scankey, 0, Anum_pg_database_datname,
|
||||
F_NAMEEQ, NameGetDatum(dbname));
|
||||
F_NAMEEQ, NameGetDatum(dbname));
|
||||
scan = heap_beginscan(relation, 0, SnapshotNow, 1, &scankey);
|
||||
dbtuple = heap_getnext(scan, 0);
|
||||
if (!HeapTupleIsValid(dbtuple))
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.45 2000/01/26 05:56:13 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.46 2000/04/12 17:14:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -156,14 +156,15 @@ SingleOpOperatorRemove(Oid typeOid)
|
||||
{
|
||||
key[0].sk_attno = attnums[i];
|
||||
scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
|
||||
while (HeapTupleIsValid(tup = heap_getnext(scan, 0))) {
|
||||
while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
|
||||
{
|
||||
|
||||
/*** This is apparently a routine not in use, but remove ***/
|
||||
/*** any comments anyways ***/
|
||||
/*** This is apparently a routine not in use, but remove ***/
|
||||
/*** any comments anyways ***/
|
||||
|
||||
DeleteComments(tup->t_data->t_oid);
|
||||
DeleteComments(tup->t_data->t_oid);
|
||||
|
||||
heap_delete(rel, &tup->t_self, NULL);
|
||||
heap_delete(rel, &tup->t_self, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.41 2000/01/26 05:56:13 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.42 2000/04/12 17:14:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -76,12 +76,12 @@ renameatt(char *relname,
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT release
|
||||
* until end of transaction.
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
targetrelation = heap_openr(relname, AccessExclusiveLock);
|
||||
relid = RelationGetRelid(targetrelation);
|
||||
heap_close(targetrelation, NoLock); /* close rel but keep lock! */
|
||||
heap_close(targetrelation, NoLock); /* close rel but keep lock! */
|
||||
|
||||
/*
|
||||
* if the 'recurse' flag is set then we are supposed to rename this
|
||||
@@ -160,11 +160,12 @@ renameatt(char *relname,
|
||||
/* keep system catalog indices current */
|
||||
{
|
||||
Relation irelations[Num_pg_attr_indices];
|
||||
|
||||
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations);
|
||||
CatalogIndexInsert(irelations, Num_pg_attr_indices, attrelation, oldatttup);
|
||||
CatalogCloseIndices(Num_pg_attr_indices, irelations);
|
||||
}
|
||||
|
||||
|
||||
heap_freetuple(oldatttup);
|
||||
heap_close(attrelation, RowExclusiveLock);
|
||||
}
|
||||
@@ -194,8 +195,8 @@ renamerel(const char *oldrelname, const char *newrelname)
|
||||
newrelname);
|
||||
|
||||
/*
|
||||
* Grab an exclusive lock on the target table, which we will NOT release
|
||||
* until end of transaction.
|
||||
* Grab an exclusive lock on the target table, which we will NOT
|
||||
* release until end of transaction.
|
||||
*/
|
||||
targetrelation = heap_openr(oldrelname, AccessExclusiveLock);
|
||||
|
||||
@@ -211,14 +212,15 @@ renamerel(const char *oldrelname, const char *newrelname)
|
||||
* they don't exist anyway. So, no warning in that case.
|
||||
* ----------------
|
||||
*/
|
||||
if (IsTransactionBlock() && ! targetrelation->rd_myxactonly)
|
||||
if (IsTransactionBlock() && !targetrelation->rd_myxactonly)
|
||||
elog(NOTICE, "Caution: RENAME TABLE cannot be rolled back, so don't abort now");
|
||||
|
||||
/*
|
||||
* Flush all blocks of the relation out of the buffer pool. We need this
|
||||
* because the blocks are marked with the relation's name as well as OID.
|
||||
* If some backend tries to write a dirty buffer with mdblindwrt after
|
||||
* we've renamed the physical file, we'll be in big trouble.
|
||||
* Flush all blocks of the relation out of the buffer pool. We need
|
||||
* this because the blocks are marked with the relation's name as well
|
||||
* as OID. If some backend tries to write a dirty buffer with
|
||||
* mdblindwrt after we've renamed the physical file, we'll be in big
|
||||
* trouble.
|
||||
*
|
||||
* Since we hold the exclusive lock on the relation, we don't have to
|
||||
* worry about more blocks being read in while we finish the rename.
|
||||
@@ -227,8 +229,8 @@ renamerel(const char *oldrelname, const char *newrelname)
|
||||
elog(ERROR, "renamerel: unable to flush relation from buffer pool");
|
||||
|
||||
/*
|
||||
* Make sure smgr and lower levels close the relation's files.
|
||||
* (Next access to rel will reopen them.)
|
||||
* Make sure smgr and lower levels close the relation's files. (Next
|
||||
* access to rel will reopen them.)
|
||||
*
|
||||
* Note: we rely on shared cache invalidation message to make other
|
||||
* backends close and re-open the files.
|
||||
@@ -238,14 +240,15 @@ renamerel(const char *oldrelname, const char *newrelname)
|
||||
/*
|
||||
* Close rel, but keep exclusive lock!
|
||||
*
|
||||
* Note: we don't do anything about updating the relcache entry;
|
||||
* we assume it will be flushed by shared cache invalidate.
|
||||
* XXX is this good enough? What if relation is myxactonly?
|
||||
* Note: we don't do anything about updating the relcache entry; we
|
||||
* assume it will be flushed by shared cache invalidate. XXX is this
|
||||
* good enough? What if relation is myxactonly?
|
||||
*/
|
||||
heap_close(targetrelation, NoLock);
|
||||
|
||||
/*
|
||||
* Find relation's pg_class tuple, and make sure newrelname isn't in use.
|
||||
* Find relation's pg_class tuple, and make sure newrelname isn't in
|
||||
* use.
|
||||
*/
|
||||
relrelation = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||
|
||||
@@ -262,8 +265,8 @@ renamerel(const char *oldrelname, const char *newrelname)
|
||||
* Perform physical rename of files. If this fails, we haven't yet
|
||||
* done anything irreversible.
|
||||
*
|
||||
* XXX smgr.c ought to provide an interface for this; doing it
|
||||
* directly is bletcherous.
|
||||
* XXX smgr.c ought to provide an interface for this; doing it directly
|
||||
* is bletcherous.
|
||||
*/
|
||||
strcpy(oldpath, relpath(oldrelname));
|
||||
strcpy(newpath, relpath(newrelname));
|
||||
|
||||
@@ -410,7 +410,9 @@ init_sequence(char *caller, char *name)
|
||||
|
||||
if (elm != (SeqTable) NULL)
|
||||
{
|
||||
/* We are using a seqtable entry left over from a previous xact;
|
||||
|
||||
/*
|
||||
* We are using a seqtable entry left over from a previous xact;
|
||||
* must check for relid change.
|
||||
*/
|
||||
elm->rel = seqrel;
|
||||
@@ -424,7 +426,9 @@ init_sequence(char *caller, char *name)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Time to make a new seqtable entry. These entries live as long
|
||||
|
||||
/*
|
||||
* Time to make a new seqtable entry. These entries live as long
|
||||
* as the backend does, so we use plain malloc for them.
|
||||
*/
|
||||
elm = (SeqTable) malloc(sizeof(SeqTableData));
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.62 2000/02/29 12:28:24 wieck Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.63 2000/04/12 17:14:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -89,7 +89,7 @@ CreateTrigger(CreateTrigStmt *stmt)
|
||||
rel = heap_openr(stmt->constrrelname, NoLock);
|
||||
if (rel == NULL)
|
||||
elog(ERROR, "table \"%s\" does not exist",
|
||||
stmt->constrrelname);
|
||||
stmt->constrrelname);
|
||||
constrrelid = rel->rd_id;
|
||||
heap_close(rel, NoLock);
|
||||
}
|
||||
@@ -182,12 +182,12 @@ CreateTrigger(CreateTrigStmt *stmt)
|
||||
values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(tuple->t_data->t_oid);
|
||||
values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype);
|
||||
|
||||
values[Anum_pg_trigger_tgenabled - 1] = true;
|
||||
values[Anum_pg_trigger_tgisconstraint - 1] = stmt->isconstraint;
|
||||
values[Anum_pg_trigger_tgconstrname - 1] = PointerGetDatum(constrname);;
|
||||
values[Anum_pg_trigger_tgconstrrelid - 1] = constrrelid;
|
||||
values[Anum_pg_trigger_tgdeferrable - 1] = stmt->deferrable;
|
||||
values[Anum_pg_trigger_tginitdeferred - 1] = stmt->initdeferred;
|
||||
values[Anum_pg_trigger_tgenabled - 1] = true;
|
||||
values[Anum_pg_trigger_tgisconstraint - 1] = stmt->isconstraint;
|
||||
values[Anum_pg_trigger_tgconstrname - 1] = PointerGetDatum(constrname);;
|
||||
values[Anum_pg_trigger_tgconstrrelid - 1] = constrrelid;
|
||||
values[Anum_pg_trigger_tgdeferrable - 1] = stmt->deferrable;
|
||||
values[Anum_pg_trigger_tginitdeferred - 1] = stmt->initdeferred;
|
||||
|
||||
if (stmt->args)
|
||||
{
|
||||
@@ -261,10 +261,11 @@ CreateTrigger(CreateTrigStmt *stmt)
|
||||
CatalogCloseIndices(Num_pg_class_indices, ridescs);
|
||||
heap_freetuple(tuple);
|
||||
heap_close(pgrel, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
* We used to try to update the rel's relcache entry here, but that's
|
||||
* fairly pointless since it will happen as a byproduct of the upcoming
|
||||
* CommandCounterIncrement...
|
||||
* fairly pointless since it will happen as a byproduct of the
|
||||
* upcoming CommandCounterIncrement...
|
||||
*/
|
||||
/* Keep lock on target rel until end of xact */
|
||||
heap_close(rel, NoLock);
|
||||
@@ -301,12 +302,12 @@ DropTrigger(DropTrigStmt *stmt)
|
||||
if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
|
||||
{
|
||||
|
||||
/*** Delete any comments associated with this trigger ***/
|
||||
/*** Delete any comments associated with this trigger ***/
|
||||
|
||||
DeleteComments(tuple->t_data->t_oid);
|
||||
DeleteComments(tuple->t_data->t_oid);
|
||||
|
||||
heap_delete(tgrel, &tuple->t_self, NULL);
|
||||
tgfound++;
|
||||
heap_delete(tgrel, &tuple->t_self, NULL);
|
||||
tgfound++;
|
||||
|
||||
}
|
||||
else
|
||||
@@ -337,10 +338,11 @@ DropTrigger(DropTrigStmt *stmt)
|
||||
CatalogCloseIndices(Num_pg_class_indices, ridescs);
|
||||
heap_freetuple(tuple);
|
||||
heap_close(pgrel, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
* We used to try to update the rel's relcache entry here, but that's
|
||||
* fairly pointless since it will happen as a byproduct of the upcoming
|
||||
* CommandCounterIncrement...
|
||||
* fairly pointless since it will happen as a byproduct of the
|
||||
* upcoming CommandCounterIncrement...
|
||||
*/
|
||||
/* Keep lock on target rel until end of xact */
|
||||
heap_close(rel, NoLock);
|
||||
@@ -360,13 +362,14 @@ RelationRemoveTriggers(Relation rel)
|
||||
|
||||
tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &key);
|
||||
|
||||
while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0))) {
|
||||
while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0)))
|
||||
{
|
||||
|
||||
/*** Delete any comments associated with this trigger ***/
|
||||
/*** Delete any comments associated with this trigger ***/
|
||||
|
||||
DeleteComments(tup->t_data->t_oid);
|
||||
DeleteComments(tup->t_data->t_oid);
|
||||
|
||||
heap_delete(tgrel, &tup->t_self, NULL);
|
||||
heap_delete(tgrel, &tup->t_self, NULL);
|
||||
|
||||
}
|
||||
|
||||
@@ -385,14 +388,14 @@ RelationRemoveTriggers(Relation rel)
|
||||
* ----------
|
||||
*/
|
||||
ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgconstrrelid,
|
||||
F_OIDEQ, RelationGetRelid(rel));
|
||||
F_OIDEQ, RelationGetRelid(rel));
|
||||
|
||||
tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &key);
|
||||
while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0)))
|
||||
{
|
||||
Form_pg_trigger pg_trigger;
|
||||
Relation refrel;
|
||||
DropTrigStmt stmt;
|
||||
Form_pg_trigger pg_trigger;
|
||||
Relation refrel;
|
||||
DropTrigStmt stmt;
|
||||
|
||||
pg_trigger = (Form_pg_trigger) GETSTRUCT(tup);
|
||||
|
||||
@@ -436,8 +439,8 @@ RelationBuildTriggers(Relation relation)
|
||||
Relation irel = (Relation) NULL;
|
||||
ScanKeyData skey;
|
||||
HeapTupleData tuple;
|
||||
IndexScanDesc sd = (IndexScanDesc) NULL;
|
||||
HeapScanDesc tgscan = (HeapScanDesc) NULL;
|
||||
IndexScanDesc sd = (IndexScanDesc) NULL;
|
||||
HeapScanDesc tgscan = (HeapScanDesc) NULL;
|
||||
HeapTuple htup;
|
||||
RetrieveIndexResult indexRes;
|
||||
Buffer buffer;
|
||||
@@ -684,13 +687,13 @@ FreeTriggerDesc(TriggerDesc *trigdesc)
|
||||
bool
|
||||
equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
|
||||
{
|
||||
int i,
|
||||
j;
|
||||
int i,
|
||||
j;
|
||||
|
||||
/*
|
||||
* We need not examine the "index" data, just the trigger array itself;
|
||||
* if we have the same triggers with the same types, the derived index
|
||||
* data should match.
|
||||
* We need not examine the "index" data, just the trigger array
|
||||
* itself; if we have the same triggers with the same types, the
|
||||
* derived index data should match.
|
||||
*
|
||||
* XXX It seems possible that the same triggers could appear in different
|
||||
* orders in the two trigger arrays; do we need to handle that?
|
||||
@@ -703,8 +706,8 @@ equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
|
||||
return false;
|
||||
for (i = 0; i < trigdesc1->numtriggers; i++)
|
||||
{
|
||||
Trigger *trig1 = trigdesc1->triggers + i;
|
||||
Trigger *trig2 = NULL;
|
||||
Trigger *trig1 = trigdesc1->triggers + i;
|
||||
Trigger *trig2 = NULL;
|
||||
|
||||
/*
|
||||
* We can't assume that the triggers are always read from
|
||||
@@ -1014,31 +1017,31 @@ ltrmark:;
|
||||
* end.
|
||||
* ----------
|
||||
*/
|
||||
static GlobalMemory deftrig_gcxt = NULL;
|
||||
static GlobalMemory deftrig_cxt = NULL;
|
||||
static GlobalMemory deftrig_gcxt = NULL;
|
||||
static GlobalMemory deftrig_cxt = NULL;
|
||||
|
||||
/* ----------
|
||||
* Global data that tells which triggers are actually in
|
||||
* state IMMEDIATE or DEFERRED.
|
||||
* ----------
|
||||
*/
|
||||
static bool deftrig_dfl_all_isset = false;
|
||||
static bool deftrig_dfl_all_isdeferred = false;
|
||||
static List *deftrig_dfl_trigstates = NIL;
|
||||
static bool deftrig_dfl_all_isset = false;
|
||||
static bool deftrig_dfl_all_isdeferred = false;
|
||||
static List *deftrig_dfl_trigstates = NIL;
|
||||
|
||||
static bool deftrig_all_isset;
|
||||
static bool deftrig_all_isdeferred;
|
||||
static List *deftrig_trigstates;
|
||||
static bool deftrig_all_isset;
|
||||
static bool deftrig_all_isdeferred;
|
||||
static List *deftrig_trigstates;
|
||||
|
||||
/* ----------
|
||||
* The list of events during the entire transaction.
|
||||
*
|
||||
* XXX This must finally be held in a file because of the huge
|
||||
* number of events that could occur in the real world.
|
||||
* number of events that could occur in the real world.
|
||||
* ----------
|
||||
*/
|
||||
static int deftrig_n_events;
|
||||
static List *deftrig_events;
|
||||
static int deftrig_n_events;
|
||||
static List *deftrig_events;
|
||||
|
||||
|
||||
/* ----------
|
||||
@@ -1051,9 +1054,9 @@ static List *deftrig_events;
|
||||
static bool
|
||||
deferredTriggerCheckState(Oid tgoid, int32 itemstate)
|
||||
{
|
||||
MemoryContext oldcxt;
|
||||
List *sl;
|
||||
DeferredTriggerStatus trigstate;
|
||||
MemoryContext oldcxt;
|
||||
List *sl;
|
||||
DeferredTriggerStatus trigstate;
|
||||
|
||||
/* ----------
|
||||
* Not deferrable triggers (i.e. normal AFTER ROW triggers
|
||||
@@ -1068,7 +1071,7 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate)
|
||||
* Lookup if we know an individual state for this trigger
|
||||
* ----------
|
||||
*/
|
||||
foreach (sl, deftrig_trigstates)
|
||||
foreach(sl, deftrig_trigstates)
|
||||
{
|
||||
trigstate = (DeferredTriggerStatus) lfirst(sl);
|
||||
if (trigstate->dts_tgoid == tgoid)
|
||||
@@ -1092,10 +1095,10 @@ deferredTriggerCheckState(Oid tgoid, int32 itemstate)
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_cxt);
|
||||
|
||||
trigstate = (DeferredTriggerStatus)
|
||||
palloc(sizeof(DeferredTriggerStatusData));
|
||||
trigstate->dts_tgoid = tgoid;
|
||||
trigstate->dts_tgisdeferred =
|
||||
((itemstate & TRIGGER_DEFERRED_INITDEFERRED) != 0);
|
||||
palloc(sizeof(DeferredTriggerStatusData));
|
||||
trigstate->dts_tgoid = tgoid;
|
||||
trigstate->dts_tgisdeferred =
|
||||
((itemstate & TRIGGER_DEFERRED_INITDEFERRED) != 0);
|
||||
deftrig_trigstates = lappend(deftrig_trigstates, trigstate);
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
@@ -1130,8 +1133,8 @@ deferredTriggerAddEvent(DeferredTriggerEvent event)
|
||||
static DeferredTriggerEvent
|
||||
deferredTriggerGetPreviousEvent(Oid relid, ItemPointer ctid)
|
||||
{
|
||||
DeferredTriggerEvent previous;
|
||||
int n;
|
||||
DeferredTriggerEvent previous;
|
||||
int n;
|
||||
|
||||
for (n = deftrig_n_events - 1; n >= 0; n--)
|
||||
{
|
||||
@@ -1143,15 +1146,15 @@ deferredTriggerGetPreviousEvent(Oid relid, ItemPointer ctid)
|
||||
continue;
|
||||
|
||||
if (ItemPointerGetBlockNumber(ctid) ==
|
||||
ItemPointerGetBlockNumber(&(previous->dte_newctid)) &&
|
||||
ItemPointerGetOffsetNumber(ctid) ==
|
||||
ItemPointerGetOffsetNumber(&(previous->dte_newctid)))
|
||||
ItemPointerGetBlockNumber(&(previous->dte_newctid)) &&
|
||||
ItemPointerGetOffsetNumber(ctid) ==
|
||||
ItemPointerGetOffsetNumber(&(previous->dte_newctid)))
|
||||
return previous;
|
||||
}
|
||||
|
||||
elog(ERROR,
|
||||
"deferredTriggerGetPreviousEvent(): event for tuple %s not found",
|
||||
tidout(ctid));
|
||||
"deferredTriggerGetPreviousEvent(): event for tuple %s not found",
|
||||
tidout(ctid));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1166,13 +1169,13 @@ deferredTriggerGetPreviousEvent(Oid relid, ItemPointer ctid)
|
||||
static void
|
||||
deferredTriggerExecute(DeferredTriggerEvent event, int itemno)
|
||||
{
|
||||
Relation rel;
|
||||
TriggerData SaveTriggerData;
|
||||
HeapTupleData oldtuple;
|
||||
HeapTupleData newtuple;
|
||||
HeapTuple rettuple;
|
||||
Buffer oldbuffer;
|
||||
Buffer newbuffer;
|
||||
Relation rel;
|
||||
TriggerData SaveTriggerData;
|
||||
HeapTupleData oldtuple;
|
||||
HeapTupleData newtuple;
|
||||
HeapTuple rettuple;
|
||||
Buffer oldbuffer;
|
||||
Buffer newbuffer;
|
||||
|
||||
/* ----------
|
||||
* Open the heap and fetch the required OLD and NEW tuples.
|
||||
@@ -1200,31 +1203,31 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno)
|
||||
* Setup the trigger information
|
||||
* ----------
|
||||
*/
|
||||
SaveTriggerData.tg_event = (event->dte_event & TRIGGER_EVENT_OPMASK) |
|
||||
TRIGGER_EVENT_ROW;
|
||||
SaveTriggerData.tg_event = (event->dte_event & TRIGGER_EVENT_OPMASK) |
|
||||
TRIGGER_EVENT_ROW;
|
||||
SaveTriggerData.tg_relation = rel;
|
||||
|
||||
switch (event->dte_event & TRIGGER_EVENT_OPMASK)
|
||||
{
|
||||
case TRIGGER_EVENT_INSERT:
|
||||
SaveTriggerData.tg_trigtuple = &newtuple;
|
||||
SaveTriggerData.tg_newtuple = NULL;
|
||||
SaveTriggerData.tg_trigger =
|
||||
rel->trigdesc->tg_after_row[TRIGGER_EVENT_INSERT][itemno];
|
||||
SaveTriggerData.tg_newtuple = NULL;
|
||||
SaveTriggerData.tg_trigger =
|
||||
rel->trigdesc->tg_after_row[TRIGGER_EVENT_INSERT][itemno];
|
||||
break;
|
||||
|
||||
case TRIGGER_EVENT_UPDATE:
|
||||
SaveTriggerData.tg_trigtuple = &oldtuple;
|
||||
SaveTriggerData.tg_newtuple = &newtuple;
|
||||
SaveTriggerData.tg_trigger =
|
||||
rel->trigdesc->tg_after_row[TRIGGER_EVENT_UPDATE][itemno];
|
||||
SaveTriggerData.tg_newtuple = &newtuple;
|
||||
SaveTriggerData.tg_trigger =
|
||||
rel->trigdesc->tg_after_row[TRIGGER_EVENT_UPDATE][itemno];
|
||||
break;
|
||||
|
||||
case TRIGGER_EVENT_DELETE:
|
||||
SaveTriggerData.tg_trigtuple = &oldtuple;
|
||||
SaveTriggerData.tg_newtuple = NULL;
|
||||
SaveTriggerData.tg_trigger =
|
||||
rel->trigdesc->tg_after_row[TRIGGER_EVENT_DELETE][itemno];
|
||||
SaveTriggerData.tg_newtuple = NULL;
|
||||
SaveTriggerData.tg_trigger =
|
||||
rel->trigdesc->tg_after_row[TRIGGER_EVENT_DELETE][itemno];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1271,11 +1274,11 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno)
|
||||
static void
|
||||
deferredTriggerInvokeEvents(bool immediate_only)
|
||||
{
|
||||
List *el;
|
||||
DeferredTriggerEvent event;
|
||||
int still_deferred_ones;
|
||||
int eventno = -1;
|
||||
int i;
|
||||
List *el;
|
||||
DeferredTriggerEvent event;
|
||||
int still_deferred_ones;
|
||||
int eventno = -1;
|
||||
int i;
|
||||
|
||||
/* ----------
|
||||
* For now we process all events - to speedup transaction blocks
|
||||
@@ -1286,7 +1289,7 @@ deferredTriggerInvokeEvents(bool immediate_only)
|
||||
* SET CONSTRAINTS ... command finishes and calls EndQuery.
|
||||
* ----------
|
||||
*/
|
||||
foreach (el, deftrig_events)
|
||||
foreach(el, deftrig_events)
|
||||
{
|
||||
eventno++;
|
||||
|
||||
@@ -1315,8 +1318,8 @@ deferredTriggerInvokeEvents(bool immediate_only)
|
||||
* ----------
|
||||
*/
|
||||
if (immediate_only && deferredTriggerCheckState(
|
||||
event->dte_item[i].dti_tgoid,
|
||||
event->dte_item[i].dti_state))
|
||||
event->dte_item[i].dti_tgoid,
|
||||
event->dte_item[i].dti_state))
|
||||
{
|
||||
still_deferred_ones = true;
|
||||
continue;
|
||||
@@ -1367,34 +1370,34 @@ DeferredTriggerInit(void)
|
||||
void
|
||||
DeferredTriggerBeginXact(void)
|
||||
{
|
||||
MemoryContext oldcxt;
|
||||
List *l;
|
||||
DeferredTriggerStatus dflstat;
|
||||
DeferredTriggerStatus stat;
|
||||
MemoryContext oldcxt;
|
||||
List *l;
|
||||
DeferredTriggerStatus dflstat;
|
||||
DeferredTriggerStatus stat;
|
||||
|
||||
if (deftrig_cxt != NULL)
|
||||
elog(FATAL,
|
||||
"DeferredTriggerBeginXact() called while inside transaction");
|
||||
"DeferredTriggerBeginXact() called while inside transaction");
|
||||
|
||||
/* ----------
|
||||
* Create the per transaction memory context and copy all states
|
||||
* from the per session context to here.
|
||||
* ----------
|
||||
*/
|
||||
deftrig_cxt = CreateGlobalMemory("DeferredTriggerXact");
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext)deftrig_cxt);
|
||||
deftrig_cxt = CreateGlobalMemory("DeferredTriggerXact");
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_cxt);
|
||||
|
||||
deftrig_all_isset = deftrig_dfl_all_isset;
|
||||
deftrig_all_isdeferred = deftrig_dfl_all_isdeferred;
|
||||
deftrig_all_isset = deftrig_dfl_all_isset;
|
||||
deftrig_all_isdeferred = deftrig_dfl_all_isdeferred;
|
||||
|
||||
deftrig_trigstates = NIL;
|
||||
foreach (l, deftrig_dfl_trigstates)
|
||||
deftrig_trigstates = NIL;
|
||||
foreach(l, deftrig_dfl_trigstates)
|
||||
{
|
||||
dflstat = (DeferredTriggerStatus) lfirst(l);
|
||||
stat = (DeferredTriggerStatus)
|
||||
palloc(sizeof(DeferredTriggerStatusData));
|
||||
stat = (DeferredTriggerStatus)
|
||||
palloc(sizeof(DeferredTriggerStatusData));
|
||||
|
||||
stat->dts_tgoid = dflstat->dts_tgoid;
|
||||
stat->dts_tgoid = dflstat->dts_tgoid;
|
||||
stat->dts_tgisdeferred = dflstat->dts_tgisdeferred;
|
||||
|
||||
deftrig_trigstates = lappend(deftrig_trigstates, stat);
|
||||
@@ -1402,8 +1405,8 @@ DeferredTriggerBeginXact(void)
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
deftrig_n_events = 0;
|
||||
deftrig_events = NIL;
|
||||
deftrig_n_events = 0;
|
||||
deftrig_events = NIL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1484,22 +1487,23 @@ DeferredTriggerAbortXact(void)
|
||||
void
|
||||
DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
{
|
||||
Relation tgrel;
|
||||
Relation irel = (Relation) NULL;
|
||||
List *l;
|
||||
List *ls;
|
||||
List *lnext;
|
||||
List *loid = NIL;
|
||||
MemoryContext oldcxt;
|
||||
bool found;
|
||||
DeferredTriggerStatus state;
|
||||
bool hasindex;
|
||||
Relation tgrel;
|
||||
Relation irel = (Relation) NULL;
|
||||
List *l;
|
||||
List *ls;
|
||||
List *lnext;
|
||||
List *loid = NIL;
|
||||
MemoryContext oldcxt;
|
||||
bool found;
|
||||
DeferredTriggerStatus state;
|
||||
bool hasindex;
|
||||
|
||||
/* ----------
|
||||
* Handle SET CONSTRAINTS ALL ...
|
||||
* ----------
|
||||
*/
|
||||
if (stmt->constraints == NIL) {
|
||||
if (stmt->constraints == NIL)
|
||||
{
|
||||
if (!IsTransactionBlock())
|
||||
{
|
||||
/* ----------
|
||||
@@ -1527,13 +1531,15 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
* Set the session ALL state to known.
|
||||
* ----------
|
||||
*/
|
||||
deftrig_dfl_all_isset = true;
|
||||
deftrig_dfl_all_isset = true;
|
||||
deftrig_dfl_all_isdeferred = stmt->deferred;
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------
|
||||
* ... inside of a transaction block
|
||||
* ----------
|
||||
@@ -1559,7 +1565,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
* Set the per transaction ALL state to known.
|
||||
* ----------
|
||||
*/
|
||||
deftrig_all_isset = true;
|
||||
deftrig_all_isset = true;
|
||||
deftrig_all_isdeferred = stmt->deferred;
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
@@ -1578,23 +1584,23 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
if (hasindex)
|
||||
irel = index_openr(TriggerConstrNameIndex);
|
||||
|
||||
foreach (l, stmt->constraints)
|
||||
foreach(l, stmt->constraints)
|
||||
{
|
||||
ScanKeyData skey;
|
||||
HeapTupleData tuple;
|
||||
IndexScanDesc sd = (IndexScanDesc) NULL;
|
||||
HeapScanDesc tgscan = (HeapScanDesc) NULL;
|
||||
HeapTuple htup;
|
||||
RetrieveIndexResult indexRes;
|
||||
Buffer buffer;
|
||||
Form_pg_trigger pg_trigger;
|
||||
Oid constr_oid;
|
||||
ScanKeyData skey;
|
||||
HeapTupleData tuple;
|
||||
IndexScanDesc sd = (IndexScanDesc) NULL;
|
||||
HeapScanDesc tgscan = (HeapScanDesc) NULL;
|
||||
HeapTuple htup;
|
||||
RetrieveIndexResult indexRes;
|
||||
Buffer buffer;
|
||||
Form_pg_trigger pg_trigger;
|
||||
Oid constr_oid;
|
||||
|
||||
/* ----------
|
||||
* Check that only named constraints are set explicitly
|
||||
* ----------
|
||||
*/
|
||||
if (strcmp((char *)lfirst(l), "") == 0)
|
||||
if (strcmp((char *) lfirst(l), "") == 0)
|
||||
elog(ERROR, "unnamed constraints cannot be set explicitly");
|
||||
|
||||
/* ----------
|
||||
@@ -1605,7 +1611,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
(bits16) 0x0,
|
||||
(AttrNumber) 1,
|
||||
(RegProcedure) F_NAMEEQ,
|
||||
PointerGetDatum((char *)lfirst(l)));
|
||||
PointerGetDatum((char *) lfirst(l)));
|
||||
|
||||
if (hasindex)
|
||||
sd = index_beginscan(irel, false, 1, &skey);
|
||||
@@ -1629,9 +1635,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
heap_fetch(tgrel, SnapshotNow, &tuple, &buffer);
|
||||
pfree(indexRes);
|
||||
if (!tuple.t_data)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
htup = &tuple;
|
||||
}
|
||||
else
|
||||
@@ -1649,13 +1653,13 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
*/
|
||||
pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
|
||||
if (stmt->deferred && !pg_trigger->tgdeferrable &&
|
||||
pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD &&
|
||||
pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL)
|
||||
pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD &&
|
||||
pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL)
|
||||
elog(ERROR, "Constraint '%s' is not deferrable",
|
||||
(char *)lfirst(l));
|
||||
(char *) lfirst(l));
|
||||
|
||||
constr_oid = htup->t_data->t_oid;
|
||||
loid = lappend(loid, (Node *)constr_oid);
|
||||
loid = lappend(loid, (Node *) constr_oid);
|
||||
found = true;
|
||||
|
||||
if (hasindex)
|
||||
@@ -1667,11 +1671,11 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
* ----------
|
||||
*/
|
||||
if (!found)
|
||||
elog(ERROR, "Constraint '%s' does not exist", (char *)lfirst(l));
|
||||
elog(ERROR, "Constraint '%s' does not exist", (char *) lfirst(l));
|
||||
|
||||
if (hasindex)
|
||||
index_endscan(sd);
|
||||
else
|
||||
else
|
||||
heap_endscan(tgscan);
|
||||
}
|
||||
if (hasindex)
|
||||
@@ -1688,10 +1692,10 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
*/
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_gcxt);
|
||||
|
||||
foreach (l, loid)
|
||||
foreach(l, loid)
|
||||
{
|
||||
found = false;
|
||||
foreach (ls, deftrig_dfl_trigstates)
|
||||
foreach(ls, deftrig_dfl_trigstates)
|
||||
{
|
||||
state = (DeferredTriggerStatus) lfirst(ls);
|
||||
if (state->dts_tgoid == (Oid) lfirst(l))
|
||||
@@ -1704,19 +1708,21 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
if (!found)
|
||||
{
|
||||
state = (DeferredTriggerStatus)
|
||||
palloc(sizeof(DeferredTriggerStatusData));
|
||||
state->dts_tgoid = (Oid) lfirst(l);
|
||||
palloc(sizeof(DeferredTriggerStatusData));
|
||||
state->dts_tgoid = (Oid) lfirst(l);
|
||||
state->dts_tgisdeferred = stmt->deferred;
|
||||
|
||||
deftrig_dfl_trigstates =
|
||||
lappend(deftrig_dfl_trigstates, state);
|
||||
lappend(deftrig_dfl_trigstates, state);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ----------
|
||||
* Inside of a transaction block set the trigger
|
||||
* states of individual triggers on transaction level.
|
||||
@@ -1724,10 +1730,10 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
*/
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_cxt);
|
||||
|
||||
foreach (l, loid)
|
||||
foreach(l, loid)
|
||||
{
|
||||
found = false;
|
||||
foreach (ls, deftrig_trigstates)
|
||||
foreach(ls, deftrig_trigstates)
|
||||
{
|
||||
state = (DeferredTriggerStatus) lfirst(ls);
|
||||
if (state->dts_tgoid == (Oid) lfirst(l))
|
||||
@@ -1740,12 +1746,12 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
if (!found)
|
||||
{
|
||||
state = (DeferredTriggerStatus)
|
||||
palloc(sizeof(DeferredTriggerStatusData));
|
||||
state->dts_tgoid = (Oid) lfirst(l);
|
||||
palloc(sizeof(DeferredTriggerStatusData));
|
||||
state->dts_tgoid = (Oid) lfirst(l);
|
||||
state->dts_tgisdeferred = stmt->deferred;
|
||||
|
||||
deftrig_trigstates =
|
||||
lappend(deftrig_trigstates, state);
|
||||
lappend(deftrig_trigstates, state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1764,33 +1770,33 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
|
||||
*/
|
||||
void
|
||||
DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
HeapTuple oldtup, HeapTuple newtup)
|
||||
HeapTuple oldtup, HeapTuple newtup)
|
||||
{
|
||||
MemoryContext oldcxt;
|
||||
DeferredTriggerEvent new_event;
|
||||
DeferredTriggerEvent prev_event;
|
||||
int new_size;
|
||||
int i;
|
||||
int ntriggers;
|
||||
Trigger **triggers;
|
||||
ItemPointerData oldctid;
|
||||
ItemPointerData newctid;
|
||||
TriggerData SaveTriggerData;
|
||||
MemoryContext oldcxt;
|
||||
DeferredTriggerEvent new_event;
|
||||
DeferredTriggerEvent prev_event;
|
||||
int new_size;
|
||||
int i;
|
||||
int ntriggers;
|
||||
Trigger **triggers;
|
||||
ItemPointerData oldctid;
|
||||
ItemPointerData newctid;
|
||||
TriggerData SaveTriggerData;
|
||||
|
||||
if (deftrig_cxt == NULL)
|
||||
elog(ERROR,
|
||||
"DeferredTriggerSaveEvent() called outside of transaction");
|
||||
"DeferredTriggerSaveEvent() called outside of transaction");
|
||||
|
||||
/* ----------
|
||||
* Check if we're interested in this row at all
|
||||
* ----------
|
||||
*/
|
||||
if (rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] == 0 &&
|
||||
rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] == 0 &&
|
||||
rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] == 0 &&
|
||||
rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] == 0 &&
|
||||
rel->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE] == 0 &&
|
||||
rel->trigdesc->n_before_row[TRIGGER_EVENT_DELETE] == 0)
|
||||
rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] == 0 &&
|
||||
rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] == 0 &&
|
||||
rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] == 0 &&
|
||||
rel->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE] == 0 &&
|
||||
rel->trigdesc->n_before_row[TRIGGER_EVENT_DELETE] == 0)
|
||||
return;
|
||||
|
||||
/* ----------
|
||||
@@ -1813,14 +1819,14 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
oldcxt = MemoryContextSwitchTo((MemoryContext) deftrig_cxt);
|
||||
|
||||
ntriggers = rel->trigdesc->n_after_row[event];
|
||||
triggers = rel->trigdesc->tg_after_row[event];
|
||||
triggers = rel->trigdesc->tg_after_row[event];
|
||||
|
||||
new_size = sizeof(DeferredTriggerEventData) +
|
||||
ntriggers * sizeof(DeferredTriggerEventItem);
|
||||
new_size = sizeof(DeferredTriggerEventData) +
|
||||
ntriggers * sizeof(DeferredTriggerEventItem);
|
||||
|
||||
new_event = (DeferredTriggerEvent) palloc(new_size);
|
||||
new_event->dte_event = event & TRIGGER_EVENT_OPMASK;
|
||||
new_event->dte_relid = rel->rd_id;
|
||||
new_event->dte_event = event & TRIGGER_EVENT_OPMASK;
|
||||
new_event->dte_relid = rel->rd_id;
|
||||
ItemPointerCopy(&oldctid, &(new_event->dte_oldctid));
|
||||
ItemPointerCopy(&newctid, &(new_event->dte_newctid));
|
||||
new_event->dte_n_items = ntriggers;
|
||||
@@ -1830,11 +1836,11 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
new_event->dte_item[i].dti_tgoid = triggers[i]->tgoid;
|
||||
new_event->dte_item[i].dti_state =
|
||||
((triggers[i]->tgdeferrable) ?
|
||||
TRIGGER_DEFERRED_DEFERRABLE : 0) |
|
||||
TRIGGER_DEFERRED_DEFERRABLE : 0) |
|
||||
((triggers[i]->tginitdeferred) ?
|
||||
TRIGGER_DEFERRED_INITDEFERRED : 0) |
|
||||
TRIGGER_DEFERRED_INITDEFERRED : 0) |
|
||||
((rel->trigdesc->n_before_row[event] > 0) ?
|
||||
TRIGGER_DEFERRED_HAS_BEFORE : 0);
|
||||
TRIGGER_DEFERRED_HAS_BEFORE : 0);
|
||||
}
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
@@ -1864,8 +1870,8 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
*/
|
||||
for (i = 0; i < ntriggers; i++)
|
||||
{
|
||||
bool is_ri_trigger;
|
||||
bool key_unchanged;
|
||||
bool is_ri_trigger;
|
||||
bool key_unchanged;
|
||||
|
||||
/* ----------
|
||||
* We are interested in RI_FKEY triggers only.
|
||||
@@ -1888,11 +1894,11 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
if (!is_ri_trigger)
|
||||
continue;
|
||||
|
||||
SaveTriggerData.tg_event = TRIGGER_EVENT_UPDATE;
|
||||
SaveTriggerData.tg_relation = rel;
|
||||
SaveTriggerData.tg_event = TRIGGER_EVENT_UPDATE;
|
||||
SaveTriggerData.tg_relation = rel;
|
||||
SaveTriggerData.tg_trigtuple = oldtup;
|
||||
SaveTriggerData.tg_newtuple = newtup;
|
||||
SaveTriggerData.tg_trigger = triggers[i];
|
||||
SaveTriggerData.tg_newtuple = newtup;
|
||||
SaveTriggerData.tg_trigger = triggers[i];
|
||||
|
||||
CurrentTriggerData = &SaveTriggerData;
|
||||
key_unchanged = RI_FKey_keyequal_upd();
|
||||
@@ -1911,7 +1917,7 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
if (prev_event)
|
||||
{
|
||||
if (prev_event->dte_event &
|
||||
TRIGGER_DEFERRED_ROW_INSERTED)
|
||||
TRIGGER_DEFERRED_ROW_INSERTED)
|
||||
{
|
||||
/* ----------
|
||||
* This is a row inserted during our transaction.
|
||||
@@ -1919,11 +1925,11 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
* ----------
|
||||
*/
|
||||
new_event->dte_event |=
|
||||
TRIGGER_DEFERRED_ROW_INSERTED;
|
||||
TRIGGER_DEFERRED_ROW_INSERTED;
|
||||
new_event->dte_event |=
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
new_event->dte_item[i].dti_state |=
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1934,12 +1940,12 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
* ----------
|
||||
*/
|
||||
if (prev_event->dte_item[i].dti_state &
|
||||
TRIGGER_DEFERRED_KEY_CHANGED)
|
||||
TRIGGER_DEFERRED_KEY_CHANGED)
|
||||
{
|
||||
new_event->dte_item[i].dti_state |=
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
new_event->dte_event |=
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1954,16 +1960,16 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
if (prev_event)
|
||||
{
|
||||
if (prev_event->dte_event &
|
||||
TRIGGER_DEFERRED_ROW_INSERTED)
|
||||
TRIGGER_DEFERRED_ROW_INSERTED)
|
||||
elog(ERROR, "triggered data change violation "
|
||||
"on relation \"%s\"",
|
||||
nameout(&(rel->rd_rel->relname)));
|
||||
"on relation \"%s\"",
|
||||
nameout(&(rel->rd_rel->relname)));
|
||||
|
||||
if (prev_event->dte_item[i].dti_state &
|
||||
TRIGGER_DEFERRED_KEY_CHANGED)
|
||||
TRIGGER_DEFERRED_KEY_CHANGED)
|
||||
elog(ERROR, "triggered data change violation "
|
||||
"on relation \"%s\"",
|
||||
nameout(&(rel->rd_rel->relname)));
|
||||
"on relation \"%s\"",
|
||||
nameout(&(rel->rd_rel->relname)));
|
||||
}
|
||||
|
||||
/* ----------
|
||||
@@ -1972,7 +1978,7 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
* ----------
|
||||
*/
|
||||
new_event->dte_item[i].dti_state |=
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
new_event->dte_event |= TRIGGER_DEFERRED_KEY_CHANGED;
|
||||
}
|
||||
}
|
||||
@@ -1996,8 +2002,8 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
prev_event = deferredTriggerGetPreviousEvent(rel->rd_id, &oldctid);
|
||||
if (prev_event->dte_event & TRIGGER_DEFERRED_KEY_CHANGED)
|
||||
elog(ERROR, "triggered data change violation "
|
||||
"on relation \"%s\"",
|
||||
nameout(&(rel->rd_rel->relname)));
|
||||
"on relation \"%s\"",
|
||||
nameout(&(rel->rd_rel->relname)));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2012,5 +2018,3 @@ DeferredTriggerSaveEvent(Relation rel, int event,
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.146 2000/04/06 18:12:07 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.147 2000/04/12 17:14:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -102,15 +102,17 @@ static char *vc_show_rusage(struct rusage * ru0);
|
||||
|
||||
/*
|
||||
* This routines handle a special cross-transaction portal.
|
||||
* However it is automatically closed in case of abort.
|
||||
* However it is automatically closed in case of abort.
|
||||
*/
|
||||
void CommonSpecialPortalOpen(void)
|
||||
void
|
||||
CommonSpecialPortalOpen(void)
|
||||
{
|
||||
char *pname;
|
||||
|
||||
|
||||
if (CommonSpecialPortalInUse)
|
||||
elog(ERROR, "CommonSpecialPortal is in use");
|
||||
|
||||
/*
|
||||
* Create a portal for safe memory across transactions. We need to
|
||||
* palloc the name space for it because our hash function expects the
|
||||
@@ -130,7 +132,8 @@ void CommonSpecialPortalOpen(void)
|
||||
CommonSpecialPortalInUse = true;
|
||||
}
|
||||
|
||||
void CommonSpecialPortalClose(void)
|
||||
void
|
||||
CommonSpecialPortalClose(void)
|
||||
{
|
||||
/* Clear flag first, to avoid recursion if PortalDrop elog's */
|
||||
CommonSpecialPortalInUse = false;
|
||||
@@ -141,16 +144,18 @@ void CommonSpecialPortalClose(void)
|
||||
PortalDrop(&vc_portal);
|
||||
}
|
||||
|
||||
PortalVariableMemory CommonSpecialPortalGetMemory(void)
|
||||
PortalVariableMemory
|
||||
CommonSpecialPortalGetMemory(void)
|
||||
{
|
||||
return PortalGetVariableMemory(vc_portal);
|
||||
}
|
||||
|
||||
bool CommonSpecialPortalIsOpen(void)
|
||||
bool
|
||||
CommonSpecialPortalIsOpen(void)
|
||||
{
|
||||
return CommonSpecialPortalInUse;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
|
||||
{
|
||||
@@ -208,9 +213,9 @@ vacuum(char *vacrel, bool verbose, bool analyze, List *va_spec)
|
||||
* Start up the vacuum cleaner.
|
||||
*
|
||||
* NOTE: since this commits the current transaction, the memory holding
|
||||
* any passed-in parameters gets freed here. We must have already copied
|
||||
* pass-by-reference parameters to safe storage. Don't make me fix this
|
||||
* again!
|
||||
* any passed-in parameters gets freed here. We must have already
|
||||
* copied pass-by-reference parameters to safe storage. Don't make me
|
||||
* fix this again!
|
||||
*/
|
||||
vc_init();
|
||||
|
||||
@@ -316,11 +321,12 @@ vc_getrels(NameData *VacRelP)
|
||||
|
||||
if (NameStr(*VacRelP))
|
||||
{
|
||||
|
||||
/*
|
||||
* we could use the cache here, but it is clearer to use scankeys
|
||||
* for both vacuum cases, bjm 2000/01/19
|
||||
*/
|
||||
char *nontemp_relname;
|
||||
char *nontemp_relname;
|
||||
|
||||
/* We must re-map temp table names bjm 2000-04-06 */
|
||||
if ((nontemp_relname =
|
||||
@@ -414,7 +420,7 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
|
||||
int32 nindices,
|
||||
i;
|
||||
VRelStats *vacrelstats;
|
||||
bool reindex = false;
|
||||
bool reindex = false;
|
||||
|
||||
StartTransactionCommand();
|
||||
|
||||
@@ -678,7 +684,7 @@ static void
|
||||
vc_scanheap(VRelStats *vacrelstats, Relation onerel,
|
||||
VPageList vacuum_pages, VPageList fraged_pages)
|
||||
{
|
||||
BlockNumber nblocks,
|
||||
BlockNumber nblocks,
|
||||
blkno;
|
||||
ItemId itemid;
|
||||
Buffer buf;
|
||||
@@ -1201,7 +1207,7 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||
last_vacuum_block = -1;
|
||||
}
|
||||
if (num_fraged_pages > 0 &&
|
||||
fraged_pages->vpl_pagedesc[num_fraged_pages - 1]->vpd_blkno ==
|
||||
fraged_pages->vpl_pagedesc[num_fraged_pages - 1]->vpd_blkno ==
|
||||
(BlockNumber) blkno)
|
||||
{
|
||||
/* page is in fraged_pages too; remove it */
|
||||
@@ -1456,8 +1462,8 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||
* we stop shrinking here. I could try to find
|
||||
* real parent row but want not to do it because
|
||||
* of real solution will be implemented anyway,
|
||||
* latter, and we are too close to 6.5 release.
|
||||
* - vadim 06/11/99
|
||||
* latter, and we are too close to 6.5 release. -
|
||||
* vadim 06/11/99
|
||||
*/
|
||||
if (Ptp.t_data->t_xmax != tp.t_data->t_xmin)
|
||||
{
|
||||
@@ -1539,20 +1545,23 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
|
||||
* to get t_infomask of inserted heap tuple !!!
|
||||
*/
|
||||
ToPage = BufferGetPage(cur_buffer);
|
||||
|
||||
/*
|
||||
* If this page was not used before - clean it.
|
||||
*
|
||||
* This path is different from the other callers of
|
||||
* vc_vacpage, because we have already incremented the
|
||||
* vpd's vpd_offsets_used field to account for the
|
||||
* tuple(s) we expect to move onto the page. Therefore
|
||||
* vc_vacpage's check for vpd_offsets_used == 0 is wrong.
|
||||
* But since that's a good debugging check for all other
|
||||
* callers, we work around it here rather than remove it.
|
||||
* tuple(s) we expect to move onto the page. Therefore
|
||||
* vc_vacpage's check for vpd_offsets_used == 0 is
|
||||
* wrong. But since that's a good debugging check for
|
||||
* all other callers, we work around it here rather
|
||||
* than remove it.
|
||||
*/
|
||||
if (!PageIsEmpty(ToPage) && vtmove[ti].cleanVpd)
|
||||
{
|
||||
int sv_offsets_used = destvpd->vpd_offsets_used;
|
||||
int sv_offsets_used = destvpd->vpd_offsets_used;
|
||||
|
||||
destvpd->vpd_offsets_used = 0;
|
||||
vc_vacpage(ToPage, destvpd);
|
||||
destvpd->vpd_offsets_used = sv_offsets_used;
|
||||
@@ -2267,7 +2276,7 @@ vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple tuple)
|
||||
#ifdef _DROP_COLUMN_HACK__
|
||||
if (COLUMN_IS_DROPPED(stats->attr))
|
||||
continue;
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
#endif /* _DROP_COLUMN_HACK__ */
|
||||
value = heap_getattr(tuple,
|
||||
stats->attr->attnum, tupDesc, &isnull);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.33 2000/04/07 13:39:24 thomas Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.34 2000/04/12 17:15:00 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -436,7 +436,7 @@ parse_geqo(char *value)
|
||||
|
||||
if (strcasecmp(tok, "on") == 0)
|
||||
{
|
||||
int new_geqo_rels = GEQO_RELS;
|
||||
int new_geqo_rels = GEQO_RELS;
|
||||
|
||||
if (val != NULL)
|
||||
{
|
||||
@@ -505,7 +505,7 @@ static bool
|
||||
show_effective_cache_size()
|
||||
{
|
||||
elog(NOTICE, "EFFECTIVE_CACHE_SIZE is %g (%dK pages)",
|
||||
effective_cache_size, BLCKSZ/1024);
|
||||
effective_cache_size, BLCKSZ / 1024);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -656,12 +656,12 @@ reset_cpu_operator_cost()
|
||||
* DATE_STYLE
|
||||
*
|
||||
* NOTE: set_default_datestyle() is called during backend startup to check
|
||||
* if the PGDATESTYLE environment variable is set. We want the env var
|
||||
* if the PGDATESTYLE environment variable is set. We want the env var
|
||||
* to determine the value that "RESET DateStyle" will reset to!
|
||||
*/
|
||||
|
||||
/* These get initialized from the "master" values in init/globals.c */
|
||||
static int DefaultDateStyle;
|
||||
static int DefaultDateStyle;
|
||||
static bool DefaultEuroDates;
|
||||
|
||||
static bool
|
||||
@@ -777,8 +777,9 @@ set_default_datestyle(void)
|
||||
{
|
||||
char *DBDate;
|
||||
|
||||
/* Initialize from compile-time defaults in init/globals.c.
|
||||
* NB: this is a necessary step; consider PGDATESTYLE="DEFAULT".
|
||||
/*
|
||||
* Initialize from compile-time defaults in init/globals.c. NB: this
|
||||
* is a necessary step; consider PGDATESTYLE="DEFAULT".
|
||||
*/
|
||||
DefaultDateStyle = DateStyle;
|
||||
DefaultEuroDates = EuroDates;
|
||||
@@ -788,9 +789,11 @@ set_default_datestyle(void)
|
||||
if (DBDate == NULL)
|
||||
return;
|
||||
|
||||
/* Make a modifiable copy --- overwriting the env var doesn't seem
|
||||
/*
|
||||
* Make a modifiable copy --- overwriting the env var doesn't seem
|
||||
* like a good idea, even though we currently won't look at it again.
|
||||
* Note that we cannot use palloc at this early stage of initialization.
|
||||
* Note that we cannot use palloc at this early stage of
|
||||
* initialization.
|
||||
*/
|
||||
DBDate = strdup(DBDate);
|
||||
|
||||
@@ -1041,9 +1044,8 @@ reset_XactIsoLevel()
|
||||
static bool
|
||||
parse_pg_options(char *value)
|
||||
{
|
||||
if (!superuser()) {
|
||||
if (!superuser())
|
||||
elog(ERROR, "Only users with superuser privilege can set pg_options");
|
||||
}
|
||||
if (value == NULL)
|
||||
read_pg_options(0);
|
||||
else
|
||||
@@ -1061,9 +1063,8 @@ show_pg_options(void)
|
||||
static bool
|
||||
reset_pg_options(void)
|
||||
{
|
||||
if (!superuser()) {
|
||||
if (!superuser())
|
||||
elog(ERROR, "Only users with superuser privilege can set pg_options");
|
||||
}
|
||||
read_pg_options(0);
|
||||
return (TRUE);
|
||||
}
|
||||
@@ -1075,7 +1076,7 @@ reset_pg_options(void)
|
||||
static bool
|
||||
parse_random_seed(char *value)
|
||||
{
|
||||
double seed = 0;
|
||||
double seed = 0;
|
||||
|
||||
if (value == NULL)
|
||||
reset_random_seed();
|
||||
@@ -1097,7 +1098,7 @@ show_random_seed(void)
|
||||
static bool
|
||||
reset_random_seed(void)
|
||||
{
|
||||
double seed = 0.5;
|
||||
double seed = 0.5;
|
||||
|
||||
setseed(&seed);
|
||||
return (TRUE);
|
||||
|
||||
Reference in New Issue
Block a user