Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 95ef6a3

Browse files
committed
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.
1 parent 8c9c8ca commit 95ef6a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2022
-1518
lines changed

doc/src/sgml/xfunc.sgml

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.49 2002/03/11 05:03:52 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.50 2002/03/21 16:00:28 tgl Exp $
33
-->
44

55
<chapter id="xfunc">
@@ -306,7 +306,8 @@ CREATE FUNCTION new_emp() RETURNS EMP AS '
306306
<para>
307307
The target list order must be exactly the same as
308308
that in which the columns appear in the table associated
309-
with the composite type.
309+
with the composite type. (Naming the columns, as we did above,
310+
is irrelevant to the system.)
310311
</para>
311312
</listitem>
312313
<listitem>
@@ -328,28 +329,46 @@ ERROR: function declared to return emp returns varchar instead of text at colum
328329
there are some unpleasant restrictions on how functions returning
329330
composite types can be used. Briefly, when calling a function that
330331
returns a row, we cannot retrieve the entire row. We must either
331-
project a single attribute out of the row or pass the entire row into
332+
extract a single attribute out of the row or pass the entire row into
332333
another function. (Trying to display the entire row value will yield
333334
a meaningless number.) For example,
334335

335336
<programlisting>
336-
SELECT name(new_emp());
337+
SELECT (new_emp()).name;
337338
</programlisting>
338339

339340
<screen>
340341
name
341342
------
342343
None
344+
</screen>
345+
346+
We need the extra parentheses to keep the parser from getting confused:
347+
348+
<screen>
349+
SELECT new_emp().name;
350+
ERROR: parser: parse error at or near "."
343351
</screen>
344352
</para>
345353

346354
<para>
347-
This example makes use of the
348-
function notation for projecting attributes. The simple way
349-
to explain this is that we can usually use the
355+
Another approach is to use
356+
functional notation for extracting attributes. The simple way
357+
to explain this is that we can use the
350358
notations <literal>attribute(table)</> and <literal>table.attribute</>
351359
interchangeably:
352360

361+
<programlisting>
362+
SELECT name(new_emp());
363+
</programlisting>
364+
365+
<screen>
366+
name
367+
------
368+
None
369+
</screen>
370+
</para>
371+
353372
<programlisting>
354373
--
355374
-- this is the same as:
@@ -367,19 +386,6 @@ SELECT name(EMP) AS youngster
367386
</screen>
368387
</para>
369388

370-
<para>
371-
The reason why, in general, we must use the function
372-
syntax for projecting attributes of function return
373-
values is that the parser just doesn't understand
374-
the dot syntax for projection when combined
375-
with function calls.
376-
377-
<screen>
378-
SELECT new_emp().name AS nobody;
379-
ERROR: parser: parse error at or near "."
380-
</screen>
381-
</para>
382-
383389
<para>
384390
Another way to use a function returning a row result is to declare a
385391
second function accepting a row type parameter, and pass the function

src/backend/catalog/aclchk.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.56 2002/03/06 06:09:24 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.57 2002/03/21 16:00:29 tgl Exp $
1212
*
1313
* NOTES
1414
* See acl.h.
@@ -200,7 +200,7 @@ ExecuteGrantStmt_Table(GrantStmt *stmt)
200200

