PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
view.h File Reference
Include dependency graph for view.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void validateWithCheckOption (char *value)
 
ObjectAddress DefineView (ViewStmt *stmt, const char *queryString, int stmt_location, int stmt_len)
 
void StoreViewQuery (Oid viewOid, Query *viewParse, bool replace)
 

Function Documentation

ObjectAddress DefineView ( ViewStmt stmt,
const char *  queryString,
int  stmt_location,
int  stmt_len 
)

Definition at line 417 of file view.c.

References ViewStmt::aliases, CASCADED_CHECK_OPTION, castNode, CMD_SELECT, Query::commandType, copyObject(), DefineVirtualRelation(), DefElem::defname, elog, ereport, errcode(), errhint(), errmsg(), ERROR, Query::hasModifyingCTE, IsA, isQueryUsingTempRelation(), lappend(), lfirst, list_head(), lnext, LOCAL_CHECK_OPTION, makeDefElem(), makeNode, makeString(), NIL, NOTICE, NULL, ViewStmt::options, parse_analyze(), pg_strcasecmp(), pstrdup(), ViewStmt::query, RangeVar::relname, RangeVar::relpersistence, RELPERSISTENCE_PERMANENT, RELPERSISTENCE_TEMP, RELPERSISTENCE_UNLOGGED, ViewStmt::replace, TargetEntry::resjunk, TargetEntry::resname, RawStmt::stmt, RawStmt::stmt_len, RawStmt::stmt_location, strVal, Query::targetList, Query::utilityStmt, ViewStmt::view, view_query_is_auto_updatable(), and ViewStmt::withCheckOption.

Referenced by ProcessUtilitySlow().

