• Start

SurrealQL

Statements and values

SurrealQL statements grouped as resource definitions, control flow with transactions, and CRUD-style query operations.

SurrealDB has a variety of statements that let you configure and query a database. In this section, we'll look at the different types of statements that are available.

SurrealDB has a large variety of statements. They can be divided into three types:

  • Statements that define and access database resources,

  • Statements used for control flow and handling manual transactions,

  • Statements used in the context of queries, usually in CRUD (create, read, update, delete) operations.

These statements pertain to defining, removing, altering, and rebuilding database resources. Some examples are:

  • DEFINE statements to define database resources,

  • ALTER statements to alter certain resources,

  • REBUILD to rebuild an index.

Some other statements pertain to using defined resources. They are:

  • USE to move from one namespace or database to another,

  • INFO statements to see the definitions for resources.

These statements are used to describe how query execution should progress.

Some control flow statements only pertain to manual transactions. While all statements in SurrealDB are conducted inside their own transaction, these statements can be used to manually set up a larger transaction composed of multiple statements. They are:

  • BEGIN to begin a manual transaction,

  • COMMIT to commit a transaction,

  • CANCEL to cancel a transaction.

Other control flow statements are used in the same manner as in other programming languages. Some examples are:

  • FOR to begin a for loop,

  • CONTINUE to continue to the next iteration of a loop,

  • BREAK to break out of a for loop, internal scope, function, etc.,

  • THROW to cancel execution and return an error.

These statements are used to execute queries, most often but not always in the context of a CRUD operation.

Some examples of query statements are:

  • CREATE to create one or more records of one or more types of tables,

  • INSERT to create one or more regular records or graph edges,

  • RELATE to create a single graph edge between two records,

  • LIVE SELECT to stream all the changes to a table,

  • DELETE to delete one or more records.

The following flowchart can be used to get a sense of when it makes sense to use CREATE, INSERT, UPDATE, UPSERT, and RELATE.

A flowchart that explains in which cases to use the statements create, insert, update, insert, and relate.

A number of parameters prefixed with $ are automatically available within a statement that provide access to relevant context inside the statement. These are known as reserved variable names. For example:

  • $before and $after can be accessed in statements that mutate values to see the values before and after an update,

  • $session provides context on the current session,

  • $parent provides access to the value in a primary query while inside a subquery.

For a full list of these automatically generated parameters, see the parameters page.

Each of the types mentioned in the data model is a subset of an all-encompassing type called a value.

As every data type a subset of value, any value can be compared with another one.

9 > 1;            // Returns true
null > none; // Also returns true

Being able to compare a value with any other value is what makes SurrealDB's record range syntax possible.

CREATE time_data:[d'2024-07-23T00:00:00.000Z'];
CREATE time_data:[d'2024-07-24T00:00:00.000Z'];
CREATE time_data:[d'2024-07-25T00:00:00.000Z'];
-- Records from the 24th to the 25th
SELECT * FROM time_data:[d'2024-07-24']..[d'2024-07-25'];
-- Records from the 24th
SELECT * FROM time_data:[d'2024-07-24']..;
-- All records
SELECT * FROM time_data:[NONE]..;

The .. open-range syntax also represents an infinite value inside a record range query, making it the greatest possible value and the inverse of NONE, the lowest possible value. A part of a record range query that begins with NONE and ends with .. will thus filter out nothing.

CREATE temperature:['London', d'2025-02-19T00:00:00.000Z'] SET val = 5.5;
CREATE temperature:['London', d'2025-02-20T00:00:00.000Z'] SET val = 5.7;

-- Return all records as long as index 0 = 'London'
SELECT * FROM temperature:['London', NONE]..=['London', ..];

Output

[
{
id: temperature:[
'London',
d'2025-02-19T00:00:00Z'
],
val: 5.5f
},
{
id: temperature:[
'London',
d'2025-02-20T00:00:00Z'
],
val: 5.7f
}
]

Inside a schema, the keyword any is used to denote any possible value.

DEFINE FIELD anything ON TABLE person TYPE any;

Any value is considered to be truthy if it is not NONE, NULL, or a default value for the data type. A data type at its default value is one that is empty, such as an empty string or array or object, or a number set to 0.

The following example shows the result of the array::all() method, which checks to see if all of the items inside an array are truthy or not.

RETURN array::all(["", 1, 2, 3]); // false because of ""
RETURN array::all([{}, 1, 2, 3]); // false because of {}
RETURN array::all(["SurrealDB", { is_nice_database: true }, 1, 2, 3]); // true

As the ! operator reverses the truthiness of a value, a doubling of this operator can also be used to check for truthiness.

RETURN [
!!"Has a value", !!"", // true, false
!!true, !!false, // true, false
!!{ is_nice_database: true }, !!{} // true, false
];

Was this page helpful?