From b3e62c24fffc67cbb9b9aa1420d4fea38e8261cc Mon Sep 17 00:00:00 2001 From: Pavel Raiskup <praiskup@redhat.com> Date: Sat, 22 Feb 2014 07:46:51 -0100 Subject: [PATCH] Fix for CVE-2014-0062 --- src/backend/bootstrap/bootparse.y | 13 ++++++-- src/backend/catalog/index.c | 3 +- src/backend/commands/alter.c | 4 +-- src/backend/commands/indexcmds.c | 15 +++++---- src/backend/commands/tablecmds.c | 65 +++++++++++++++++++++------------------ src/backend/commands/trigger.c | 24 ++++++++++++--- src/backend/nodes/copyfuncs.c | 1 + src/backend/nodes/equalfuncs.c | 1 + src/backend/nodes/outfuncs.c | 1 + src/backend/tcop/utility.c | 49 +++++++++++++++++++++++------ src/include/catalog/index.h | 2 ++ src/include/commands/defrem.h | 2 +- src/include/commands/tablecmds.h | 2 +- src/include/commands/trigger.h | 3 +- src/include/nodes/parsenodes.h | 1 + src/include/tcop/utility.h | 2 +- 16 files changed, 127 insertions(+), 61 deletions(-) diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index a3b2285..1fbd5ea 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -27,6 +27,7 @@ #include "bootstrap/bootstrap.h" #include "catalog/catalog.h" #include "catalog/heap.h" +#include "catalog/namespace.h" #include "catalog/pg_am.h" #include "catalog/pg_attribute.h" #include "catalog/pg_authid.h" @@ -242,9 +243,13 @@ Boot_InsertStmt: Boot_DeclareIndexStmt: XDECLARE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN { + Oid relationId; do_start(); - DefineIndex(makeRangeVar(NULL, LexIDStr($6)), + relationId = RangeVarGetRelid(makeRangeVar(NULL, LexIDStr($6)), + false); + + DefineIndex(relationId, LexIDStr($3), $4, LexIDStr($8), @@ -260,9 +265,13 @@ Boot_DeclareIndexStmt: Boot_DeclareUniqueIndexStmt: XDECLARE UNIQUE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN { + Oid relationId; do_start(); - DefineIndex(makeRangeVar(NULL, LexIDStr($7)), + relationId = RangeVarGetRelid(makeRangeVar(NULL, LexIDStr($7)), + false); + + DefineIndex(relationId, LexIDStr($4), $5, LexIDStr($9), diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index d39b810..a8ffec1 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -64,7 +64,6 @@ static void UpdateIndexRelation(Oid indexoid, Oid heapoid, IndexInfo *indexInfo, Oid *classOids, bool primary); -static Oid IndexGetRelation(Oid indexId); static void UpdateStats(Oid relid, double reltuples); @@ -1632,7 +1631,7 @@ IndexBuildHeapScan(Relation heapRelation, * IndexGetRelation: given an index's relation OID, get the OID of the * relation it is an index on. Uses the system cache. */ -static Oid +Oid IndexGetRelation(Oid indexId) { HeapTuple tuple; diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 23cf8bf..c5c857a 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -91,9 +91,8 @@ ExecRenameStmt(RenameStmt *stmt) { Oid relid; - CheckRelationOwnership(stmt->relation, true); - relid = RangeVarGetRelid(stmt->relation, false); + CheckRelationOwnership(relid, true); switch (stmt->renameType) { @@ -159,7 +158,6 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt) case OBJECT_SEQUENCE: case OBJECT_TABLE: - CheckRelationOwnership(stmt->relation, true); AlterTableNamespace(stmt->relation, stmt->newschema); break; diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 81ab2e8..ca75a02 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -60,7 +60,8 @@ static bool relationHasPrimaryKey(Relation rel); * DefineIndex * Creates a new index. * - * 'heapRelation': the relation the index will apply to. + * 'relationId': the OID of the heap relation on which the index is to be + * created * 'indexRelationName': the name for the new index, or NULL to indicate * that a nonconflicting default name should be picked. * 'indexRelationId': normally InvalidOid, but during bootstrap can be @@ -84,7 +85,7 @@ static bool relationHasPrimaryKey(Relation rel); * 'quiet': suppress the NOTICE chatter ordinarily provided for constraints. */ void -DefineIndex(RangeVar *heapRelation, +DefineIndex(Oid relationId, char *indexRelationName, Oid indexRelationId, char *accessMethodName, @@ -102,7 +103,6 @@ DefineIndex(RangeVar *heapRelation, { Oid *classObjectId; Oid accessMethodId; - Oid relationId; Oid namespaceId; Oid tablespaceId; Relation rel; @@ -127,8 +127,11 @@ DefineIndex(RangeVar *heapRelation, /* * Open heap relation, acquire a suitable lock on it, remember its OID + * + * NB: Caller is responsible for making sure that relationId refers + * to the relation on which the index should be built. */ - rel = heap_openrv(heapRelation, ShareLock); + rel = heap_open(relationId, ShareLock); /* Note: during bootstrap may see uncataloged relation */ if (rel->rd_rel->relkind != RELKIND_RELATION && @@ -136,9 +139,9 @@ DefineIndex(RangeVar *heapRelation, ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a table", - heapRelation->relname))); + RelationGetRelationName(rel)))); - relationId = RelationGetRelid(rel); + relationId = RelationGetRelid(rel); /* empty operation? */ namespaceId = RelationGetNamespace(rel); /* diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 3d2e385..04a79c6 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -53,6 +53,7 @@ #include "parser/parse_type.h" #include "rewrite/rewriteHandler.h" #include "storage/smgr.h" +#include "tcop/utility.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -180,8 +181,8 @@ static Oid transformFkeyCheckAttrs(Relation pkrel, Oid *opclasses); static void validateForeignKeyConstraint(FkConstraint *fkconstraint, Relation rel, Relation pkrel); -static void createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, - Oid constrOid); +static void createForeignKeyTriggers(Relation rel, Oid refRelOid, + FkConstraint *fkconstraint, Oid constrOid); static char *fkMatchTypeToString(char match_type); static void ATController(Relation rel, List *cmds, bool recurse); static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, @@ -1862,9 +1863,9 @@ CheckTableNotInUse(Relation rel, const char *stmt) * the whole operation; we don't have to do anything special to clean up. */ void -AlterTable(AlterTableStmt *stmt) +AlterTable(Oid relid, AlterTableStmt *stmt) { - Relation rel = relation_openrv(stmt->relation, AccessExclusiveLock); + Relation rel = relation_open(relid, AccessExclusiveLock); CheckTableNotInUse(rel, "ALTER TABLE"); @@ -3776,7 +3777,7 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, /* suppress notices when rebuilding existing index */ quiet = is_rebuild; - DefineIndex(stmt->relation, /* relation */ + DefineIndex(RelationGetRelid(rel), /* relation */ stmt->idxname, /* index name */ InvalidOid, /* no predefined OID */ stmt->accessMethod, /* am name */ @@ -3916,7 +3917,10 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, * table; trying to start with a lesser lock will just create a risk of * deadlock.) */ - pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock); + if (OidIsValid(fkconstraint->old_pktable_oid)) + pkrel = heap_open(fkconstraint->old_pktable_oid, AccessExclusiveLock); + else + pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock); /* * Validity and permissions checks @@ -4107,7 +4111,8 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, /* * Create the triggers that will enforce the constraint. */ - createForeignKeyTriggers(rel, fkconstraint, constrOid); + createForeignKeyTriggers(rel, RelationGetRelid(pkrel), fkconstraint, + constrOid); /* * Close pk table, but keep lock until we've committed. @@ -4459,7 +4464,7 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint, } static void -CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint, +CreateFKCheckTrigger(Oid myRelOid, Oid refRelOid, FkConstraint *fkconstraint, ObjectAddress *constrobj, ObjectAddress *trigobj, bool on_insert) { @@ -4469,7 +4474,7 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint, fk_trigger = makeNode(CreateTrigStmt); fk_trigger->trigname = fkconstraint->constr_name; - fk_trigger->relation = myRel; + fk_trigger->relation = NULL; fk_trigger->before = false; fk_trigger->row = true; @@ -4495,7 +4500,7 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint, fk_trigger->args = lappend(fk_trigger->args, makeString(fkconstraint->constr_name)); fk_trigger->args = lappend(fk_trigger->args, - makeString(myRel->relname)); + makeString(get_rel_name(myRelOid))); fk_trigger->args = lappend(fk_trigger->args, makeString(fkconstraint->pktable->relname)); fk_trigger->args = lappend(fk_trigger->args, @@ -4512,7 +4517,7 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint, fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr)); } - trigobj->objectId = CreateTrigger(fk_trigger, true); + trigobj->objectId = CreateTrigger(fk_trigger, myRelOid, refRelOid, true); /* Register dependency from trigger to constraint */ recordDependencyOn(trigobj, constrobj, DEPENDENCY_INTERNAL); @@ -4525,21 +4530,17 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint, * Create the triggers that implement an FK constraint. */ static void -createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, - Oid constrOid) +createForeignKeyTriggers(Relation rel, Oid refRelOid, + FkConstraint *fkconstraint, Oid constrOid) { - RangeVar *myRel; + Oid myRelOid; CreateTrigStmt *fk_trigger; ListCell *fk_attr; ListCell *pk_attr; ObjectAddress trigobj, constrobj; - /* - * Reconstruct a RangeVar for my relation (not passed in, unfortunately). - */ - myRel = makeRangeVar(get_namespace_name(RelationGetNamespace(rel)), - pstrdup(RelationGetRelationName(rel))); + myRelOid = RelationGetRelid(rel); /* * Preset objectAddress fields @@ -4557,8 +4558,10 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, * Build and execute a CREATE CONSTRAINT TRIGGER statement for the CHECK * action for both INSERTs and UPDATEs on the referencing table. */ - CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, true); - CreateFKCheckTrigger(myRel, fkconstraint, &constrobj, &trigobj, false); + CreateFKCheckTrigger(myRelOid, refRelOid, fkconstraint, + &constrobj, &trigobj, true); + CreateFKCheckTrigger(myRelOid, refRelOid, fkconstraint, + &constrobj, &trigobj, false); /* * Build and execute a CREATE CONSTRAINT TRIGGER statement for the ON @@ -4566,14 +4569,14 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, */ fk_trigger = makeNode(CreateTrigStmt); fk_trigger->trigname = fkconstraint->constr_name; - fk_trigger->relation = fkconstraint->pktable; + fk_trigger->relation = NULL; fk_trigger->before = false; fk_trigger->row = true; fk_trigger->actions[0] = 'd'; fk_trigger->actions[1] = '\0'; fk_trigger->isconstraint = true; - fk_trigger->constrrel = myRel; + fk_trigger->constrrel = rel; switch (fkconstraint->fk_del_action) { case FKCONSTR_ACTION_NOACTION: @@ -4611,7 +4614,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, fk_trigger->args = lappend(fk_trigger->args, makeString(fkconstraint->constr_name)); fk_trigger->args = lappend(fk_trigger->args, - makeString(myRel->relname)); + makeString(get_rel_name(myRelOid))); fk_trigger->args = lappend(fk_trigger->args, makeString(fkconstraint->pktable->relname)); fk_trigger->args = lappend(fk_trigger->args, @@ -4623,7 +4626,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr)); } - trigobj.objectId = CreateTrigger(fk_trigger, true); + trigobj.objectId = CreateTrigger(fk_trigger, refRelOid, myRelOid, true); /* Register dependency from trigger to constraint */ recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL); @@ -4637,13 +4640,13 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, */ fk_trigger = makeNode(CreateTrigStmt); fk_trigger->trigname = fkconstraint->constr_name; - fk_trigger->relation = fkconstraint->pktable; + fk_trigger->relation = NULL; fk_trigger->before = false; fk_trigger->row = true; fk_trigger->actions[0] = 'u'; fk_trigger->actions[1] = '\0'; fk_trigger->isconstraint = true; - fk_trigger->constrrel = myRel; + fk_trigger->constrrel = rel; switch (fkconstraint->fk_upd_action) { case FKCONSTR_ACTION_NOACTION: @@ -4681,7 +4684,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, fk_trigger->args = lappend(fk_trigger->args, makeString(fkconstraint->constr_name)); fk_trigger->args = lappend(fk_trigger->args, - makeString(myRel->relname)); + makeString(get_rel_name(myRelOid))); fk_trigger->args = lappend(fk_trigger->args, makeString(fkconstraint->pktable->relname)); fk_trigger->args = lappend(fk_trigger->args, @@ -4693,7 +4696,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr)); } - trigobj.objectId = CreateTrigger(fk_trigger, true); + trigobj.objectId = CreateTrigger(fk_trigger, refRelOid, myRelOid, true); /* Register dependency from trigger to constraint */ recordDependencyOn(&trigobj, &constrobj, DEPENDENCY_INTERNAL); @@ -6230,7 +6233,8 @@ needs_toast_table(Relation rel) /* * Execute ALTER TABLE SET SCHEMA * - * Note: caller must have checked ownership of the relation already + * WARNING WARNING WARNING: In previous *minor* releases the caller was + * responsible for checking ownership of the relation, but now we do it here. */ void AlterTableNamespace(RangeVar *relation, const char *newschema) @@ -6251,6 +6255,7 @@ AlterTableNamespace(RangeVar *relation, const char *newschema) RelationGetRelationName(rel)))); relid = RelationGetRelid(rel); + CheckRelationOwnership(relid, true); oldNspOid = RelationGetNamespace(rel); /* get schema OID and check its permissions */ diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index ace9924..2d79fae 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -58,13 +58,21 @@ static void AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event, /* * Create a trigger. Returns the OID of the created trigger. * + * relOid, if nonzero, is the relation on which the trigger should be + * created. If zero, the name provided in the statement will be looked up. + * + * refRelOid, if nonzero, is the relation to which the constraint trigger + * refers. If zero, the constraint relation name provided in the statement + * will be looked up as needed. + * * forConstraint, if true, says that this trigger is being created to * implement a constraint. The caller will then be expected to make * a pg_depend entry linking the trigger to that constraint (and thereby * to the owning relation(s)). */ Oid -CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) +CreateTrigger(CreateTrigStmt *stmt, Oid relOid, Oid refRelOid, + bool forConstraint) { int16 tgtype; int2vector *tgattr; @@ -90,10 +98,18 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) ObjectAddress myself, referenced; - rel = heap_openrv(stmt->relation, AccessExclusiveLock); + if (OidIsValid(relOid)) + rel = heap_open(relOid, AccessExclusiveLock); + else + rel = heap_openrv(stmt->relation, AccessExclusiveLock); if (stmt->constrrel != NULL) - constrrelid = RangeVarGetRelid(stmt->constrrel, false); + { + if (OidIsValid(refRelOid)) + constrrelid = refRelOid; + else + constrrelid = RangeVarGetRelid(stmt->constrrel, false); + } else if (stmt->isconstraint) { /* @@ -266,7 +282,7 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("trigger \"%s\" for relation \"%s\" already exists", - trigname, stmt->relation->relname))); + trigname, RelationGetRelationName(rel)))); found++; } systable_endscan(tgscan); diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 8cb209a..76e69f8 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -1335,6 +1335,7 @@ _copyFkConstraint(FkConstraint *from) COPY_SCALAR_FIELD(deferrable); COPY_SCALAR_FIELD(initdeferred); COPY_SCALAR_FIELD(skip_validation); + COPY_SCALAR_FIELD(old_pktable_oid); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 1940d78..7665432 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1701,6 +1701,7 @@ _equalFkConstraint(FkConstraint *a, FkConstraint *b) COMPARE_SCALAR_FIELD(deferrable); COMPARE_SCALAR_FIELD(initdeferred); COMPARE_SCALAR_FIELD(skip_validation); + COMPARE_SCALAR_FIELD(old_pktable_oid); return true; } diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 75a9fa3..25ca107 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -1764,6 +1764,7 @@ _outFkConstraint(StringInfo str, FkConstraint *node) WRITE_BOOL_FIELD(deferrable); WRITE_BOOL_FIELD(initdeferred); WRITE_BOOL_FIELD(skip_validation); + WRITE_OID_FIELD(old_pktable_oid); } diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 3845267..28af83f 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -50,12 +50,15 @@ #include "rewrite/rewriteDefine.h" #include "rewrite/rewriteRemove.h" #include "storage/fd.h" +#include "storage/lmgr.h" #include "tcop/pquery.h" #include "tcop/utility.h" #include "utils/acl.h" #include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/syscache.h" +#include "utils/lsyscache.h" +#include "utils/relcache.h" /* @@ -192,12 +195,10 @@ CheckDropPermissions(RangeVar *rel, char rightkind) * except when allowSystemTableMods is true. */ void -CheckRelationOwnership(RangeVar *rel, bool noCatalogs) +CheckRelationOwnership(Oid relOid, bool noCatalogs) { - Oid relOid; HeapTuple tuple; - relOid = RangeVarGetRelid(rel, false); tuple = SearchSysCache(RELOID, ObjectIdGetDatum(relOid), 0, 0, 0); @@ -206,7 +207,7 @@ CheckRelationOwnership(RangeVar *rel, bool noCatalogs) if (!pg_class_ownercheck(relOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, - rel->relname); + get_rel_name(relOid)); if (noCatalogs) { @@ -215,7 +216,7 @@ CheckRelationOwnership(RangeVar *rel, bool noCatalogs) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied: \"%s\" is a system catalog", - rel->relname))); + get_rel_name(relOid)))); } ReleaseSysCache(tuple); @@ -655,8 +656,24 @@ ProcessUtility(Node *parsetree, break; case T_AlterTableStmt: - AlterTable((AlterTableStmt *) parsetree); - break; + { + /* + * This change is probably not completely necessary but keep the + * backport consistent. + */ + AlterTableStmt *atstmt = (AlterTableStmt *) parsetree; + Oid relid; + + /* + * Look up the relation OID just once, right here at the + * beginning, so that we don't end up repeating the name + * lookup later and latching onto a different relation + * partway through. + */ + relid = RangeVarGetRelid(atstmt->relation, false); + AlterTable(relid, atstmt); + break; + } case T_AlterDomainStmt: { @@ -764,10 +781,21 @@ ProcessUtility(Node *parsetree, case T_IndexStmt: /* CREATE INDEX */ { IndexStmt *stmt = (IndexStmt *) parsetree; + Oid relid; - CheckRelationOwnership(stmt->relation, true); + /* + * Look up the relation OID just once, right here at the + * beginning, so that we don't end up repeating the name + * lookup later and latching onto a different relation + * partway through. To avoid lock upgrade hazards, it's + * important that we take the strongest lock that will + * eventually be needed here, so the lockmode calculation + * needs to match what DefineIndex() does. + */ + relid = RangeVarGetRelid(stmt->relation, false); + CheckRelationOwnership(relid, true); - DefineIndex(stmt->relation, /* relation */ + DefineIndex(relid, /* relation */ stmt->idxname, /* index name */ InvalidOid, /* no predefined OID */ stmt->accessMethod, /* am name */ @@ -943,7 +971,8 @@ ProcessUtility(Node *parsetree, break; case T_CreateTrigStmt: - CreateTrigger((CreateTrigStmt *) parsetree, false); + CreateTrigger((CreateTrigStmt *) parsetree, InvalidOid, + InvalidOid, false); break; case T_DropPropertyStmt: diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 7f41201..a39ef25 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -72,4 +72,6 @@ extern double IndexBuildHeapScan(Relation heapRelation, extern void reindex_index(Oid indexId); extern bool reindex_relation(Oid relid, bool toast_too); +extern Oid IndexGetRelation(Oid indexId); + #endif /* INDEX_H */ diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 462d084..4548360 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -18,7 +18,7 @@ /* commands/indexcmds.c */ -extern void DefineIndex(RangeVar *heapRelation, +extern void DefineIndex(Oid relationId, char *indexRelationName, Oid indexRelationId, char *accessMethodName, diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index 7e00b9e..2c89567 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -22,7 +22,7 @@ extern Oid DefineRelation(CreateStmt *stmt, char relkind); extern void RemoveRelation(const RangeVar *relation, DropBehavior behavior); -extern void AlterTable(AlterTableStmt *stmt); +extern void AlterTable(Oid relid, AlterTableStmt *stmt); extern void AlterTableInternal(Oid relid, List *cmds, bool recurse); diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index 464f8d4..14f5982 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -105,7 +105,8 @@ typedef struct TriggerData #define RI_MAX_ARGUMENTS (RI_FIRST_ATTNAME_ARGNO + (RI_MAX_NUMKEYS * 2)) -extern Oid CreateTrigger(CreateTrigStmt *stmt, bool forConstraint); +extern Oid CreateTrigger(CreateTrigStmt *stmt, Oid relOid, Oid refRelOid, + bool forConstraint); extern void DropTrigger(Oid relid, const char *trigname, DropBehavior behavior); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 4fff844..04ceaea 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1081,6 +1081,7 @@ typedef struct FkConstraint bool deferrable; /* DEFERRABLE */ bool initdeferred; /* INITIALLY DEFERRED */ bool skip_validation; /* skip validation of existing rows? */ + Oid old_pktable_oid; /* pg_constraint.confrelid of my former self */ } FkConstraint; diff --git a/src/include/tcop/utility.h b/src/include/tcop/utility.h index f6cfaec..a7453a0 100644 --- a/src/include/tcop/utility.h +++ b/src/include/tcop/utility.h @@ -30,6 +30,6 @@ extern const char *CreateQueryTag(Query *parsetree); extern bool QueryIsReadOnly(Query *parsetree); -extern void CheckRelationOwnership(RangeVar *rel, bool noCatalogs); +extern void CheckRelationOwnership(Oid relOid, bool noCatalogs); #endif /* UTILITY_H */ -- 1.8.5.3