DatabaseStatusSyntax FamilyMin Version
PostgreSQL partial generated-always-as 12
MySQL full generated-always-as 5.7
MariaDB full generated-always-as 5.2
Oracle full generated-always-as 11g
SQL Server full as-expression -
SQLite full generated-always-as 3.31.0
Redshift none - -
DB2 full generated-always-as -
Snowflake none - -
BigQuery none - -

Compare Databases

Database Details

PostgreSQL partial
CREATE TABLE orders (
  quantity INT,
  unit_price NUMERIC,
  total NUMERIC GENERATED ALWAYS AS (quantity * unit_price) STORED
);
  • STORED only. The expression must be immutable (no volatile functions, other tables, or subqueries) and cannot reference another generated column.
MySQL full
CREATE TABLE orders (
  quantity INT,
  unit_price DECIMAL(10,2),
  total DECIMAL(10,2) GENERATED ALWAYS AS (quantity * unit_price) STORED
);
  • Default is VIRTUAL; STORED is opt-in. Both can be indexed.
  • GENERATED ALWAYS is optional; AS (expr) alone is accepted.
MariaDB full
CREATE TABLE orders (
  quantity INT,
  unit_price DECIMAL(10,2),
  total DECIMAL(10,2) AS (quantity * unit_price) PERSISTENT
);
  • Default is VIRTUAL. PERSISTENT is MariaDB's term for STORED; STORED is also accepted since 10.2.
Oracle full
CREATE TABLE orders (
  quantity NUMBER,
  unit_price NUMBER,
  total NUMBER GENERATED ALWAYS AS (quantity * unit_price)
);
  • VIRTUAL only since 11g; no STORED option.
  • AS (expr) shorthand is accepted; virtual columns can be indexed and used in constraints.
SQL Server full
CREATE TABLE orders (
  quantity INT,
  unit_price DECIMAL(10,2),
  total AS (quantity * unit_price) PERSISTED
);
  • Spelling is AS (expr) [PERSISTED], not GENERATED ALWAYS AS.
  • VIRTUAL is the default; PERSISTED materializes the value on write and is required (along with a deterministic expression) for indexing.
SQLite full
CREATE TABLE orders (
  quantity INTEGER,
  unit_price REAL,
  total REAL GENERATED ALWAYS AS (quantity * unit_price) STORED
);
  • Default is VIRTUAL; STORED is opt-in.
  • Not usable as a PRIMARY KEY but can participate in UNIQUE and other constraints.
  • VIRTUAL columns cannot always be indexed directly; an expression index on the underlying columns is the usual workaround.
Redshift none
  • No expression-based generated columns. IDENTITY columns handle auto-increment but not arbitrary expressions.
DB2 full
CREATE TABLE orders (
  quantity INT,
  unit_price DECIMAL(10,2),
  total DECIMAL(10,2) GENERATED ALWAYS AS (quantity * unit_price)
);
  • GENERATED ALWAYS AS (expr) is virtual; adding STORED materializes it on write.
  • Expressions may use arithmetic, function calls, and CASE.
Snowflake none
  • Not supported on standard tables. The AS (expr) column syntax is only available on external-table virtual columns.
  • Use a view or Dynamic Table to expose derived values.
BigQuery none
  • Not supported. Use a view or materialized view for derived columns.