@@ -24,6 +24,12 @@ PostgreSQL documentation
2424CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW <replaceable class="PARAMETER">name</replaceable> [ ( <replaceable class="PARAMETER">column_name</replaceable> [, ...] ) ]
2525 [ WITH ( <replaceable class="PARAMETER">view_option_name</replaceable> [= <replaceable class="PARAMETER">view_option_value</replaceable>] [, ... ] ) ]
2626 AS <replaceable class="PARAMETER">query</replaceable>
27+ [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
28+
29+ <phrase>where <replaceable class="parameter">view_option_name</replaceable> can be one of:</phrase>
30+
31+ security_barrier [ <replaceable class="parameter">boolean</replaceable> ]
32+ check_option [ <replaceable class="parameter">text</replaceable> (<literal>local</literal> or <literal>cascaded</literal>) ]
2733</synopsis>
2834 </refsynopsisdiv>
2935
@@ -120,10 +126,33 @@ CREATE VIEW <replaceable>name</> AS WITH RECURSIVE <replaceable>name</> (<replac
120126 <term><literal>WITH ( <replaceable class="PARAMETER">view_option_name</replaceable> [= <replaceable class="PARAMETER">view_option_value</replaceable>] [, ... ] )</literal></term>
121127 <listitem>
122128 <para>
123- This clause specifies optional parameters for a view; currently, the
124- only supported parameter name is <literal>security_barrier</literal>,
125- which should be enabled when a view is intended to provide row-level
126- security. See <xref linkend="rules-privileges"> for full details.
129+ This clause specifies optional parameters for a view; the following
130+ parameters are supported:
131+
132+ <variablelist>
133+ <varlistentry>
134+ <term><literal>security_barrier(boolean)</literal></term>
135+ <listitem>
136+ <para>
137+ This should be used if the view is intended to provide row-level
138+ security. See <xref linkend="rules-privileges"> for full details.
139+ </para>
140+ </listitem>
141+ </varlistentry>
142+
143+ <varlistentry>
144+ <term><literal>check_option(text)</literal></term>
145+ <listitem>
146+ <para>
147+ This parameter may be either <literal>local</> or
148+ <literal>cascaded</>, and is equivalent to specifying
149+ <literal>WITH [ CASCADED | LOCAL ] CHECK OPTION</> (see below).
150+ This option can be changed on existing views using <xref
151+ linkend="sql-alterview">.
152+ </para>
153+ </listitem>
154+ </varlistentry>
155+ </variablelist>
127156 </para>
128157 </listitem>
129158 </varlistentry>
@@ -138,6 +167,77 @@ CREATE VIEW <replaceable>name</> AS WITH RECURSIVE <replaceable>name</> (<replac
138167 </para>
139168 </listitem>
140169 </varlistentry>
170+
171+ <varlistentry>
172+ <term><literal>WITH [ CASCADED | LOCAL ] CHECK OPTION</literal></term>
173+ <listitem>
174+ <para>
175+ <indexterm zone="SQL-CREATEVIEW">
176+ <primary>CHECK OPTION</primary>
177+ </indexterm>
178+ <indexterm zone="SQL-CREATEVIEW">
179+ <primary>WITH CHECK OPTION</primary>
180+ </indexterm>
181+ This option controls the behavior of automatically updatable views. When
182+ this option is specified, <command>INSERT</> and <command>UPDATE</>
183+ commands on the view will be checked to ensure that new rows satisfy the
184+ view-defining condition (that is, the new rows are checked to ensure that
185+ they are visible through the view). If they are not, the update will be
186+ rejected. If the <literal>CHECK OPTION</> is not specified,
187+ <command>INSERT</> and <command>UPDATE</> commands on the view are
188+ allowed to create rows that are not visible through the view. The
189+ following check options are supported:
190+
191+ <variablelist>
192+ <varlistentry>
193+ <term><literal>LOCAL</literal></term>
194+ <listitem>
195+ <para>
196+ New rows are only checked against the conditions defined directly in
197+ the view itself. Any conditions defined on underlying base views are
198+ not checked (unless they also specify the <literal>CHECK OPTION</>).
199+ </para>
200+ </listitem>
201+ </varlistentry>
202+
203+ <varlistentry>
204+ <term><literal>CASCADED</literal></term>
205+ <listitem>
206+ <para>
207+ New rows are checked against the conditions of the view and all
208+ underlying base views. If the <literal>CHECK OPTION</> is specified,
209+ and neither <literal>LOCAL</> nor <literal>CASCADED</> is specified,
210+ then <literal>CASCADED</> is assumed.
211+ </para>
212+ </listitem>
213+ </varlistentry>
214+ </variablelist>
215+ </para>
216+
217+ <para>
218+ The <literal>CHECK OPTION</> may not be used with <literal>RECURSIVE</>
219+ views.
220+ </para>
221+
222+ <para>
223+ Note that the <literal>CHECK OPTION</> is only supported on views that
224+ are automatically updatable, and do not have <literal>INSTEAD OF</>
225+ triggers or <literal>INSTEAD</> rules. If an automatically updatable
226+ view is defined on top of a base view that has <literal>INSTEAD OF</>
227+ triggers, then the <literal>LOCAL CHECK OPTION</> may be used to check
228+ the conditions on the automatically updatable view, but the conditions
229+ on the base view with <literal>INSTEAD OF</> triggers will not be
230+ checked (a cascaded check option will not cascade down to a
231+ trigger-updatable view, and any check options defined directly on a
232+ trigger-updatable view will be ignored). If the view or any of its base
233+ relations has an <literal>INSTEAD</> rule that causes the
234+ <command>INSERT</> or <command>UPDATE</> command to be rewritten, then
235+ all check options will be ignored in the rewritten query, including any
236+ checks from automatically updatable views defined on top of the relation
237+ with the <literal>INSTEAD</> rule.
238+ </para>
239+ </listitem>
240+ </varlistentry>
141241 </variablelist>
142242 </refsect1>
143243
@@ -256,7 +356,9 @@ CREATE VIEW vista AS SELECT text 'Hello World' AS hello;
256356 condition, and thus is no longer visible through the view. Similarly,
257357 an <command>INSERT</> command can potentially insert base-relation rows
258358 that do not satisfy the <literal>WHERE</> condition and thus are not
259- visible through the view.
359+ visible through the view. The <literal>CHECK OPTION</> may be used to
360+ prevent <command>INSERT</> and <command>UPDATE</> commands from creating
361+ such rows that are not visible through the view.
260362 </para>
261363
262364 <para>
@@ -300,6 +402,38 @@ CREATE VIEW comedies AS
300402 the table will not be part of the view.
301403 </para>
302404
405+ <para>
406+ Create a view with <literal>LOCAL CHECK OPTION</>:
407+
408+ <programlisting>
409+ CREATE VIEW universal_comedies AS
410+ SELECT *
411+ FROM comedies
412+ WHERE classification = 'U'
413+ WITH LOCAL CHECK OPTION;
414+ </programlisting>
415+ This will create a view based on the <literal>comedies</> view, showing
416+ only films with <literal>kind = 'Comedy'</> and
417+ <literal>classification = 'U'</>. Any attempt to <command>INSERT</> or
418+ <command>UPDATE</> a row in the view will be rejected if the new row
419+ doesn't have <literal>classification = 'U'</>, but the film
420+ <literal>kind</> will not be checked.
421+ </para>
422+
423+ <para>
424+ Create a view with <literal>CASCADED CHECK OPTION</>:
425+
426+ <programlisting>
427+ CREATE VIEW pg_comedies AS
428+ SELECT *
429+ FROM comedies
430+ WHERE classification = 'PG'
431+ WITH CASCADED CHECK OPTION;
432+ </programlisting>
433+ This will create a view that checks both the <literal>kind</> and
434+ <literal>classification</> of new rows.
435+ </para>
436+
303437 <para>
304438 Create a recursive view consisting of the numbers from 1 to 100:
305439<programlisting>
@@ -313,64 +447,11 @@ UNION ALL
313447 <refsect1>
314448 <title>Compatibility</title>
315449
316- <para>
317- The SQL standard specifies some additional capabilities for the
318- <command>CREATE VIEW</command> statement:
319- <synopsis>
320- CREATE VIEW <replaceable class="parameter">name</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
321- AS <replaceable class="PARAMETER">query</replaceable>
322- [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
323- </synopsis>
324- </para>
325-
326- <para>
327- The optional clauses for the full SQL command are:
328-
329- <variablelist>
330- <varlistentry>
331- <term><literal>CHECK OPTION</literal></term>
332- <listitem>
333- <para>
334- This option controls the behavior of automatically updatable views.
335- When given, <command>INSERT</> and <command>UPDATE</> commands on
336- the view will be checked to ensure new rows satisfy the
337- view-defining condition (that is, the new rows would be visible
338- through the view). If they do not, the update will be rejected.
339- Without <literal>CHECK OPTION</literal>, <command>INSERT</> and
340- <command>UPDATE</> commands on the view are allowed to create rows
341- that are not visible through the view. (The latter behavior is the
342- only one currently provided by <productname>PostgreSQL</>.)
343- </para>
344- </listitem>
345- </varlistentry>
346-
347- <varlistentry>
348- <term><literal>LOCAL</literal></term>
349- <listitem>
350- <para>
351- Check for integrity on this view.
352- </para>
353- </listitem>
354- </varlistentry>
355-
356- <varlistentry>
357- <term><literal>CASCADED</literal></term>
358- <listitem>
359- <para>
360- Check for integrity on this view and on any dependent
361- view. <literal>CASCADED</> is assumed if neither
362- <literal>CASCADED</> nor <literal>LOCAL</> is specified.
363- </para>
364- </listitem>
365- </varlistentry>
366- </variablelist>
367- </para>
368-
369450 <para>
370451 <command>CREATE OR REPLACE VIEW</command> is a
371452 <productname>PostgreSQL</productname> language extension.
372453 So is the concept of a temporary view.
373- The <literal>WITH</> clause is an extension as well.
454+ The <literal>WITH ( ... ) </> clause is an extension as well.
374455 </para>
375456 </refsect1>
376457
0 commit comments