IntermediateAdvanced PostgreSQL

Immutable function for expression indexes

The query

SQL
-- Regular functions cannot be used in indexes
-- Use IMMUTABLE functions (same input = always same output)

CREATE OR REPLACE FUNCTION normalize_email(email TEXT)
RETURNS TEXT AS $$
  SELECT LOWER(TRIM(email));
$$ LANGUAGE SQL IMMUTABLE STRICT;

-- Now this expression index works:
CREATE INDEX idx_normalized_email ON customers(normalize_email(email));

-- Query uses the index:
SELECT * FROM customers
WHERE normalize_email(email) = normalize_email('  User@GMAIL.COM  ');
Tested against PostgreSQL 16

Note

IMMUTABLE functions can be indexed. STABLE = reads DB but same per statement. VOLATILE = default, cannot index.

Tables referenced