4 wtf из 5 - NULL
В PostgreSQL есть два типа NULL - типизированный и не типизированный...
Звучит как какой-то треш :)
Но если вы знакомы с функциональным программированием, то эту конструкцию можно сравнить с монадой maybe.
Объясняется это довольно просто. Если у вас есть таблица с nullable полем, то при выборке из таблицы NULL будет того же типа, что и колонка.
Но какой тип будет у NULL в следующем выражении:
SELECT NULLВот и PostgreSQL не знает...
Поэтому для тех случаев, когда тип не ясен, полю будет присвоен специальный тип - UNKNOWN
Такой же тип вы получите для неопределенного булева выражения:
SELECTВы же знаете, что проверку на NULL нельзя делать через оператор =, а нужно использовать IS NULL?
NULL IS UNKNOWN, -- true
(1 = NULL) IS UNKNOWN -- true
Но это еще не все. Если UNKNOWN возвращается из подзапроса, то он обретает тип:
SELECTПочти такая же история, как и с вложенным ROW().
NULL, -- unknown
(SELECT NULL) -- text
Наш парсер знает о таком поведении.
5 wtf из 5 - updatable views
Многие из нас используют представления (VIEW) в своих базах. Но мало кто знает, что с представлениями могут быть использованы команды INSERT, UPDATE и DELETE.
Не со всеми и не всегда, но могут. Для этого представление должно быть создано с определенными ограничениями, главное из которых - оно должно иметь только 1 источник данных.
Кому и зачем это может быть нужно?
Для начала нужно помнить, что если у таблицы, над которой сделали VIEW, переименовать столбец, то ничего не сломается. VIEW будет иметь старое имя столбца и при этом ссылаться на переименованный:
CREATE TABLE t (a INT);Но это еще не все. Если мы по каким-то причинам не можем обновлять приложение при изменении схемы базы, то мы можем изменять данные в целевых таблицах через представления. Если при этом изменятся имена колонок в таблице, то во VIEW все останется как было. Т.е. для таблицы, описанной выше, сработает:
CREATE VIEW t_view AS SELECT a from t ;
ALTER TABLE t RENAME COLUMN a TO b;
UPDATE t_view SET a = 1 WHERE a = 2;Это, безусловно, безумная практика и однозначный путь к провалу, который рано или поздно закончится трагедией. Мы будем предупреждать разработчика о представлениях, сделанных до изменений в целевой таблице.