diff options
Diffstat (limited to 'src/backend/commands')
| -rw-r--r-- | src/backend/commands/command.c | 114 | ||||
| -rw-r--r-- | src/backend/commands/creatinh.c | 20 | ||||
| -rw-r--r-- | src/backend/commands/explain.c | 8 | ||||
| -rw-r--r-- | src/backend/commands/sequence.c | 11 | ||||
| -rw-r--r-- | src/backend/commands/trigger.c | 59 | ||||
| -rw-r--r-- | src/backend/commands/vacuum.c | 12 | ||||
| -rw-r--r-- | src/backend/commands/view.c | 28 |
7 files changed, 177 insertions, 75 deletions
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index c32be8b02f..5821e1d103 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.161 2002/03/14 22:44:50 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.162 2002/03/21 16:00:31 tgl Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -33,7 +33,7 @@ #include "catalog/pg_type.h" #include "commands/command.h" #include "commands/trigger.h" -#include "commands/defrem.h" /* For add constraint unique, primary */ +#include "commands/defrem.h" #include "executor/execdefs.h" #include "executor/executor.h" #include "miscadmin.h" @@ -44,7 +44,8 @@ #include "parser/parse_expr.h" #include "parser/parse_oper.h" #include "parser/parse_relation.h" -#include "parser/analyze.h" /* For add constraint unique, primary */ +#include "parser/analyze.h" +#include "tcop/utility.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -1279,8 +1280,7 @@ AlterTableAddConstraint(char *relationName, * Convert the A_EXPR in raw_expr into an * EXPR */ - expr = transformExpr(pstate, constr->raw_expr, - EXPR_COLUMN_FIRST); + expr = transformExpr(pstate, constr->raw_expr); /* * Make sure it yields a boolean result. @@ -1366,7 +1366,7 @@ AlterTableAddConstraint(char *relationName, List *list; int count; - if (is_temp_rel_name(fkconstraint->pktable_name) && + if (is_temp_rel_name(fkconstraint->pktable->relname) && !is_temp_rel_name(relationName)) elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint."); @@ -1375,10 +1375,10 @@ AlterTableAddConstraint(char *relationName, * someone doesn't delete rows out from under us. */ - pkrel = heap_openr(fkconstraint->pktable_name, AccessExclusiveLock); + pkrel = heap_openr(fkconstraint->pktable->relname, AccessExclusiveLock); if (pkrel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "referenced table \"%s\" not a relation", - fkconstraint->pktable_name); + fkconstraint->pktable->relname); heap_close(pkrel, NoLock); /* @@ -1417,7 +1417,7 @@ AlterTableAddConstraint(char *relationName, else trig.tgargs[0] = "<unknown>"; trig.tgargs[1] = (char *) relationName; - trig.tgargs[2] = fkconstraint->pktable_name; + trig.tgargs[2] = fkconstraint->pktable->relname; trig.tgargs[3] = fkconstraint->match_type; count = 4; foreach(list, fkconstraint->fk_attrs) @@ -1936,9 +1936,10 @@ LockTableCommand(LockStmt *lockstmt) * at a time */ - foreach(p, lockstmt->rellist) + foreach(p, lockstmt->relations) { - char *relname = strVal(lfirst(p)); + RangeVar *relation = lfirst(p); + char *relname = relation->relname; int aclresult; Relation rel; @@ -1962,3 +1963,94 @@ LockTableCommand(LockStmt *lockstmt) relation_close(rel, NoLock); /* close rel, keep lock */ } } + + +/* + * CREATE SCHEMA + */ +void +CreateSchemaCommand(CreateSchemaStmt *stmt) +{ + const char *schemaName = stmt->schemaname; + const char *authId = stmt->authid; + List *parsetree_list; + List *parsetree_item; + const char *owner_name; + Oid owner_userid; + Oid saved_userid; + + saved_userid = GetUserId(); + + if (!authId) + { + owner_userid = saved_userid; + owner_name = GetUserName(owner_userid); + } + else if (superuser()) + { + owner_name = authId; + /* The following will error out if user does not exist */ + owner_userid = get_usesysid(owner_name); + /* + * Set the current user to the requested authorization so + * that objects created in the statement have the requested + * owner. (This will revert to session user on error or at + * the end of this routine.) + */ + SetUserId(owner_userid); + } + else /* not superuser */ + { + owner_userid = saved_userid; + owner_name = GetUserName(owner_userid); + if (strcmp(authId, owner_name) != 0) + elog(ERROR, "CREATE SCHEMA: permission denied" + "\n\t\"%s\" is not a superuser, so cannot create a schema for \"%s\"", + owner_name, authId); + } + + /* FIXME FENN: Create the schema here */ + (void) schemaName; /* suppress compiler warning for now... */ + + /* + * Let commands in the schema-element-list know about the schema + */ + CommandCounterIncrement(); + + /* + * Examine the list of commands embedded in the CREATE SCHEMA command, + * and reorganize them into a sequentially executable order with no + * forward references. Note that the result is still a list of raw + * parsetrees in need of parse analysis --- we cannot, in general, + * run analyze.c on one statement until we have actually executed the + * prior ones. + */ + parsetree_list = analyzeCreateSchemaStmt(stmt); + + /* + * Analyze and execute each command contained in the CREATE SCHEMA + */ + foreach(parsetree_item, parsetree_list) + { + Node *parsetree = (Node *) lfirst(parsetree_item); + List *querytree_list, + *querytree_item; + + querytree_list = parse_analyze(parsetree, NULL); + + foreach(querytree_item, querytree_list) + { + Query *querytree = (Query *) lfirst(querytree_item); + + /* schemas should contain only utility stmts */ + Assert(querytree->commandType == CMD_UTILITY); + /* do this step */ + ProcessUtility(querytree->utilityStmt, None, NULL); + /* make sure later steps can see the object created here */ + CommandCounterIncrement(); + } + } + + /* Reset current user */ + SetUserId(saved_userid); +} diff --git a/src/backend/commands/creatinh.c b/src/backend/commands/creatinh.c index c9dee0cbbe..04854a2afa 100644 --- a/src/backend/commands/creatinh.c +++ b/src/backend/commands/creatinh.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.88 2002/03/20 19:43:42 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.89 2002/03/21 16:00:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -69,7 +69,7 @@ DefineRelation(CreateStmt *stmt, char relkind) * Truncate relname to appropriate length (probably a waste of time, * as parser should have done this already). */ - StrNCpy(relname, stmt->relname, NAMEDATALEN); + StrNCpy(relname, (stmt->relation)->relname, NAMEDATALEN); /* * Merge domain attributes into the known columns before processing table @@ -82,8 +82,9 @@ DefineRelation(CreateStmt *stmt, char relkind) * Look up inheritance ancestors and generate relation schema, * including inherited attributes. */ - schema = MergeAttributes(schema, stmt->inhRelnames, stmt->istemp, - &inheritOids, &old_constraints, &parentHasOids); + schema = MergeAttributes(schema, stmt->inhRelations, + stmt->relation->istemp, + &inheritOids, &old_constraints, &parentHasOids); numberOfAttributes = length(schema); if (numberOfAttributes <= 0) @@ -147,7 +148,7 @@ DefineRelation(CreateStmt *stmt, char relkind) relationId = heap_create_with_catalog(relname, descriptor, relkind, stmt->hasoids || parentHasOids, - stmt->istemp, + stmt->relation->istemp, allowSystemTableMods); StoreCatalogInheritance(relationId, inheritOids); @@ -414,6 +415,8 @@ MergeAttributes(List *schema, List *supers, bool istemp, /* * Reject duplicate names in the list of parents, too. + * + * XXX needs to be smarter about schema-qualified table names. */ foreach(entry, supers) { @@ -421,9 +424,10 @@ MergeAttributes(List *schema, List *supers, bool istemp, foreach(rest, lnext(entry)) { - if (strcmp(strVal(lfirst(entry)), strVal(lfirst(rest))) == 0) + if (strcmp(((RangeVar *) lfirst(entry))->relname, + ((RangeVar *) lfirst(rest))->relname) == 0) elog(ERROR, "CREATE TABLE: inherited relation \"%s\" duplicated", - strVal(lfirst(entry))); + ((RangeVar *) lfirst(entry))->relname); } } @@ -435,7 +439,7 @@ MergeAttributes(List *schema, List *supers, bool istemp, child_attno = 0; foreach(entry, supers) { - char *name = strVal(lfirst(entry)); + char *name = ((RangeVar *) lfirst(entry))->relname; Relation relation; TupleDesc tupleDesc; TupleConstr *constr; diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index e230ba598a..95263a5da0 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -5,7 +5,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.71 2002/03/12 00:51:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.72 2002/03/21 16:00:32 tgl Exp $ * */ @@ -310,9 +310,9 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) appendStringInfo(str, " on %s", stringStringInfo(rte->relname)); - if (strcmp(rte->eref->relname, rte->relname) != 0) + if (strcmp(rte->eref->aliasname, rte->relname) != 0) appendStringInfo(str, " %s", - stringStringInfo(rte->eref->relname)); + stringStringInfo(rte->eref->aliasname)); } break; case T_SubqueryScan: @@ -322,7 +322,7 @@ explain_outNode(StringInfo str, Plan *plan, int indent, ExplainState *es) es->rtable); appendStringInfo(str, " %s", - stringStringInfo(rte->eref->relname)); + stringStringInfo(rte->eref->aliasname)); } break; default: diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 0e57d90dfb..e9df6392bc 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.71 2002/03/15 19:20:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.72 2002/03/21 16:00:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -123,7 +123,7 @@ DefineSequence(CreateSeqStmt *seq) case SEQ_COL_NAME: typnam->name = "name"; coldef->colname = "sequence_name"; - namestrcpy(&name, seq->seqname); + namestrcpy(&name, seq->sequence->relname); value[i - 1] = NameGetDatum(&name); break; case SEQ_COL_LASTVAL: @@ -170,15 +170,14 @@ DefineSequence(CreateSeqStmt *seq) stmt->tableElts = lappend(stmt->tableElts, coldef); } - stmt->relname = seq->seqname; - stmt->inhRelnames = NIL; + stmt->relation = seq->sequence; + stmt->inhRelations = NIL; stmt->constraints = NIL; - stmt->istemp = seq->istemp; stmt->hasoids = false; DefineRelation(stmt, RELKIND_SEQUENCE); - rel = heap_openr(seq->seqname, AccessExclusiveLock); + rel = heap_openr(seq->sequence->relname, AccessExclusiveLock); tupDesc = RelationGetDescr(rel); /* Initialize first page of relation with special magic number */ diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index e25b83b455..5bef86e306 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -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.105 2002/03/08 04:37:14 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.106 2002/03/21 16:00:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -71,10 +71,11 @@ CreateTrigger(CreateTrigStmt *stmt) char *constrname = ""; Oid constrrelid = InvalidOid; - if (!allowSystemTableMods && IsSystemRelationName(stmt->relname)) - elog(ERROR, "CreateTrigger: can't create trigger for system relation %s", stmt->relname); + if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname)) + elog(ERROR, "CreateTrigger: can't create trigger for system relation %s", + stmt->relation->relname); - if (pg_aclcheck(stmt->relname, GetUserId(), + if (pg_aclcheck(stmt->relation->relname, GetUserId(), stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER) != ACLCHECK_OK) elog(ERROR, "permission denied"); @@ -89,7 +90,7 @@ CreateTrigger(CreateTrigStmt *stmt) stmt->trigname = constrtrigname; sprintf(constrtrigname, "RI_ConstraintTrigger_%u", newoid()); - if (strcmp(stmt->constrrelname, "") == 0) + if (stmt->constrrel == NULL) constrrelid = InvalidOid; else { @@ -97,17 +98,17 @@ CreateTrigger(CreateTrigStmt *stmt) * NoLock is probably sufficient here, since we're only * interested in getting the relation's OID... */ - rel = heap_openr(stmt->constrrelname, NoLock); + rel = heap_openr(stmt->constrrel->relname, NoLock); constrrelid = rel->rd_id; heap_close(rel, NoLock); } } - rel = heap_openr(stmt->relname, AccessExclusiveLock); + rel = heap_openr(stmt->relation->relname, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "CreateTrigger: relation \"%s\" is not a table", - stmt->relname); + stmt->relation->relname); TRIGGER_CLEAR_TYPE(tgtype); if (stmt->before) @@ -159,7 +160,7 @@ CreateTrigger(CreateTrigStmt *stmt) if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0) elog(ERROR, "CreateTrigger: trigger %s already defined on relation %s", - stmt->trigname, stmt->relname); + stmt->trigname, stmt->relation->relname); found++; } systable_endscan(tgscan); @@ -283,11 +284,11 @@ CreateTrigger(CreateTrigStmt *stmt) */ pgrel = heap_openr(RelationRelationName, RowExclusiveLock); tuple = SearchSysCacheCopy(RELNAME, - PointerGetDatum(stmt->relname), + PointerGetDatum(stmt->relation->relname), 0, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "CreateTrigger: relation %s not found in pg_class", - stmt->relname); + stmt->relation->relname); ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1; simple_heap_update(pgrel, &tuple->t_self, tuple); @@ -320,19 +321,19 @@ DropTrigger(DropTrigStmt *stmt) int found = 0; int tgfound = 0; - if (!allowSystemTableMods && IsSystemRelationName(stmt->relname)) + if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname)) elog(ERROR, "DropTrigger: can't drop trigger for system relation %s", - stmt->relname); + stmt->relation->relname); - if (!pg_ownercheck(GetUserId(), stmt->relname, RELNAME)) - elog(ERROR, "%s: %s", stmt->relname, + if (!pg_ownercheck(GetUserId(), stmt->relation->relname, RELNAME)) + elog(ERROR, "%s: %s", stmt->relation->relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]); - rel = heap_openr(stmt->relname, AccessExclusiveLock); + rel = heap_openr(stmt->relation->relname, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION) elog(ERROR, "DropTrigger: relation \"%s\" is not a table", - stmt->relname); + stmt->relation->relname); /* * Search pg_trigger, delete target trigger, count remaining triggers @@ -366,10 +367,10 @@ DropTrigger(DropTrigStmt *stmt) if (tgfound == 0) elog(ERROR, "DropTrigger: there is no trigger %s on relation %s", - stmt->trigname, stmt->relname); + stmt->trigname, stmt->relation->relname); if (tgfound > 1) elog(NOTICE, "DropTrigger: found (and deleted) %d triggers %s on relation %s", - tgfound, stmt->trigname, stmt->relname); + tgfound, stmt->trigname, stmt->relation->relname); /* * Update relation's pg_class entry. Crucial side-effect: other @@ -378,11 +379,11 @@ DropTrigger(DropTrigStmt *stmt) */ pgrel = heap_openr(RelationRelationName, RowExclusiveLock); tuple = SearchSysCacheCopy(RELNAME, - PointerGetDatum(stmt->relname), + PointerGetDatum(stmt->relation->relname), 0, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "DropTrigger: relation %s not found in pg_class", - stmt->relname); + stmt->relation->relname); ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found; simple_heap_update(pgrel, &tuple->t_self, tuple); @@ -478,20 +479,23 @@ RelationRemoveTriggers(Relation rel) { Form_pg_trigger pg_trigger; Relation refrel; - DropTrigStmt stmt; + DropTrigStmt *stmt = makeNode(DropTrigStmt); pg_trigger = (Form_pg_trigger) GETSTRUCT(tup); - stmt.trigname = pstrdup(NameStr(pg_trigger->tgname)); + stmt->trigname = pstrdup(NameStr(pg_trigger->tgname)); /* May as well grab AccessExclusiveLock, since DropTrigger will. */ refrel = heap_open(pg_trigger->tgrelid, AccessExclusiveLock); - stmt.relname = pstrdup(RelationGetRelationName(refrel)); + stmt->relation = makeNode(RangeVar); + /* XXX bogus: what about schema? */ + stmt->relation->relname = pstrdup(RelationGetRelationName(refrel)); heap_close(refrel, NoLock); - elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"", stmt.relname); + elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"", + stmt->relation->relname); - DropTrigger(&stmt); + DropTrigger(stmt); /* * Need to do a command counter increment here to show up new @@ -500,9 +504,6 @@ RelationRemoveTriggers(Relation rel) * FK table defined on the PK table). */ CommandCounterIncrement(); - - pfree(stmt.relname); - pfree(stmt.trigname); } systable_endscan(tgscan); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 6b94db1077..836091c583 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.217 2002/03/06 06:09:38 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.218 2002/03/21 16:00:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -209,10 +209,10 @@ vacuum(VacuumStmt *vacstmt) ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); - /* Convert vacrel, which is just a string, to a Name */ - if (vacstmt->vacrel) + /* Convert relname, which is just a string, to a Name */ + if (vacstmt->relation) { - namestrcpy(&VacRel, vacstmt->vacrel); + namestrcpy(&VacRel, vacstmt->relation->relname); VacRelName = &VacRel; } else @@ -268,7 +268,7 @@ vacuum(VacuumStmt *vacstmt) static void vacuum_init(VacuumStmt *vacstmt) { - if (vacstmt->vacuum && vacstmt->vacrel == NULL) + if (vacstmt->vacuum && vacstmt->relation == NULL) { /* * Compute the initially applicable OldestXmin and FreezeLimit @@ -308,7 +308,7 @@ vacuum_shutdown(VacuumStmt *vacstmt) * row with info about the transaction IDs used, and try to truncate * pg_clog. */ - if (vacstmt->vacuum && vacstmt->vacrel == NULL) + if (vacstmt->vacuum && vacstmt->relation == NULL) { vac_update_dbstats(MyDatabaseId, initialOldestXmin, initialFreezeLimit); diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 9d1254a4cb..74a3ac2bca 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: view.c,v 1.58 2001/10/25 05:49:26 momjian Exp $ + * $Id: view.c,v 1.59 2002/03/21 16:00:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -41,6 +41,7 @@ static void DefineVirtualRelation(char *relname, List *tlist) { CreateStmt *createStmt = makeNode(CreateStmt); + RangeVar *rel = makeNode(RangeVar); List *attrList, *t; @@ -83,11 +84,13 @@ DefineVirtualRelation(char *relname, List *tlist) * now create the parameters for keys/inheritance etc. All of them are * nil... */ - createStmt->relname = relname; + rel->relname = relname; + rel->schemaname = NULL; /* XXX wrong */ + rel->istemp = false; + createStmt->relation = rel; createStmt->tableElts = attrList; - createStmt->inhRelnames = NIL; + createStmt->inhRelations = NIL; createStmt->constraints = NIL; - createStmt->istemp = false; createStmt->hasoids = false; /* @@ -101,21 +104,24 @@ FormViewRetrieveRule(char *viewName, Query *viewParse) { RuleStmt *rule; char *rname; - Attr *attr; + RangeVar *rel; /* * Create a RuleStmt that corresponds to the suitable rewrite rule * args for DefineQueryRewrite(); */ - rule = makeNode(RuleStmt); rname = MakeRetrieveViewRuleName(viewName); - attr = makeNode(Attr); - attr->relname = pstrdup(viewName); + rel = makeNode(RangeVar); + rel->relname = pstrdup(viewName); + rel->inhOpt = INH_NO; + rel->alias = NULL; + + rule = makeNode(RuleStmt); + rule->relation = rel; rule->rulename = pstrdup(rname); rule->whereClause = NULL; rule->event = CMD_SELECT; - rule->object = attr; rule->instead = true; rule->actions = makeList1(viewParse); @@ -191,10 +197,10 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse) * table... OLD first, then NEW.... */ rt_entry1 = addRangeTableEntry(NULL, viewName, - makeAttr("*OLD*", NULL), + makeAlias("*OLD*", NIL), false, false); rt_entry2 = addRangeTableEntry(NULL, viewName, - makeAttr("*NEW*", NULL), + makeAlias("*NEW*", NIL), false, false); /* Must override addRangeTableEntry's default access-check flags */ rt_entry1->checkForRead = false; |
