#include "nodes/parsenodes.h"

Go to the source code of this file.
Functions | |
| Oid | DefineView (ViewStmt *stmt, const char *queryString) |
| void | StoreViewQuery (Oid viewOid, Query *viewParse, bool replace) |
Definition at line 372 of file view.c.
References ViewStmt::aliases, Assert, CMD_SELECT, CommandCounterIncrement(), Query::commandType, copyObject(), DefineVirtualRelation(), elog, ereport, errcode(), errmsg(), ERROR, Query::hasModifyingCTE, IsA, isQueryUsingTempRelation(), lfirst, list_head(), lnext, NIL, NOTICE, NULL, ViewStmt::options, parse_analyze(), pstrdup(), ViewStmt::query, RangeVar::relname, RangeVar::relpersistence, RELPERSISTENCE_PERMANENT, RELPERSISTENCE_UNLOGGED, ViewStmt::replace, TargetEntry::resjunk, TargetEntry::resname, StoreViewQuery(), strVal, Query::targetList, Query::utilityStmt, and ViewStmt::view.
Referenced by ProcessUtilitySlow().
{
Query *viewParse;
Oid viewOid;
RangeVar *view;
/*
* Run parse analysis to convert the raw parse tree to a Query. Note this
* also acquires sufficient locks on the source table(s).
*
* Since parse analysis scribbles on its input, copy the raw parse tree;
* this ensures we don't corrupt a prepared statement, for example.
*/
viewParse = parse_analyze((Node *) copyObject(stmt->query),
queryString, NULL, 0);
/*
* The grammar should ensure that the result is a single SELECT Query.
* However, it doesn't forbid SELECT INTO, so we have to check for that.
*/
if (!IsA(viewParse, Query))
elog(ERROR, "unexpected parse analysis result");
if (viewParse->utilityStmt != NULL &&
IsA(viewParse->utilityStmt, CreateTableAsStmt))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("views must not contain SELECT INTO")));
if (viewParse->commandType != CMD_SELECT ||
viewParse->utilityStmt != NULL)
elog(ERROR, "unexpected parse analysis result");
/*
* Check for unsupported cases. These tests are redundant with ones in
* DefineQueryRewrite(), but that function will complain about a bogus ON
* SELECT rule, and we'd rather the message complain about a view.
*/
if (viewParse->hasModifyingCTE)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("views must not contain data-modifying statements in WITH")));
/*
* If a list of column names was given, run through and insert these into
* the actual query tree. - thomas 2000-03-08
*/
if (stmt->aliases != NIL)
{
ListCell *alist_item = list_head(stmt->aliases);
ListCell *targetList;
foreach(targetList, viewParse->targetList)
{
TargetEntry *te = (TargetEntry *) lfirst(targetList);
Assert(IsA(te, TargetEntry));
/* junk columns don't get aliases */
if (te->resjunk)
continue;
te->resname = pstrdup(strVal(lfirst(alist_item)));
alist_item = lnext(alist_item);
if (alist_item == NULL)
break; /* done assigning aliases */
}
if (alist_item != NULL)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("CREATE VIEW specifies more column "
"names than columns")));
}
/* Unlogged views are not sensible. */
if (stmt->view->relpersistence == RELPERSISTENCE_UNLOGGED)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("views cannot be unlogged because they do not have storage")));
/*
* If the user didn't explicitly ask for a temporary view, check whether
* we need one implicitly. We allow TEMP to be inserted automatically as
* long as the CREATE command is consistent with that --- no explicit
* schema name.
*/
view = copyObject(stmt->view); /* don't corrupt original command */
if (view->relpersistence == RELPERSISTENCE_PERMANENT
&& isQueryUsingTempRelation(viewParse))
{
view->relpersistence = RELPERSISTENCE_TEMP;
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,
stmt->replace, stmt->options);
/*
* The relation we have just created is not visible to any other commands
* running with the same transaction & command id. So, increment the
* command id counter (but do NOT pfree any memory!!!!)
*/
CommandCounterIncrement();
StoreViewQuery(viewOid, viewParse, stmt->replace);
return viewOid;
}
Definition at line 490 of file view.c.
References DefineViewRules(), and UpdateRangeTableOfViewParse().
Referenced by DefineView(), and intorel_startup().
{
/*
* The range table of 'viewParse' does not contain entries for the "OLD"
* and "NEW" relations. So... add them!
*/
viewParse = UpdateRangeTableOfViewParse(viewOid, viewParse);
/*
* Now create the rules associated with the view.
*/
DefineViewRules(viewOid, viewParse, replace);
}
1.7.1