Jeg tror, problemet her er, at den hstore du har er null, og null ELLER nogle hstore er null.
Den bedste løsning jeg har, som nok ikke er den bedste løsning, er at lave tabellen med en standard tom hstore i stedet for at tillade null. Så fungerer dine eksempler, som du gerne vil:
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)
Jeg kan desværre ikke se en renere måde at oprette en tom hstore på end hstore(array[]::varchar[])
men det betyder ikke, at der ikke er en bedre måde. Du kan inkorporere dette i din hstore-opdatering fra før som sådan:
update htest set h = coalesce(h, hstore(array[]::varchar[])) || ('foo'=>'bar') where t='key';
På denne måde behøver du ikke at genskabe bordet. Det synes jeg dog er ret grimt. Håber dette hjælper.