Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4cbe3ac

Browse files
committed
WITH CHECK OPTION support for auto-updatable VIEWs
For simple views which are automatically updatable, this patch allowsthe user to specify what level of checking should be done on recordsbeing inserted or updated. For 'LOCAL CHECK', new tuples are validatedagainst the conditionals of the view they are being inserted into, whilefor 'CASCADED CHECK' the new tuples are validated against theconditionals for all views involved (from the top down).This option is part of the SQL specification.Dean Rasheed, reviewed by Pavel Stehule
1 parent6f9e39b commit4cbe3ac

File tree

33 files changed

+1245
-107
lines changed

33 files changed

+1245
-107
lines changed

‎doc/src/sgml/ref/alter_view.sgml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENAM
2828
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
2929
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">view_option_name</replaceable> [= <replaceable class="parameter">view_option_value</replaceable>] [, ... ] )
3030
ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RESET ( <replaceable class="parameter">view_option_name</replaceable> [, ... ] )
31+
32+
<phrase>where <replaceable class="parameter">view_option_name</replaceable> can be one of:</phrase>
33+
34+
security_barrier [ <replaceable class="parameter">boolean</replaceable> ]
35+
check_option [ <replaceable class="parameter">text</replaceable> (<literal>local</literal> or <literal>cascaded</literal>) ]
3136
</synopsis>
3237
</refsynopsisdiv>
3338

‎doc/src/sgml/ref/create_view.sgml

Lines changed: 140 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ PostgreSQL documentation
2424
CREATE [ 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

‎src/backend/access/common/reloptions.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include"catalog/pg_type.h"
2525
#include"commands/defrem.h"
2626
#include"commands/tablespace.h"
27+
#include"commands/view.h"
2728
#include"nodes/makefuncs.h"
2829
#include"utils/array.h"
2930
#include"utils/attoptcache.h"
@@ -248,6 +249,17 @@ static relopt_string stringRelOpts[] =
248249
gistValidateBufferingOption,
249250
"auto"
250251
},
252+
{
253+
{
254+
"check_option",
255+
"View has WITH CHECK OPTION defined (local or cascaded).",
256+
RELOPT_KIND_VIEW
257+
},
258+
0,
259+
true,
260+
validateWithCheckOption,
261+
NULL
262+
},
251263
/* list terminator */
252264
{{NULL}}
253265
};
@@ -1152,6 +1164,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
11521164
offsetof(StdRdOptions,autovacuum)+offsetof(AutoVacOpts,analyze_scale_factor)},
11531165
{"security_barrier",RELOPT_TYPE_BOOL,
11541166
offsetof(StdRdOptions,security_barrier)},
1167+
{"check_option",RELOPT_TYPE_STRING,
1168+
offsetof(StdRdOptions,check_option_offset)},
11551169
};
11561170

11571171
options=parseRelOptions(reloptions,validate,kind,&numoptions);

‎src/backend/catalog/information_schema.sql

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2494,7 +2494,13 @@ CREATE VIEW views AS
24942494
ELSEnull END
24952495
AS character_data)AS view_definition,
24962496

2497-
CAST('NONE'AS character_data)AS check_option,
2497+
CAST(
2498+
CASE WHEN'check_option=cascaded'= ANY (c.reloptions)
2499+
THEN'CASCADED'
2500+
WHEN'check_option=local'= ANY (c.reloptions)
2501+
THEN'LOCAL'
2502+
ELSE'NONE' END
2503+
AS character_data)AS check_option,
24982504

24992505
CAST(
25002506
-- (1 << CMD_UPDATE) + (1 << CMD_DELETE)

‎src/backend/catalog/sql_features.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ F311Schema definition statementNO
227227
F311Schema definition statement01CREATE SCHEMAYES
228228
F311Schema definition statement02CREATE TABLE for persistent base tablesYES
229229
F311Schema definition statement03CREATE VIEWYES
230-
F311Schema definition statement04CREATE VIEW: WITH CHECK OPTIONNO
230+
F311Schema definition statement04CREATE VIEW: WITH CHECK OPTIONYES
231231
F311Schema definition statement05GRANT statementYES
232232
F312MERGE statementNO
233233
F313Enhanced MERGE statementNO
@@ -301,7 +301,7 @@ F711ALTER domainYES
301301
F721Deferrable constraintsNOforeign and unique keys only
302302
F731INSERT column privilegesYES
303303
F741Referential MATCH typesNOno partial match yet
304-
F751View CHECK enhancementsNO
304+
F751View CHECK enhancementsYES
305305
F761Session managementYES
306306
F762CURRENT_CATALOGYES
307307
F763CURRENT_SCHEMAYES

‎src/backend/commands/tablecmds.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8774,6 +8774,42 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation,
87748774
break;
87758775
}
87768776

8777+
/* Special-case validation of view options */
8778+
if (rel->rd_rel->relkind==RELKIND_VIEW)
8779+
{
8780+
Query*view_query=get_view_query(rel);
8781+
List*view_options=untransformRelOptions(newOptions);
8782+
ListCell*cell;
8783+
boolcheck_option= false;
8784+
boolsecurity_barrier= false;
8785+
8786+
foreach(cell,view_options)
8787+
{
8788+
DefElem*defel= (DefElem*)lfirst(cell);
8789+
8790+
if (pg_strcasecmp(defel->defname,"check_option")==0)
8791+
check_option= true;
8792+
if (pg_strcasecmp(defel->defname,"security_barrier")==0)
8793+
security_barrier=defGetBoolean(defel);
8794+
}
8795+
8796+
/*
8797+
* If the check option is specified, look to see if the view is
8798+
* actually auto-updatable or not.
8799+
*/
8800+
if (check_option)
8801+
{
8802+
constchar*view_updatable_error=
8803+
view_query_is_auto_updatable(view_query,security_barrier);
8804+
8805+
if (view_updatable_error)
8806+
ereport(ERROR,
8807+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
8808+
errmsg("WITH CHECK OPTION is supported only on auto-updatable views"),
8809+
errhint("%s",view_updatable_error)));
8810+
}
8811+
}
8812+
87778813
/*
87788814
* All we need do here is update the pg_class row; the new options will be
87798815
* propagated into relcaches during post-commit cache inval.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp