Myślę, że problem polega na tym, że hstore, który masz, ma wartość null, a null LUB jakiś hstore ma wartość null.
Najlepszym rozwiązaniem, które mam, a które prawdopodobnie nie jest najlepszym rozwiązaniem, jest utworzenie tabeli z domyślnym pustym hstore zamiast zezwalania na wartość null. Następnie Twoje przykłady działają tak, jak chcesz:
postgres=# create table htest (t text, h hstore default hstore(array[]::varchar[]));
CREATE TABLE
postgres=# insert into htest (t) values ('key');
INSERT 0 1
postgres=# update htest set h = h || ('foo'=>'bar') where t='key';
UPDATE 1
postgres=# select * from htest;
t | h
-----+--------------
key | "foo"=>"bar"
(1 row)
Niestety nie widzę czystszego sposobu na utworzenie pustego hstore niż hstore(array[]::varchar[])
ale to nie znaczy, że nie ma lepszego sposobu. Możesz włączyć to do swojej aktualizacji hstore w ten sposób:
update htest set h = coalesce(h, hstore(array[]::varchar[])) || ('foo'=>'bar') where t='key';
W ten sposób nie musisz ponownie tworzyć tabeli. Uważam, że to dość obrzydliwe. Mam nadzieję, że to pomoże.