Skip to main content
Firebolt SQL is modeled after PostgreSQL (see SQL reference). This page lists only where the two differ; anything not mentioned works as in PostgreSQL. The comparison is against PostgreSQL 18 with default settings: DateStyle = 'ISO, MDY' and a database created with the en_US.UTF-8 locale. Tables on this page use these statuses:

Key differences

These differences change query results, mostly without raising an error. Check them first when you migrate a workload.
Write exact values as NUMERIC '1.5' or '1.5'::NUMERIC(10, 2).
Always specify precision and scale, for example NUMERIC(12, 0).
Cast the operands to a larger scale first.
avg over BIGINT values above 2^53 loses precision. Cast to NUMERIC where the exact result matters.
Use decimal literals.
COLLATE is not supported. The same order affects min, max, greatest, and least.
Truncate with substr and trim trailing blanks with rtrim.
DATE spans 0001-01-01 to 9999-12-30, and TIMESTAMP and TIMESTAMPTZ end at 9999-12-30 22:00:00.999999. PostgreSQL accepts years from 4713 BC to 294276 AD for timestamps and to 5874897 AD for dates. Values outside the Firebolt range raise an error, including the common end-of-time value:
Inner arrays can have different lengths. Index with a[i][j] to reach an element.
To keep the original text, store the document as TEXT and apply JSON functions to it.
Declare a constraint only when your loads guarantee it.
PostgreSQL keeps a temporary table private to the session and drops it when the session ends. Firebolt creates an ordinary table that every session sees and that is never dropped automatically. Use a regular table with a unique name and drop it explicitly.
A SELECT * view returns columns added to the table after the view was created. ALTER TABLE ... DROP COLUMN succeeds when a view uses the column, and the view then fails when queried; PostgreSQL refuses the drop. List view columns explicitly.
PostgreSQL defaults to READ COMMITTED: a second writer waits on the row lock and then succeeds. Firebolt has no locks; the first transaction to commit wins, and a later conflicting transaction fails at COMMIT. Retry the transaction on a conflict.

Data types

These types work as in PostgreSQL: integer, bigint, real, double precision, bytea, and boolean. real and double precision print inf, -inf, and nan instead of Infinity, -Infinity, and NaN, and switch to exponent notation at 1e21 and 1e-6 rather than at PostgreSQL’s thresholds. See Data types for the Firebolt types. Not available: smallint (use INTEGER), serial and identity columns, money, "char", name, time, timetz, uuid (use TEXT with gen_random_uuid_text()), composite and row types (use STRUCT), enum, domains, range types, network types, geometric types (use GEOGRAPHY), tsvector, tsquery, bit, xml, pg_lsn, and the other reg* types.

Literals

Not available: tagged dollar quotes ($tag$...$tag$), Unicode escape strings (U&'...'), bit strings (B'101', X'1F'), and array literals with explicit bounds ('[0:2]={1,2,3}').

Query syntax

Core SELECT features work as in PostgreSQL, including joins, LATERAL, GROUPING SETS, subqueries, CTEs, and the default NULL ordering. Two precedence rules differ without an error; the remaining gaps raise errors.
Not available: NATURAL LEFT, NATURAL RIGHT, and NATURAL FULL joins (write them with USING), and USING (...) AS alias.
Not available:
  • DISTINCT ON; use QUALIFY row_number() OVER (PARTITION BY ... ORDER BY ...) = 1.
  • GROUP BY DISTINCT.
  • LIMIT ALL, OFFSET n ROWS without FETCH, FETCH FIRST ROW ONLY without a count, and WITH TIES; use OFFSET n and FETCH FIRST 1 ROWS ONLY.
  • Bare VALUES ... ORDER BY and TABLE t; use SELECT * FROM ....
  • TABLESAMPLE, FOR UPDATE, FOR SHARE, ONLY, and system columns such as ctid.
Not available:
  • WITH RECURSIVE, SEARCH, CYCLE, and data-modifying statements in WITH.
  • Row comparisons such as (a, b) < (c, d), ROW(...), SOME, and ARRAY(subquery); (a, b) IN (SELECT ...) works.
  • GROUPS frames, EXCLUDE, and refining a named window, as in OVER (w ORDER BY ...).
Not available: PREPARE and EXECUTE (drivers pass parameters), and bare user, current_role, current_schema, current_time, localtime, and system_user (use current_user and current_schema()).

Functions and operators

