Как исправить ошибку DEFAULT для expires_at в PostgreSQL
При создании таблицы verification в PostgreSQL разработчики часто сталкиваются с ошибкой: cannot use column reference in DEFAULT expression. Это происходит, когда в качестве значения по умолчанию пытаются использовать ссылку на другую колонку (created_at) или функцию, зависящую от времени создания строки. В этой статье объясняем, почему так происходит и как правильно настроить автоматическое вычисление expires_at.
Причина ошибки column reference в DEFAULT
В PostgreSQL выражение DEFAULT не может ссылаться на другие столбцы той же таблицы. Запрос DEFAULT dateadd(day, 7, getdate()) некорректен, так как getdate() не является стандартной функцией PostgreSQL, а dateadd отсутствует. Вместо этого нужно использовать NOW() или CURRENT_TIMESTAMP и прибавлять интервал.
Правильный синтаксис DEFAULT для expires_at
Чтобы expires_at автоматически устанавливался на 7 дней позже created_at, используйте выражение:
CREATE TABLE verification (
id serial PRIMARY KEY NOT NULL,
user_id text NOT NULL,
identifier text NOT NULL,
value boolean DEFAULT false,
expires_at timestamp DEFAULT (NOW() + INTERVAL '7 days') NOT NULL,
created_at timestamp DEFAULT NOW() NOT NULL,
updated_at timestamp DEFAULT NOW() NOT NULL
);Здесь NOW() + INTERVAL '7 days' - корректное значение по умолчанию, которое не ссылается на другие колонки.
Альтернатива: триггер для гибкости
Если нужно, чтобы expires_at зависел именно от created_at (например, при ручной вставке), используйте триггер:
CREATE OR REPLACE FUNCTION set_expires_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.expires_at := NEW.created_at + INTERVAL '7 days';
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_set_expires_at
BEFORE INSERT ON verification
FOR EACH ROW EXECUTE FUNCTION set_expires_at();Этот подход гарантирует, что expires_at всегда будет на 7 дней позже created_at, даже если created_at передан явно.
Распространённые ошибки при DEFAULT в PostgreSQL
- Использование GETDATE() - функция из SQL Server, в PostgreSQL замените на
NOW()илиCURRENT_TIMESTAMP. - DATEADD - не существует в PostgreSQL; используйте
INTERVAL. - Ссылка на колонку в DEFAULT - недопустима, применяйте триггеры или вычисляйте значение на стороне приложения.
Заключение
Ошибка cannot use column reference in DEFAULT expression решается заменой некорректных функций на NOW() + INTERVAL или использованием триггера. Теперь ваша таблица verification будет создаваться без ошибок, а expires_at - автоматически получать значение через 7 дней.