201201
foreach(i, stmt->objects)
202202
{
203-
char *relname = strVal(lfirst(i));
203+
char *relname = ((RangeVar *) lfirst(i))->relname;
204204
Relation relation;
205205
HeapTuple tuple;
206206
Form_pg_class pg_class_tuple;

src/backend/catalog/heap.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.189 2002/03/20 19:43:34 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.190 2002/03/21 16:00:29 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -1728,7 +1728,7 @@ AddRelationRawConstraints(Relation rel,
17281728
/*
17291729
* Transform raw parsetree to executable expression.
17301730
*/
1731-
expr = transformExpr(pstate, cdef->raw_expr, EXPR_COLUMN_FIRST);
1731+
expr = transformExpr(pstate, cdef->raw_expr);
17321732

17331733
/*
17341734
* Make sure it yields a boolean result.
@@ -1863,7 +1863,7 @@ cookDefault(ParseState *pstate,
18631863
/*
18641864
* Transform raw parsetree to executable expression.
18651865
*/
1866-
expr = transformExpr(pstate, raw_default, EXPR_COLUMN_FIRST);
1866+
expr = transformExpr(pstate, raw_default);
18671867

18681868
/*
18691869
* Make sure default expr does not refer to any vars.

src/backend/commands/command.c

Lines changed: 103 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.161 2002/03/14 22:44:50 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.162 2002/03/21 16:00:31 tgl Exp $
1212
*
1313
* NOTES
1414
* The PerformAddAttribute() code, like most of the relation
@@ -33,7 +33,7 @@
3333
#include "catalog/pg_type.h"
3434
#include "commands/command.h"
3535
#include "commands/trigger.h"
36-
#include "commands/defrem.h" /* For add constraint unique, primary */
36+
#include "commands/defrem.h"
3737
#include "executor/execdefs.h"
3838
#include "executor/executor.h"
3939
#include "miscadmin.h"
@@ -44,7 +44,8 @@
4444
#include "parser/parse_expr.h"
4545
#include "parser/parse_oper.h"
4646
#include "parser/parse_relation.h"
47-
#include "parser/analyze.h" /* For add constraint unique, primary */
47+
#include "parser/analyze.h"
48+
#include "tcop/utility.h"
4849
#include "utils/acl.h"
4950
#include "utils/builtins.h"
5051
#include "utils/fmgroids.h"
@@ -1279,8 +1280,7 @@ AlterTableAddConstraint(char *relationName,
12791280
* Convert the A_EXPR in raw_expr into an
12801281
* EXPR
12811282
*/
1282-
expr = transformExpr(pstate, constr->raw_expr,
1283-
EXPR_COLUMN_FIRST);
1283+
expr = transformExpr(pstate, constr->raw_expr);
12841284

12851285
/*
12861286
* Make sure it yields a boolean result.
@@ -1366,7 +1366,7 @@ AlterTableAddConstraint(char *relationName,
13661366
List *list;
13671367
int count;
13681368

1369-
if (is_temp_rel_name(fkconstraint->pktable_name) &&
1369+
if (is_temp_rel_name(fkconstraint->pktable->relname) &&
13701370
!is_temp_rel_name(relationName))
13711371
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint.");
13721372

@@ -1375,10 +1375,10 @@ AlterTableAddConstraint(char *relationName,
13751375
* someone doesn't delete rows out from under us.
13761376
*/
13771377

1378-
pkrel = heap_openr(fkconstraint->pktable_name, AccessExclusiveLock);
1378+
pkrel = heap_openr(fkconstraint->pktable->relname, AccessExclusiveLock);
13791379
if (pkrel->rd_rel->relkind != RELKIND_RELATION)
13801380
elog(ERROR, "referenced table \"%s\" not a relation",
1381-
fkconstraint->pktable_name);
1381+
fkconstraint->pktable->relname);
13821382
heap_close(pkrel, NoLock);
13831383

13841384
/*
@@ -1417,7 +1417,7 @@ AlterTableAddConstraint(char *relationName,
14171417
else
14181418
trig.tgargs[0] = "<unknown>";
14191419
trig.tgargs[1] = (char *) relationName;
1420-
trig.tgargs[2] = fkconstraint->pktable_name;
1420+
trig.tgargs[2] = fkconstraint->pktable->relname;
14211421
trig.tgargs[3] = fkconstraint->match_type;
14221422
count = 4;
14231423
foreach(list, fkconstraint->fk_attrs)
@@ -1936,9 +1936,10 @@ LockTableCommand(LockStmt *lockstmt)
19361936
* at a time
19371937
*/
19381938

1939-
foreach(p, lockstmt->rellist)
1939+
foreach(p, lockstmt->relations)
19401940
{
1941-
char *relname = strVal(lfirst(p));
1941+
RangeVar *relation = lfirst(p);
1942+
char *relname = relation->relname;
19421943
int aclresult;
19431944
Relation rel;
19441945

@@ -1962,3 +1963,94 @@ LockTableCommand(LockStmt *lockstmt)
19621963
relation_close(rel, NoLock); /* close rel, keep lock */
19631964
}
19641965
}
1966+
1967+
1968+
/*
1969+
* CREATE SCHEMA
1970+
*/
1971+
void
1972+
CreateSchemaCommand(CreateSchemaStmt *stmt)
1973+
{
1974+
const char *schemaName = stmt->schemaname;
1975+
const char *authId = stmt->authid;
1976+
List *parsetree_list;
1977+
List *parsetree_item;
1978+
const char *owner_name;
1979+
Oid owner_userid;
1980+
Oid saved_userid;
1981+
1982+
saved_userid = GetUserId();
1983+
1984+
if (!authId)
1985+
{
1986+
owner_userid = saved_userid;
1987+
owner_name = GetUserName(owner_userid);
1988+
}
1989+
else if (superuser())
1990+
{
1991+
owner_name = authId;
1992+
/* The following will error out if user does not exist */
1993+
owner_userid = get_usesysid(owner_name);
1994+
/*
1995+
* Set the current user to the requested authorization so
1996+
* that objects created in the statement have the requested
1997+
* owner. (This will revert to session user on error or at
1998+
* the end of this routine.)
1999+
*/
2000+
SetUserId(owner_userid);
2001+
}
2002+
else /* not superuser */
2003+
{
2004+
owner_userid = saved_userid;
2005+
owner_name = GetUserName(owner_userid);
2006+
if (strcmp(authId, owner_name) != 0)
2007+
elog(ERROR, "CREATE SCHEMA: permission denied"
2008+
"\n\t\"%s\" is not a superuser, so cannot create a schema for \"%s\"",
2009+
owner_name, authId);
2010+
}
2011+
2012+
/* FIXME FENN: Create the schema here */
2013+
(void) schemaName; /* suppress compiler warning for now... */
2014+
2015+
/*
2016+
* Let commands in the schema-element-list know about the schema
2017+
*/
2018+
CommandCounterIncrement();
2019+
2020+
/*
2021+
* Examine the list of commands embedded in the CREATE SCHEMA command,
2022+
* and reorganize them into a sequentially executable order with no
2023+
* forward references. Note that the result is still a list of raw
2024+
* parsetrees in need of parse analysis --- we cannot, in general,
2025+
* run analyze.c on one statement until we have actually executed the
2026+
* prior ones.
2027+
*/
2028+
parsetree_list = analyzeCreateSchemaStmt(stmt);
2029+
2030+
/*
2031+
* Analyze and execute each command contained in the CREATE SCHEMA
2032+
*/
2033+
foreach(parsetree_item, parsetree_list)
2034+
{
2035+
Node *parsetree = (Node *) lfirst(parsetree_item);
2036+
List *querytree_list,
2037+
*querytree_item;
2038+
2039+
querytree_list = parse_analyze(parsetree, NULL);
2040+
2041+
foreach(querytree_item, querytree_list)
2042+
{
2043+
Query *querytree = (Query *) lfirst(querytree_item);
2044+
2045+
/* schemas should contain only utility stmts */
2046+
Assert(querytree->commandType == CMD_UTILITY);
2047+
/* do this step */
2048+
ProcessUtility(querytree->utilityStmt, None, NULL);
2049+
/* make sure later steps can see the object created here */
2050+
CommandCounterIncrement();
2051+
}
2052+
}
2053+
2054+
/* Reset current user */
2055+
SetUserId(saved_userid);
2056+
}

src/backend/commands/creatinh.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.88 2002/03/20 19:43:42 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.89 2002/03/21 16:00:31 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -69,7 +69,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
6969
* Truncate relname to appropriate length (probably a waste of time,
7070
* as parser should have done this already).
7171
*/
72-
StrNCpy(relname, stmt->relname, NAMEDATALEN);
72+
StrNCpy(relname, (stmt->relation)->relname, NAMEDATALEN);
7373

7474
/*
7575
* Merge domain attributes into the known columns before processing table
@@ -82,8 +82,9 @@ DefineRelation(CreateStmt *stmt, char relkind)
8282
* Look up inheritance ancestors and generate relation schema,
8383
* including inherited attributes.
8484
*/
85-
schema = MergeAttributes(schema, stmt->inhRelnames, stmt->istemp,
86-
&inheritOids, &old_constraints, &parentHasOids);
85+
schema = MergeAttributes(schema, stmt->inhRelations,
86+
stmt->relation->istemp,
87+
&inheritOids, &old_constraints, &parentHasOids);
8788

8889
numberOfAttributes = length(schema);
8990
if (numberOfAttributes <= 0)
@@ -147,7 +148,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
147148
relationId = heap_create_with_catalog(relname, descriptor,
148149
relkind,
149150
stmt->hasoids || parentHasOids,
150-
stmt->istemp,
151+
stmt->relation->istemp,
151152
allowSystemTableMods);
152153

153154
StoreCatalogInheritance(relationId, inheritOids);
@@ -414,16 +415,19 @@ MergeAttributes(List *schema, List *supers, bool istemp,
414415

415416
/*
416417
* Reject duplicate names in the list of parents, too.
418+
*
419+
* XXX needs to be smarter about schema-qualified table names.
417420
*/
418421
foreach(entry, supers)
419422
{
420423
List *rest;
421424

422425
foreach(rest, lnext(entry))
423426
{
424-
if (strcmp(strVal(lfirst(entry)), strVal(lfirst(rest))) == 0)
427+
if (strcmp(((RangeVar *) lfirst(entry))->relname,
428+
((RangeVar *) lfirst(rest))->relname) == 0)
425429
elog(ERROR, "CREATE TABLE: inherited relation \"%s\" duplicated",
426-
strVal(lfirst(entry)));
430+
((RangeVar *) lfirst(entry))->relname);
427431
}
428432
}
429433

@@ -435,7 +439,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
435439
child_attno = 0;
436440
foreach(entry, supers)
437441
{
438-
char *name = strVal(lfirst(entry));
442+
char *name = ((RangeVar *) lfirst(entry))->relname;
439443
Relation relation;
440444
TupleDesc tupleDesc;
441445
TupleConstr *constr;

0 commit comments

Comments
 (0)