PostgreSQL WITH CHECK OPTION
Summary: in this tutorial, you will learn how to create an updatable view using the WITH CHECK OPTION
clause to ensure that the changes to the base tables through the view satisfy the view-defining condition.
Introduction to the PostgreSQL WITH CHECK OPTION clause
In PostgreSQL, a view is a named query stored in the PostgreSQL database server. A simple view can be updatable.
To ensure that any data modification made through a view adheres to certain conditions in the view’s definition, you use the WITH CHECK OPTION
clause.
Typically, you specify the WITH CHECK OPTION
when creating a view using the CREATE VIEW
statement:
When you create a view WITH CHECK OPTION
, PostgreSQL will ensure that you can only modify data of the view that satisfies the condition in the view’s defining query (query
).
Scope of check
In PostgreSQL, you can specify a scope of check:
LOCAL
CASCADED
The LOCAL
scope restricts the check option enforcement to the current view only. It does not enforce the check to the views that the current view is based on.
Here’s the syntax for creating a view with the WITH LOCAL CHECK OPTION
:
The CASCADED
scope extends the check option enforcement to all underlying views of the current view. Here’s the syntax for creating a view with the WITH CASCADED CHECK OPTION
.
To change the scope of check for an existing view, you can use the ALTER VIEW statement.
PostgreSQL WITH CHECK OPTION examples
Let’s take some examples of using the WITH CHECK OPTION
.
Setting up a sample table
The following statements create a new table called employees
and insert data into it:
1) Basic PostgreSQL WITH CHECK OPTION example
First, create a view called fte
that retrieves the employees with the type FTE
from the employees
table:
Second, retrieve data from the fte
view:
Output:
Third, insert a new row into the employees
table via the fte
view:
It succeeds.
The issue is that we can insert an employee with the type of Contractor
into the employee
table via the view that exposes the employee to the type of FTE
.
To ensure that we can insert only employees with the type FTE
into the employees
table via the fte
view, you can use the WITH CHECK OPTION
:
Fourth, replace the fte
view and add the WITH CHECK OPTION
:
After adding the WITH CHECK OPTION
, you perform insert, update, and delete on employees
table that satisfies the WHERE
clause in the defining query of the view.
For example, the following INSERT
statement will fail with an error:
Error:
The reason is that the employee_type
Contractor
does not satisfy the condition defined in the defining query of the view:
But if you modify the row with the employee type FTE
, it’ll be fine.
Fifth, change the last name of the employee id 2
to 'Doe'
:
It works as expected.
2) Using WITH LOCAL CHECK OPTION example
First, recreate the fte
view without using the WITH CHECK OPTION
:
Second, create a new view fte_1
based on the fte
view that returns the employees
of department 1
, with the WITH LOCAL CHECK OPTION
:
Third, retrieve the data from the fte_1
view:
Output:
Since we use the WITH LOCAL CHECK OPTION
, PostgreSQL checks only the fte_1
view when we modify the data in the employees
table via the fte_1
view.
Fourth, insert a new row into the employees
table via the fte_1
view:
It succeeded. The reason is that the INSERT
statement inserts a row with department 1 that satisfies the condition in the fte_1
view:
Fifth, query data from the employees
table:
Output:
3) Using WITH CASCADED CHECK OPTION example
First, recreate the view fte_1
with the WITH CASCADED CHECK OPTION
:
Second, insert a new row into employee
table via the fte_1
view:
Error:
The WITH CASCADED CHECK OPTION
instructs PostgreSQL to check the constraint on the fte_1
view and also its base view which is the fte
view.
That’s why the INSERT
statement fails the condition of both fte_1
and fte
views.
Summary
- Use the
WITH CHECK OPTION
clause to enforce constraints on data modifications through views and ensure that only valid data can be changed.