aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/command.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-03-21 16:02:16 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-03-21 16:02:16 +0000
commit95ef6a344821655ce4d0a74999ac49dd6af6d342 (patch)
treedf484a4c9dde9827894ab707917c001a1f376749 /src/backend/commands/command.c
parent8c9c8ca2b57e4edef218245ccdc9eef7c06425d8 (diff)
downloadpostgresql-95ef6a344821655ce4d0a74999ac49dd6af6d342.tar.gz
postgresql-95ef6a344821655ce4d0a74999ac49dd6af6d342.zip
First phase of SCHEMA changes, concentrating on fixing the grammar and
the parsetree representation. As yet we don't *do* anything with schema names, just drop 'em on the floor; but you can enter schema-compatible command syntax, and there's even a primitive CREATE SCHEMA command. No doc updates yet, except to note that you can now extract a field from a function-returning-row's result with (foo(...)).fieldname.
Diffstat (limited to 'src/backend/commands/command.c')
-rw-r--r--src/backend/commands/command.c114
1 files changed, 103 insertions, 11 deletions
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index c32be8b02f3..5821e1d1036 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);
+}