This page describes how to create and manage Spanner views. For more information about Spanner views, see About views.
Permissions
To create, grant, and revoke access to a view, you must have the
spanner.database.updateDdl
permission.
Create a view
To create a view, use the DDL statement
CREATE VIEW
to name the
view and provide the query that defines it. This statement has two forms:
CREATE VIEW
defines a new view in the current database. If a view namedview_name
already exists, theCREATE VIEW
statement fails.CREATE OR REPLACE VIEW
defines a new view in the current database. If a view namedview_name
already exists, its definition is replaced.
The syntax for the CREATE VIEW statement is:
{CREATE | CREATE OR REPLACE } VIEW view_name SQL SECURITY { INVOKER | DEFINER } AS query
Because a view is a virtual table, the query
that you
specify must provide names for all the columns in that virtual table.
Additionally, Spanner checks the query
you specify using strict name resolution, meaning that all schema object names
used in the query must be qualified such that they unambiguously identify a
single schema object. For example, in the examples that follow the SingerId
column in the Singers
table must be qualified as Singers.SingerId
.
You must specify the SQL SECURITY
as either INVOKER
or DEFINER
in the
CREATE VIEW
or CREATE OR REPLACE VIEW
statement. For more information about
the difference between the two security types, see About views.
For example, assume the Singers
table is defined as follows:
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId);
PostgreSQL
CREATE TABLE Singers ( SingerId BIGINT PRIMARY KEY, FirstName VARCHAR(1024), LastName VARCHAR(1024), SingerInfo BYTEA );
You can define the SingerNames
view with invoker's rights as follows:
CREATE VIEW SingerNames SQL SECURITY INVOKER AS SELECT Singers.SingerId AS SingerId, Singers.FirstName || ' ' || Singers.LastName AS Name FROM Singers;
The virtual table created when the SingerNames
view is used in a query has two
columns, SingerId
and Name
.
While this definition of the SingerNames
view is valid, it does not abide by
the best practice of casting data types to ensure stability across schema
changes, as described in the next section.
Best practices when creating views
To minimize the need to update a view's definition, explicitly cast the data type of all table columns in the query that defines the view. When you do so, the view's definition can remain valid across schema changes to a column's type.
For example, the following definition of the SingerNames
view might become
invalid as the result of changing a column's data type in the Singers
table.
CREATE VIEW SingerNames SQL SECURITY INVOKER AS SELECT Singers.SingerId AS SingerId, Singers.FirstName || ' ' || Singers.LastName AS Name FROM Singers;
You can avoid the view becoming invalid by explicitly casting the columns to the desired data types, as follows:
GoogleSQL
CREATE OR REPLACE VIEW SingerNames SQL SECURITY INVOKER AS SELECT CAST(Singers.SingerId AS INT64) AS SingerId, CAST(Singers.FirstName AS STRING) || " " || CAST(Singers.LastName AS STRING) AS Name FROM Singers;
PostgreSQL
CREATE OR REPLACE VIEW SingerNames SQL SECURITY INVOKER AS SELECT CAST(Singers.SingerId AS bigint) AS SingerId, CAST(Singers.FirstName AS varchar) || ' ' || CAST(Singers.LastName AS varchar) AS Name FROM Singers;
Grant and revoke access to a view
As a fine-grained access control user, you must have the SELECT
privilege on
a view. To grant SELECT
privilege on a view to a database role:
GoogleSQL
GRANT SELECT ON VIEW SingerNames TO ROLE Analyst;
PostgreSQL
GRANT SELECT ON TABLE SingerNames TO Analyst;
To revoke SELECT
privilege on a view from a database role:
GoogleSQL
REVOKE SELECT ON VIEW SingerNames FROM ROLE Analyst;
PostgreSQL
REVOKE SELECT ON TABLE SingerNames FROM Analyst;
Query a view
The way to query an invoker's rights or a definer's rights view is the same. However, depending on the security type of the view, Spanner may or may not need to check the schema objects referenced in the view against the database role of the principal who invoked the query.
Query an invoker's rights view
If a view has invoker's rights, the user must have privileges on all underlying schema objects of the view in order to query it.
For example, if a database role has access to all objects referenced by the
SingerNames
view, they can query the SingerNames
view:
SELECT COUNT(SingerID) as SingerCount FROM SingerNames;
Query a definer's rights view
If a view has definer's rights, a user can query the view without needing
privileges on the underlying objects as long as you grant the required role the
SELECT
privilege on the view.
In the following example, a user with the Analyst database role wants to query
the SingerNames
view. However, the user is denied access because SingerNames
is an invoker's rights view and the Analyst role does not have access to all the
underlying objects. In this case, if you decide to provide the Analyst with
access to the view, but do not want to provide them access to the Singers
table, you can replace the security type of the view to
definer's rights. After you replace the security type of the view, grant the
Analyst role access to the view. The user can now query the SingerNames
view
even though they don't have access to the Singers
table.
SELECT COUNT(SingerID) as SingerCount FROM SingerNames;
Replace a view
You can replace a view by using the CREATE OR REPLACE VIEW
statement to change
the view definition or the security type of the view.
Replacing a view is similar to dropping and recreating the view. Any access grants given to the initial view has to be granted again after replacing the view.
To replace an invoker's rights view with a definer's rights view:
CREATE OR REPLACE VIEW SingerNames SQL SECURITY DEFINER AS SELECT Singers.SingerId AS SingerId, Singers.FirstName || ' ' || Singers.LastName AS Name FROM Singers;
Delete a view
After a view is dropped, database roles with privileges on it no longer have
access. To delete a view, use the DROP VIEW
statement.
DROP VIEW SingerNames;
Get information about a view
You can get information about views in a database by querying tables in its
INFORMATION_SCHEMA
schema.
The
INFORMATION_SCHEMA.TABLES
table provides the names of all defined views.The
INFORMATION_SCHEMA.VIEWS
table provides the names, view definition, security type, and query text of all defined views. FGAC users who haveSELECT
privilege on the view can get information about the view from theINFORMATION_SCHEMA.VIEWS
table. Other FGAC users need thespanner_info_reader
role if they don't haveSELECT
privilege for the view.
To check the view definition and security type of a view called
ProductSoldLastWeek
:
SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'ProductSoldLastWeek';