web-dev-qa-db-fra.com

Ajout d'entrées htstore à une colonne ininitialisée (null)

J'ai été mordu par cette "fonctionnalité" récemment.

Si votre colonne hstore est ininitialisée et que vous commencez à ajouter des entrées. Ils sont tous avalés silencieusement sans erreur.

Est-ce attendu?

 create table test_hstore(id int, map hstore);
 insert into test_hstore(id,map) values(0, '');
 INSERT 0 1

 select * from test_hstore ;
  id | map 
 ----+-----
   0 | 


 update test_hstore set map = map || hstore('key1', 'value1') where id = 0;
 UPDATE 1

 select * from test_hstore;
  id |       map        
 ----+------------------
   0 | "key1"=>"value1"


 update test_hstore set map = null where id = 0;
 UPDATE 1

 select * from test_hstore;
  id |  map   
 ----+--------
   0 | (null)


 update test_hstore set map = map || hstore('key1', 'value1') where id = 0;
 UPDATE 1

 select * from test_hstore;
  id |  map   
 ----+--------
   0 | (null)

Si je ne peux pas avoir une contrainte non nulle sur la colonne, puis-je me protéger en faisant quelque chose comme ça (cela ne fonctionne pas réellement):

UPDATE test_hstore SET map = (IF map IS NULL
                                THEN  '' || hstore('key1', 'value1')
                                ELSE map || hstore('key1', 'value1'))
WHERE id = 0;
4
Kuba

En SQL, NULL (operator) (value) est généralement NULL.

Ce n'est pas unique à HSTORE, et est la norme pour tout.

La chaîne vide '' est différent de NULL. '' || 'somestring' est 'somestring', Wheras NULL || 'somestring' est NULL.

La même chose est vraie pour hstore. Juste comme NULL + 1 est NULL.

S'il s'agit d'un problème pour vous, vous devez probablement stocker des valeurs vides hstore au lieu de NULL et d'attribuer un NOT NULL contrainte sur la colonne.

6
Craig Ringer