Search
ctrl/
Ask AI
Light
Dark
System

Volatility

The volatility of an expression refers to how its value may change across successive evaluations.

Expressions may have one of the following volatilities, in order of increasing volatility:

  • Immutable: The expression cannot modify the database and is

    guaranteed to have the same value in all statements.

  • Stable: The expression cannot modify the database and is

    guaranteed to have the same value within a single statement.

  • Volatile: The expression cannot modify the database and can have

    different values on successive evaluations.

  • Modifying: The expression can modify the database and can have

    different values on successive evaluations.

All primitives, ranges, and multiranges are Immutable.

Arrays, tuples, and sets have the volatility of their most volatile component.

Globals are always Stable, even computed globals with an immutable expression.

Objects are generally Stable except:

  • Objects with a shape containing a more volatile computed pointer will have the volatility of its most volatile component.

  • Free objects have the volatility of their most volatile component. They may be Immutable.

An object’s non-computed pointers are Stable. Its computed pointers have the volatility of their expressions.

Any DML (i.e., insert, update, delete) is Modifying.

Unless explicitly specified, a function’s volatility will be inferred from its body expression.

A function call’s volatility is highest of its body expression and its call arguments.

Given:

Copy
# Immutable
function plus_primitive(x: float64) -> float64
    using (x + 1);

# Stable
global one := 1;
function plus_global(x: float64) -> float64
    using (x + one);

# Volatile
function plus_random(x: float64) -> float64
    using (x + random());

# Modifying
type One {
    val := 1;
};
function plus_insert(x: float64) -> float64
    using (x + (insert One).val);

Some example operator and function calls:

1 + 1:                    Immutable
1 + global one:           Stable
global one + random():    Volatile
(insert One).val:         Modifying
plus_primitive(1):        Immutable
plus_stable(1):           Stable
plus_random(global one):  Volatile
plus_insert(random()):    Immutable

Some features restrict the volatility of expressions. A lower volatility can be used.

Indexes expressions must be Immutable. Within the index, pointers to the indexed object are treated as immutable

constraints expressions must be Immutable. Within the constraint, the __subject__ and its pointers are treated as immutable.

Access policies must be Stable.

Aliases, globals, and computed pointers in the schema must be Stable.

The cartesian product of a Volatile or Modifying expression is not allowed.

Copy
db> 
SELECT {1, 2} + random()
QueryError: can not take cross product of volatile operation

Modifying expressions are not allowed in a non-scalar argument to a function, except for standard set functions.