419 {
420  RawStmt *rawstmt;
421  Query *viewParse;
422  RangeVar *view;
423  ListCell *cell;
424  bool check_option;
425  ObjectAddress address;
426 
427  /*
428  * Run parse analysis to convert the raw parse tree to a Query. Note this
429  * also acquires sufficient locks on the source table(s).
430  *
431  * Since parse analysis scribbles on its input, copy the raw parse tree;
432  * this ensures we don't corrupt a prepared statement, for example.
433  */
434  rawstmt = makeNode(RawStmt);
435  rawstmt->stmt = (Node *) copyObject(stmt->query);
436  rawstmt->stmt_location = stmt_location;
437  rawstmt->stmt_len = stmt_len;
438 
439  viewParse = parse_analyze(rawstmt, queryString, NULL, 0);
440 
441  /*
442  * The grammar should ensure that the result is a single SELECT Query.
443  * However, it doesn't forbid SELECT INTO, so we have to check for that.
444  */
445  if (!IsA(viewParse, Query))
446  elog(ERROR, "unexpected parse analysis result");
447  if (viewParse->utilityStmt != NULL &&
448  IsA(viewParse->utilityStmt, CreateTableAsStmt))
449  ereport(ERROR,
450  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
451  errmsg("views must not contain SELECT INTO")));
452  if (viewParse->commandType != CMD_SELECT)
453  elog(ERROR, "unexpected parse analysis result");
454 
455  /*
456  * Check for unsupported cases. These tests are redundant with ones in
457  * DefineQueryRewrite(), but that function will complain about a bogus ON
458  * SELECT rule, and we'd rather the message complain about a view.
459  */
460  if (viewParse->hasModifyingCTE)
461  ereport(ERROR,
462  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
463  errmsg("views must not contain data-modifying statements in WITH")));
464 
465  /*
466  * If the user specified the WITH CHECK OPTION, add it to the list of
467  * reloptions.
468  */
469  if (stmt->withCheckOption == LOCAL_CHECK_OPTION)
470  stmt->options = lappend(stmt->options,
471  makeDefElem("check_option",
472  (Node *) makeString("local"), -1));
473  else if (stmt->withCheckOption == CASCADED_CHECK_OPTION)
474  stmt->options = lappend(stmt->options,
475  makeDefElem("check_option",
476  (Node *) makeString("cascaded"), -1));
477 
478  /*
479  * Check that the view is auto-updatable if WITH CHECK OPTION was
480  * specified.
481  */
482  check_option = false;
483 
484  foreach(cell, stmt->options)
485  {
486  DefElem *defel = (DefElem *) lfirst(cell);
487 
488  if (pg_strcasecmp(defel->defname, "check_option") == 0)
489  check_option = true;
490  }
491 
492  /*
493  * If the check option is specified, look to see if the view is actually
494  * auto-updatable or not.
495  */
496  if (check_option)
497  {
498  const char *view_updatable_error =
499  view_query_is_auto_updatable(viewParse, true);
500 
501  if (view_updatable_error)
502  ereport(ERROR,
503  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
504  errmsg("WITH CHECK OPTION is supported only on automatically updatable views"),
505  errhint("%s", view_updatable_error)));
506  }
507 
508  /*
509  * If a list of column names was given, run through and insert these into
510  * the actual query tree. - thomas 2000-03-08
511  */
512  if (stmt->aliases != NIL)
513  {
514  ListCell *alist_item = list_head(stmt->aliases);
515  ListCell *targetList;
516 
517  foreach(targetList, viewParse->targetList)
518  {
519  TargetEntry *te = castNode(TargetEntry, lfirst(targetList));
520 
521  /* junk columns don't get aliases */
522  if (te->resjunk)
523  continue;
524  te->resname = pstrdup(strVal(lfirst(alist_item)));
525  alist_item = lnext(alist_item);
526  if (alist_item == NULL)
527  break; /* done assigning aliases */
528  }
529 
530  if (alist_item != NULL)
531  ereport(ERROR,
532  (errcode(ERRCODE_SYNTAX_ERROR),
533  errmsg("CREATE VIEW specifies more column "
534  "names than columns")));
535  }
536 
537  /* Unlogged views are not sensible. */
539  ereport(ERROR,
540  (errcode(ERRCODE_SYNTAX_ERROR),
541  errmsg("views cannot be unlogged because they do not have storage")));
542 
543  /*
544  * If the user didn't explicitly ask for a temporary view, check whether
545  * we need one implicitly. We allow TEMP to be inserted automatically as
546  * long as the CREATE command is consistent with that --- no explicit
547  * schema name.
548  */
549  view = copyObject(stmt->view); /* don't corrupt original command */
551  && isQueryUsingTempRelation(viewParse))
552  {
554  ereport(NOTICE,
555  (errmsg("view \"%s\" will be a temporary view",
556  view->relname)));
557  }
558 
559  /*
560  * Create the view relation
561  *
562  * NOTE: if it already exists and replace is false, the xact will be
563  * aborted.
564  */
565  address = DefineVirtualRelation(view, viewParse->targetList,
566  stmt->replace, stmt->options, viewParse);
567 
568  return address;
569 }
Value * makeString(char *str)
Definition: value.c:53
bool replace
Definition: parsenodes.h:2884
#define NIL
Definition: pg_list.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
int errhint(const char *fmt,...)
Definition: elog.c:987
bool isQueryUsingTempRelation(Query *query)
#define RELPERSISTENCE_UNLOGGED
Definition: pg_class.h:171
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
char * pstrdup(const char *in)
Definition: mcxt.c:1165
Definition: nodes.h:508
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
char * resname
Definition: primnodes.h:1332
Node * utilityStmt
Definition: parsenodes.h:111
DefElem * makeDefElem(char *name, Node *arg, int location)
Definition: makefuncs.c:543
RangeVar * view
Definition: parsenodes.h:2881
List * targetList
Definition: parsenodes.h:131
Query * parse_analyze(RawStmt *parseTree, const char *sourceText, Oid *paramTypes, int numParams)
Definition: analyze.c:96
void * copyObject(const void *from)
Definition: copyfuncs.c:4475
#define RELPERSISTENCE_PERMANENT
Definition: pg_class.h:170
char * relname
Definition: primnodes.h:67
bool resjunk
Definition: primnodes.h:1337
#define ERROR
Definition: elog.h:43
List * aliases
Definition: parsenodes.h:2882
Node * stmt
Definition: parsenodes.h:1337
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define lnext(lc)
Definition: pg_list.h:105
#define ereport(elevel, rest)
Definition: elog.h:122
List * lappend(List *list, void *datum)
Definition: list.c:128
int stmt_len
Definition: parsenodes.h:1339
int stmt_location
Definition: parsenodes.h:1338
#define NOTICE
Definition: elog.h:37
CmdType commandType
Definition: parsenodes.h:103
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
List * options
Definition: parsenodes.h:2885
#define lfirst(lc)
Definition: pg_list.h:106
static ObjectAddress DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, List *options, Query *viewParse)
Definition: view.c:67
char relpersistence
Definition: primnodes.h:70
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool hasModifyingCTE
Definition: parsenodes.h:122
char * defname
Definition: parsenodes.h:675
ViewCheckOption withCheckOption
Definition: parsenodes.h:2886
#define elog
Definition: elog.h:219
Node * query
Definition: parsenodes.h:2883
#define RELPERSISTENCE_TEMP
Definition: pg_class.h:172
const char * view_query_is_auto_updatable(Query *viewquery, bool check_cols)
void StoreViewQuery ( Oid  viewOid,
Query viewParse,
bool  replace 
)

Definition at line 575 of file view.c.

References DefineViewRules(), and UpdateRangeTableOfViewParse().

Referenced by create_ctas_internal(), and DefineVirtualRelation().

576 {
577  /*
578  * The range table of 'viewParse' does not contain entries for the "OLD"
579  * and "NEW" relations. So... add them!
580  */
581  viewParse = UpdateRangeTableOfViewParse(viewOid, viewParse);
582 
583  /*
584  * Now create the rules associated with the view.
585  */
586  DefineViewRules(viewOid, viewParse, replace);
587 }
static Query * UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
Definition: view.c:360
static void DefineViewRules(Oid viewOid, Query *viewParse, bool replace)
Definition: view.c:323
void validateWithCheckOption ( char *  value)

Definition at line 46 of file view.c.

References ereport, errcode(), errdetail(), errmsg(), ERROR, NULL, and pg_strcasecmp().

47 {
48  if (value == NULL ||
49  (pg_strcasecmp(value, "local") != 0 &&
50  pg_strcasecmp(value, "cascaded") != 0))
51  {
52  ereport(ERROR,
53  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
54  errmsg("invalid value for \"check_option\" option"),
55  errdetail("Valid values are \"local\" and \"cascaded\".")));
56  }
57 }
static struct @76 value
int errcode(int sqlerrcode)
Definition: elog.c:575
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797