Functions not mentioned here work as in PostgreSQL. Functions that exist only in Firebolt are documented in SQL functions.
Firebolt adds TRY_CAST, which returns NULL when a cast fails. Not available: to_number, to_char with a numeric or interval argument, IS UNKNOWN, BETWEEN SYMMETRIC, num_nulls, and num_nonnulls.
Text is compared and case-mapped as under the PostgreSQL C collation: by byte value, with case changes for ASCII letters only.Not available: concat_ws, initcap, chr, translate, overlay, quote_literal, quote_nullable, bit_length, normalize, string_to_table, LIKE ... ESCAPE, SIMILAR TO, LIKE ANY (array), and regexp_match, regexp_matches, regexp_substr, regexp_count, and the regexp_split_to_* functions (use REGEXP_EXTRACT_ALL).
Not available: the operators ~ (bitwise NOT), @, |/, and ||/ (use abs, sqrt, cbrt), div, gcd, lcm, factorial, width_bucket, scale, min_scale, trim_scale, setseed, random(min, max), and the degree-based trigonometric functions such as sind.
Not available: date_part (use extract), age, date_bin, make_date, make_timestamp, isfinite, OVERLAPS, current_time, localtime, clock_timestamp, statement_timestamp, transaction_timestamp, and timeofday.
Not available: last_value, every (use bool_and), mode(), percentile_disc, regr_*, hypothetical-set aggregates, json_agg, jsonb_agg, and count(DISTINCT (a, b)).
Not available: @>, <@, &&, and array || element (use ARRAY_CONTAINS, ARRAYS_OVERLAP, and ARRAY_CONCAT), slices, array_append, array_prepend, array_remove, array_replace, array_ndims, array_dims, array_lower, cardinality, and WITH ORDINALITY.
Access fields with the subscript and dot operators, for example (doc)['a'] or (doc).a.Not available: ->, #>, #>> (use the subscript operator or JSON_VALUE), @>, ?, = on JSON, jsonb_array_length, jsonb_each, json_strip_nulls, jsonb_pretty, json_build_object, json_build_array, json_extract_path, json_array_elements, json_object_keys, jsonb_path_query, and row_to_json.
Not available: generate_series over timestamps or NUMERIC, generate_subscripts, sha224, sha256, sha384, sha512, crc32, set_config, pg_backend_pid, txid_current, pg_sleep, inet_client_addr, obj_description, to_regclass, pg_get_viewdef, pg_get_constraintdef, and pg_table_size.

Database objects

Firebolt supports tables, views, schemas, databases, roles, and users. It adds objects with no PostgreSQL counterpart: engines, locations, external tables, and aggregating indexes. Not available: materialized views (use aggregating indexes), B-tree, hash, GIN, GiST, and BRIN indexes, sequences and identity columns (generate keys while loading or with row_number()), procedures, DO, CALL, triggers, rules, types, domains, enums, extensions, row-level security policies, foreign tables (use external tables or read_parquet and read_csv), CREATE STATISTICS (use ALTER TABLE ... ADD STATISTICS), tablespaces, collations, publications, and subscriptions.

Tables

Not available: CHECK, CONSTRAINT name, EXCLUDE, UNLOGGED, INHERITS, storage parameters, LIKE and WITH NO DATA (use CREATE TABLE new AS SELECT * FROM old LIMIT 0, or CREATE TABLE CLONE to copy the data too), ALTER COLUMN ... TYPE, SET and DROP DEFAULT, SET and DROP NOT NULL, ADD CONSTRAINT, and SET SCHEMA.

Views

Not available: WITH CHECK OPTION, TEMP and RECURSIVE views, ALTER VIEW ... RENAME TO, and dropping several views or tables in one statement.

Data manipulation

INSERT, UPDATE, DELETE, MERGE, and TRUNCATE work as in PostgreSQL, apart from the following. Not available: RETURNING, UPDATE ... SET (a, b) = (...), MERGE ... INSERT DEFAULT VALUES, WITH in front of a data-modifying statement (write INSERT INTO t WITH x AS (...) SELECT ..., or use a subquery), and COPY ... FROM STDIN or TO STDOUT (Firebolt COPY FROM and COPY TO use object storage).

Access control

Users and roles are separate objects: privileges are granted to roles, and roles to users. Each GRANT names one privilege, one object, and one grantee. See Role-based access control. Not available: several privileges or grantees in one statement, WITH GRANT OPTION, REVOKE ... CASCADE, GRANT CONNECT or TEMPORARY ON DATABASE (use USAGE and CREATE ON DATABASE), REFERENCES and TRIGGER privileges, ALTER ROLE ... RENAME (ALTER USER ... RENAME works), ALTER USER ... WITH PASSWORD, SET ROLE, REASSIGN OWNED, DROP OWNED, and row-level security.

Transactions and sessions

Not available: READ COMMITTED, SERIALIZABLE, READ ONLY, SET TRANSACTION, SAVEPOINT, PREPARE TRANSACTION, SELECT ... FOR UPDATE, LOCK TABLE, SET search_path (qualify names with the schema), RESET, SET LOCAL, ANALYZE, REINDEX, CLUSTER, CHECKPOINT, DISCARD, LISTEN, and NOTIFY.

System catalog

information_schema and the common pg_catalog relations are available. Firebolt’s own catalog views are documented under Information schema. Not available: referential_constraints, check_constraints, sequences, triggers, pg_proc, pg_roles, pg_auth_members, pg_index, pg_indexes, pg_stat_activity, pg_locks, pg_sequences, and pg_extension.