Почему я могу установить NULL в колонку mark, если у меня есть CHECK(mark in (1,2,3))?

В PostgreSQL CHECK-ограничения позволяют проверять правильность значений, вставляемых в столбцы. При этом, CHECK-ограничения выполняются только во время вставки/обновления данных и не проверяются при удалении или выборке.

При наличии CHECK-ограничения вида "mark in (1,2,3)", оно проверяет, что значение столбца "mark" содержится внутри множества {1, 2, 3}. При попытке вставить/обновить значение, не входящее в это множество, PostgreSQL отклонит запрос и выдаст ошибку.

Однако, при наличии CHECK-ограничения, это не означает, что значение столбца не может быть NULL. В PostgreSQL NULL - это отсутствие значения, и оно не равно ни одному другому значению, включая число или пустую строку.

CHECK-ограничение применяется только к существующим значениям, отличным от NULL. Таким образом, вы все равно можете установить NULL в столбец "mark", даже если у вас есть CHECK-ограничение mark in (1,2,3).

Важно отметить, что в соответствии с SQL стандартом, операторы сравнения, такие как "=", "<>", "<", ">", "<=", ">=" и IS NOT DISTINCT FROM, возвращают NULL при сравнении с NULL. Это означает, что выражение mark = NULL не будет выполняться и не будет включать значения NULL в результат проверки.

Если вам необходимо запретить использование NULL в столбце "mark", вам нужно будет добавить дополнительное ограничение NOT NULL к этому столбцу. Например:

ALTER TABLE your_table
ALTER COLUMN mark SET NOT NULL;

Таким образом, NULL значения больше не будут допускаться для столбца "mark". Если вы попытаетесь вставить NULL в этот столбец, PostgreSQL выдаст ошибку.