This page defines the syntax of the SQL data manipulation language (DML) statements supported for PostgreSQL-dialect databases.
Notations used in the syntax
- Square brackets
[ ]
indicate optional clauses. - Curly braces
{ }
enclose a set of options. - The vertical bar
|
indicates a logical OR. - A comma followed by an ellipsis indicates that the preceding
item
can repeat in a comma-separated list.item [, ...]
indicates one or more items, and[item, ...]
indicates zero or more items.
- Purple-colored text, such as
item
, marks Spanner extensions to open source PostgreSQL. - Parentheses
( )
indicate literal parentheses. - A comma
,
indicates the literal comma. - Angle brackets
<>
indicate literal angle brackets. - Uppercase words, such as
INSERT
, are keywords.
INSERT statement
Use the INSERT
statement to add new rows to a table.
INSERT INTO table_name [ AS alias ] [ ( column_name [, ...] ) ] { VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query } [ ON CONFLICT (conflict_target) conflict_action ] [ RETURNING select-list ] where conflict_target must be the primary key column(s) in order and separated by columns. and conflict_action is one of: DO NOTHING DO UPDATE SET { column_name [, ...] = excluded.column_name [, ...] } and where query is: a query (SELECT statement) that supplies the rows to be inserted. and select-list is: { * | expression [ [ AS ] output_name ] [, ...] }
See PostgreSQL queries for a description of the SELECT
syntax.
Default values
Use the DEFAULT
keyword to insert the default value of a column.
If a column is not included in the column name list, Spanner assigns the default
value of the column with little computing overhead. If the column has no defined default value,
NULL
is assigned to the column.
The use of default values is subject to current Spanner limits, including the mutation limit.
If a column has a default value and it is used in an insert or update, the column is counted as one mutation.
For example, assuming that table T
has three columns and that col_a
has a default value,
the following inserts each result in three mutations:
INSERT INTO T (id, col_a, col_b) VALUES (1, DEFAULT, 1);
INSERT INTO T (id, col_a, col_b) VALUES (2, 200, 2);
INSERT INTO T (id, col_b) VALUES (3, 3);
For more information about default column values, see the
DEFAULT ( expression )
clause in CREATE TABLE
.
For more information about mutations, see What are mutations?.
ON CONFLICT
clause
The ON CONFLICT DO NOTHING
clause indicates that if the row that you're
inserting already exists in the table, INSERT
doesn't throw a unique
constraint violation of the primary key, and the row isn't inserted.
The ON CONFLICT DO UPDATE SET
clause indicates that if the row that you're
inserting already exists in the table, INSERT
doesn't throw a unique
constraint violation of the primary key, and the row is updated.
This clause has a few differences from PostgreSQL, resulting in the following restrictions:
- Only permits primary key columns as the conflict_target.
- If the table has composite primary keys, you must specify all primary key columns in conflict_target.
- The
DO UPDATE SET
clause must list all columns that you specify in the insert list. For
DO UPDATE SET
, the update value must be set to the insert value in the query using the PostgreSQL special aliasexcluded
. For example:INSERT INTO singers (SingerId, FirstName, LastName) VALUES (1, 'Marc', 'Richards') ON CONFLICT (SingerId) DO UPDATE SET SingerId = excluded.SingerId, FirstName = excluded.FirstName, LastName = excluded.LastName;
The
WHERE
clause inON CONFLICT DO UPDATE
clause isn't supported.
Examples for ON CONFLICT DO UPDATE SET
For the following table:
CREATE TABLE Singers (
SingerId int primary key,
FirstName varchar(64),
LastName varchar(64),
Birthdate date,
Status varchar(64),
SingerInfo varchar(64)
);
You can use the following query without a columns list:
INSERT INTO Singers
VALUES (5, 'Zak', 'Sterling', '1996-03-12', 'active', 'nationality:"U.S.A."'),
(7, 'Edie', 'Silver', '1998-01-23', 'active', 'nationality:"U.S.A."')
ON CONFLICT (SingerId)
DO UPDATE SET SingerId=excluded.SingerId,
FirstName=excluded.FirstName,
LastName=excluded.LastName,
Birthdate=excluded.Birthdate,
Status=excluded.Status,
SingerInfo=excluded.SingerInfo;
Or you can use the following query with a columns list:
INSERT INTO Singers
(SingerId, LastName)
VALUES (5, 'Sterling'),
(7, 'Silver')
ON CONFLICT (SingerId)
DO UPDATE SET SingerId=excluded.SingerId, LastName=excluded.LastName;
RETURNING
Use the RETURNING
clause to return the results of the INSERT
operation and
selected data from the newly inserted rows. This clause is especially useful for
retrieving values of columns with default values, generated columns, and
auto-generated keys, without having to use additional SELECT
statements.
The RETURNING
clause can capture expressions based on newly inserted rows that
include the following:
*
: Returns all columns.expression
: Represents a column name of the table specified by table_name or an expression that uses any combination of such column names. Column names are valid if they belong to columns of the table_name. Excluded expressions include aggregate and analytic functions.alias
: Represents a temporary name for an expression in the query.
For example, the following query inserts two rows into the Singers
table, uses
RETURNING
to fetch the SingerId column from these rows, and computes a new
column called FullName
.
INSERT INTO singers (SingerId, FirstName, LastName)
VALUES
(7, 'Melissa', 'Garcia'),
(8, 'Russell', 'Morales')
RETURNING SingerId, FirstName || ' ' || LastName AS FullName;
In the following query, we use ON CONFLICT DO UPDATE SET
is used to update
existing rows if there is a conflict for SingerId
.
INSERT INTO singers (SingerId, FirstName, LastName)
VALUES
(7, 'Melissa', 'Garcia'),
(8, 'Russell', 'Morales')
ON CONFLICT (SingerId) DO UPDATE SET
SingerId = EXCLUDED.SingerId,
FirstName = EXCLUDED.FirstName,
LastName = EXCLUDED.LastName
RETURNING SingerId, FirstName || ' ' || LastName AS FullName;
For instructions and code samples, see Modify data with the returning DML statements.
DELETE statement
Use the DELETE
statement to delete rows from a table.
[ /* @statement_hint_expr [, ...] */ ] DELETE FROM table_name [ /* @table_hint_expr [, ...] */ ] [ [ AS ] alias ] [ WHERE condition ] [ RETURNING select-list ] where select-list is: { * | expression [ [ AS ] output_name ] [, ...] } and statement_hint_expr is: statement_hint_key = statement_hint_value and table_hint_expr is: table_hint_key = table_hint_value
RETURNING
With the optional RETURNING
clause, you can obtain data from rows that are
being deleted in a table. For example, the following query deletes all rows in
the Singers
table that contains a singer called Melissa
and returns the
deleted rows.
DELETE FROM Singers WHERE Firstname = 'Melissa'
RETURNING *;
To learn more about the values that you can use in this clause, see INSERT RETURNING.
UPDATE statement
Use the UPDATE
statement to update existing rows in a table.
[ /* @statement_hint_expr [, ...] */ ] UPDATE [ ONLY ] table_name [ /* @table_hint_expr [, ...] */ ] [ * ] [ [ AS ] alias ] SET { column_name = { expression | DEFAULT } | ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) } [, ...] [ WHERE condition ] [ RETURNING select-list ] where select-list is: { * | expression [ [ AS ] output_name ] [, ...] } and statement_hint_expr is: statement_hint_key = statement_hint_value and table_hint_expr is: table_hint_key = table_hint_value
Where:
table_name
is the name of a table to update.- The
SET
clause specifies how to modify columns in the rows that match theWHERE
clause's condition. It's a list of column names or expression pairs. expression
is an update expression. The expression can be a literal, a SQL expression, or a SQL subquery.statement_hint_expr
is a statement-level hint. The following hints are supported:statement_hint_key
statement_hint_value
Description PDML_MAX_PARALLELISM An integer between 1 to 1000 Sets the maximum parallelism for Partitioned DML queries.
This hint is only valid with the Partitioned DML query execution mode.table_hint_expr
is a hint for accessing the table. The following hints are supported:table_hint_key
table_hint_value
Description FORCE_INDEX Index name Use specified index when querying rows to be updated. FORCE_INDEX _BASE_TABLE Don't use an index when querying. Instead, scan the base table.
UPDATE
statements must comply with the following rules:
- A column can appear only once in the
SET
clause. - The columns in the
SET
clause can be listed in any order. - Each value must be type compatible with its associated column.
- The values must comply with any constraints in the schema, such as unique secondary indexes or non-nullable columns.
- Updates with joins are not supported.
- You cannot update primary key columns.
Default values
The DEFAULT
keyword sets the value of a column to its default value. If the
column has no defined default value, the DEFAULT
keyword sets it to NULL
.
The use of default values is subject to current Spanner limits, including the mutation limit. If a column has a default value and it is used in an insert or update, the column is counted as one mutation. For example, assume that in table T
, col_a
has a default value. The following updates each result in two mutations. One comes from the primary key, and another comes from either the explicit value (1000) or the default value.
UPDATE T SET col_a = 1000 WHERE id=1;
UPDATE T SET col_a = DEFAULT WHERE id=3;
For more information about default column values, see the
DEFAULT ( expression )
clause in CREATE TABLE
.
For more information about mutations, see What are mutations?.
WHERE clause
The WHERE
clause is required. This requirement can help prevent accidentally
updating all the rows in a table. To update all rows in a table, set the
condition
to true
.
The WHERE
clause can contain any valid SQL boolean expression, including a
subquery that refers to other tables.
Aliases
The WHERE
clause has an implicit alias to target_name
. This alias lets you
reference columns in target_name
without qualifying them with
target_name
. For example, if your statement starts with UPDATE Singers
, then
you can access any columns of Singers
in the WHERE
clause. In this example,
FirstName
and LastName
are columns in the Singers
table:
UPDATE singers
SET birthdate = '1990-10-10'
WHERE firstname = 'Marc' AND lastname = 'Richards';
You can also create an explicit alias using the optional AS
keyword.
RETURNING
With the optional RETURNING
clause, you can obtain data from rows that are
being updated in a table. For example, the following query updates all rows
where the singer first name is equal to Russell
and returns the updated
rows.
UPDATE Singers
SET BirthDate = '1990-10-10'
WHERE FirstName = 'Russell'
RETURNING *;
To learn more about the values that you can use in this clause, see INSERT RETURNING.