aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorStephen Frost <sfrost@snowman.net>2013-07-18 17:10:16 -0400
committerStephen Frost <sfrost@snowman.net>2013-07-18 17:10:16 -0400
commit4cbe3ac3e86790d05c569de4585e5075a62a9b41 (patch)
tree8adc929520d4103b4493c0c23bcb7d2b2c2a5a4d /src/include
parent6f9e39bc9993c18686f0950f9b9657c7c97c7450 (diff)
downloadpostgresql-4cbe3ac3e86790d05c569de4585e5075a62a9b41.tar.gz
postgresql-4cbe3ac3e86790d05c569de4585e5075a62a9b41.zip
WITH CHECK OPTION support for auto-updatable VIEWs
For simple views which are automatically updatable, this patch allows the user to specify what level of checking should be done on records being inserted or updated. For 'LOCAL CHECK', new tuples are validated against the conditionals of the view they are being inserted into, while for 'CASCADED CHECK' the new tuples are validated against the conditionals for all views involved (from the top down). This option is part of the SQL specification. Dean Rasheed, reviewed by Pavel Stehule
Diffstat (limited to 'src/include')
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/commands/view.h2
-rw-r--r--src/include/executor/executor.h2
-rw-r--r--src/include/nodes/execnodes.h4
-rw-r--r--src/include/nodes/nodes.h1
-rw-r--r--src/include/nodes/parsenodes.h23
-rw-r--r--src/include/nodes/plannodes.h1
-rw-r--r--src/include/optimizer/planmain.h3
-rw-r--r--src/include/rewrite/rewriteHandler.h4
-rw-r--r--src/include/utils/rel.h34
10 files changed, 74 insertions, 2 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index e0177369242..d9404dafc16 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201307161
+#define CATALOG_VERSION_NO 201307181
#endif
diff --git a/src/include/commands/view.h b/src/include/commands/view.h
index 431be94a7d5..e9b4b5d2e18 100644
--- a/src/include/commands/view.h
+++ b/src/include/commands/view.h
@@ -16,6 +16,8 @@
#include "nodes/parsenodes.h"
+extern void validateWithCheckOption(char *value);
+
extern Oid DefineView(ViewStmt *stmt, const char *queryString);
extern void StoreViewQuery(Oid viewOid, Query *viewParse, bool replace);
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index bc215d6c7d5..75841c83e44 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -191,6 +191,8 @@ extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
extern void ExecConstraints(ResultRelInfo *resultRelInfo,
TupleTableSlot *slot, EState *estate);
+extern void ExecWithCheckOptions(ResultRelInfo *resultRelInfo,
+ TupleTableSlot *slot, EState *estate);
extern ExecRowMark *ExecFindRowMark(EState *estate, Index rti);
extern ExecAuxRowMark *ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist);
extern TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate,
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 5de5db75821..298af26e962 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -303,6 +303,8 @@ typedef struct JunkFilter
* TrigInstrument optional runtime measurements for triggers
* FdwRoutine FDW callback functions, if foreign table
* FdwState available to save private state of FDW
+ * WithCheckOptions list of WithCheckOption's for views
+ * WithCheckOptionExprs list of WithCheckOption expr states
* ConstraintExprs array of constraint-checking expr states
* junkFilter for removing junk attributes from tuples
* projectReturning for computing a RETURNING list
@@ -322,6 +324,8 @@ typedef struct ResultRelInfo
Instrumentation *ri_TrigInstrument;
struct FdwRoutine *ri_FdwRoutine;
void *ri_FdwState;
+ List *ri_WithCheckOptions;
+ List *ri_WithCheckOptionExprs;
List **ri_ConstraintExprs;
JunkFilter *ri_junkFilter;
ProjectionInfo *ri_projectReturning;
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 0d5c007f935..78368c63c1b 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -388,6 +388,7 @@ typedef enum NodeTag
T_Constraint,
T_DefElem,
T_RangeTblEntry,
+ T_WithCheckOption,
T_SortGroupClause,
T_WindowClause,
T_PrivGrantee,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 0cefb715055..9415e2c636e 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -128,6 +128,8 @@ typedef struct Query
List *targetList; /* target list (of TargetEntry) */
+ List *withCheckOptions; /* a list of WithCheckOption's */
+
List *returningList; /* return-values list (of TargetEntry) */
List *groupClause; /* a list of SortGroupClause's */
@@ -784,6 +786,19 @@ typedef struct RangeTblEntry
} RangeTblEntry;
/*
+ * WithCheckOption -
+ * representation of WITH CHECK OPTION checks to be applied to new tuples
+ * when inserting/updating an auto-updatable view.
+ */
+typedef struct WithCheckOption
+{
+ NodeTag type;
+ char *viewname; /* name of view that specified the WCO */
+ Node *qual; /* constraint qual to check */
+ bool cascaded; /* true = WITH CASCADED CHECK OPTION */
+} WithCheckOption;
+
+/*
* SortGroupClause -
* representation of ORDER BY, GROUP BY, PARTITION BY,
* DISTINCT, DISTINCT ON items
@@ -2333,6 +2348,13 @@ typedef struct AlterEnumStmt
* Create View Statement
* ----------------------
*/
+typedef enum ViewCheckOption
+{
+ NO_CHECK_OPTION,
+ LOCAL_CHECK_OPTION,
+ CASCADED_CHECK_OPTION
+} ViewCheckOption;
+
typedef struct ViewStmt
{
NodeTag type;
@@ -2341,6 +2363,7 @@ typedef struct ViewStmt
Node *query; /* the SELECT query */
bool replace; /* replace an existing view? */
List *options; /* options from WITH clause */
+ ViewCheckOption withCheckOption; /* WITH CHECK OPTION */
} ViewStmt;
/* ----------------------
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 841701ed98a..aa4f12cec55 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -172,6 +172,7 @@ typedef struct ModifyTable
List *resultRelations; /* integer list of RT indexes */
int resultRelIndex; /* index of first resultRel in plan's list */
List *plans; /* plan(s) producing source data */
+ List *withCheckOptionLists; /* per-target-table WCO lists */
List *returningLists; /* per-target-table RETURNING tlists */
List *fdwPrivLists; /* per-target-table FDW private data lists */
List *rowMarks; /* PlanRowMarks (non-locking only) */
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index 33eaf326272..bd6841f6cdb 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -85,7 +85,8 @@ extern Result *make_result(PlannerInfo *root, List *tlist,
Node *resconstantqual, Plan *subplan);
extern ModifyTable *make_modifytable(PlannerInfo *root,
CmdType operation, bool canSetTag,
- List *resultRelations, List *subplans, List *returningLists,
+ List *resultRelations, List *subplans,
+ List *withCheckOptionLists, List *returningLists,
List *rowMarks, int epqParam);
extern bool is_projection_capable_plan(Plan *plan);
diff --git a/src/include/rewrite/rewriteHandler.h b/src/include/rewrite/rewriteHandler.h
index 1831de46406..f0604b0dc88 100644
--- a/src/include/rewrite/rewriteHandler.h
+++ b/src/include/rewrite/rewriteHandler.h
@@ -21,6 +21,10 @@ extern List *QueryRewrite(Query *parsetree);
extern void AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown);
extern Node *build_column_default(Relation rel, int attrno);
+extern Query *get_view_query(Relation view);
+extern const char *view_is_auto_updatable(Relation view);
+extern const char *view_query_is_auto_updatable(Query *viewquery,
+ bool security_barrier);
extern int relation_is_updatable(Oid reloid, bool include_triggers);
#endif /* REWRITEHANDLER_H */
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 58cc3f7ea1a..589c9a81b69 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -208,6 +208,7 @@ typedef struct StdRdOptions
int fillfactor; /* page fill factor in percent (0..100) */
AutoVacOpts autovacuum; /* autovacuum-related options */
bool security_barrier; /* for views */
+ int check_option_offset; /* for views */
} StdRdOptions;
#define HEAP_MIN_FILLFACTOR 10
@@ -244,6 +245,39 @@ typedef struct StdRdOptions
((StdRdOptions *) (relation)->rd_options)->security_barrier : false)
/*
+ * RelationHasCheckOption
+ * Returns true if the relation is a view defined with either the local
+ * or the cascaded check option.
+ */
+#define RelationHasCheckOption(relation) \
+ ((relation)->rd_options && \
+ ((StdRdOptions *) (relation)->rd_options)->check_option_offset != 0)
+
+/*
+ * RelationHasLocalCheckOption
+ * Returns true if the relation is a view defined with the local check
+ * option.
+ */
+#define RelationHasLocalCheckOption(relation) \
+ ((relation)->rd_options && \
+ ((StdRdOptions *) (relation)->rd_options)->check_option_offset != 0 ? \
+ strcmp((char *) (relation)->rd_options + \
+ ((StdRdOptions *) (relation)->rd_options)->check_option_offset, \
+ "local") == 0 : false)
+
+/*
+ * RelationHasCascadedCheckOption
+ * Returns true if the relation is a view defined with the cascaded check
+ * option.
+ */
+#define RelationHasCascadedCheckOption(relation) \
+ ((relation)->rd_options && \
+ ((StdRdOptions *) (relation)->rd_options)->check_option_offset != 0 ? \
+ strcmp((char *) (relation)->rd_options + \
+ ((StdRdOptions *) (relation)->rd_options)->check_option_offset, \
+ "cascaded") == 0 : false)
+
+/*
* RelationIsValid
* True iff relation descriptor is valid.
*/