diff options
author | Neil Conway <neilc@samurai.com> | 2005-02-02 06:36:02 +0000 |
---|---|---|
committer | Neil Conway <neilc@samurai.com> | 2005-02-02 06:36:02 +0000 |
commit | 73f630500bcb3034f65dc5af6cb410b3221fe717 (patch) | |
tree | 7efa24efb97e3e0b2afef407eb6893185c067bdf /src/backend/commands/view.c | |
parent | f94197ef35e3f7254acabdc3b8741b2b94e44d5c (diff) | |
download | postgresql-73f630500bcb3034f65dc5af6cb410b3221fe717.tar.gz postgresql-73f630500bcb3034f65dc5af6cb410b3221fe717.zip |
Add support for temporary views, including documentation and regression
tests. Contributed by Koju Iijima, review from Neil Conway, Gavin Sherry
and Tom Lane.
Also, fix error in description of WITH CHECK OPTION clause in the CREATE
VIEW reference page: it should be "CASCADED", not "CASCADE".
Diffstat (limited to 'src/backend/commands/view.c')
-rw-r--r-- | src/backend/commands/view.c | 74 |
1 files changed, 71 insertions, 3 deletions
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 270b9f8b133..10caef1375b 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.86 2004/12/31 21:59:42 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.87 2005/02/02 06:36:00 neilc Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ #include "commands/view.h" #include "miscadmin.h" #include "nodes/makefuncs.h" +#include "optimizer/clauses.h" #include "parser/parse_relation.h" #include "rewrite/rewriteDefine.h" #include "rewrite/rewriteManip.h" @@ -30,7 +31,55 @@ static void checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc); +static bool isViewOnTempTable_walker(Node *node, void *context); +/*--------------------------------------------------------------------- + * isViewOnTempTable + * + * Returns true iff any of the relations underlying this view are + * temporary tables. + *--------------------------------------------------------------------- + */ +static bool +isViewOnTempTable(Query *viewParse) +{ + return isViewOnTempTable_walker((Node *) viewParse, NULL); +} + +static bool +isViewOnTempTable_walker(Node *node, void *context) +{ + if (node == NULL) + return false; + + if (IsA(node, Query)) + { + Query *query = (Query *) node; + ListCell *rtable; + + foreach (rtable, query->rtable) + { + RangeTblEntry *rte = lfirst(rtable); + if (rte->rtekind == RTE_RELATION) + { + Relation rel = heap_open(rte->relid, AccessShareLock); + bool istemp = rel->rd_istemp; + heap_close(rel, AccessShareLock); + if (istemp) + return true; + } + } + + return query_tree_walker(query, + isViewOnTempTable_walker, + context, + QTW_IGNORE_JOINALIASES); + } + + return expression_tree_walker(node, + isViewOnTempTable_walker, + context); +} /*--------------------------------------------------------------------- * DefineVirtualRelation @@ -118,6 +167,13 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) RelationGetRelationName(rel)); /* + * Due to the namespace visibility rules for temporary + * objects, we should only end up replacing a temporary view + * with another temporary view, and vice versa. + */ + Assert(relation->istemp == rel->rd_istemp); + + /* * Create a tuple descriptor to compare against the existing view, * and verify it matches. */ @@ -326,17 +382,29 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse) *------------------------------------------------------------------- */ void -DefineView(const RangeVar *view, Query *viewParse, bool replace) +DefineView(RangeVar *view, Query *viewParse, bool replace) { Oid viewOid; /* + * If the user didn't explicitly ask for a temporary view, check + * whether we need one implicitly. + */ + if (!view->istemp) + { + view->istemp = isViewOnTempTable(viewParse); + if (view->istemp) + ereport(NOTICE, + (errmsg("view \"%s\" will be a temporary view", + view->relname))); + } + + /* * Create the view relation * * NOTE: if it already exists and replace is false, the xact will be * aborted. */ - viewOid = DefineVirtualRelation(view, viewParse->targetList, replace); /* |