diff options
author | Stephen Frost <sfrost@snowman.net> | 2013-07-18 17:10:16 -0400 |
---|---|---|
committer | Stephen Frost <sfrost@snowman.net> | 2013-07-18 17:10:16 -0400 |
commit | 4cbe3ac3e86790d05c569de4585e5075a62a9b41 (patch) | |
tree | 8adc929520d4103b4493c0c23bcb7d2b2c2a5a4d /src/include | |
parent | 6f9e39bc9993c18686f0950f9b9657c7c97c7450 (diff) | |
download | postgresql-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.h | 2 | ||||
-rw-r--r-- | src/include/commands/view.h | 2 | ||||
-rw-r--r-- | src/include/executor/executor.h | 2 | ||||
-rw-r--r-- | src/include/nodes/execnodes.h | 4 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 1 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 23 | ||||
-rw-r--r-- | src/include/nodes/plannodes.h | 1 | ||||
-rw-r--r-- | src/include/optimizer/planmain.h | 3 | ||||
-rw-r--r-- | src/include/rewrite/rewriteHandler.h | 4 | ||||
-rw-r--r-- | src/include/utils/rel.h | 34 |
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. */ |