diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile
index d15d2ae775a50ed6ba0385119cee05f6ce412039..5257bbfcc005c1255b1dc9d02fabae573f373b4a 100644
--- a/contrib/hstore/Makefile
+++ b/contrib/hstore/Makefile
@@ -1,11 +1,11 @@
-# $PostgreSQL: pgsql/contrib/hstore/Makefile,v 1.4 2007/02/09 17:24:33 petere Exp $
+# $PostgreSQL: pgsql/contrib/hstore/Makefile,v 1.5 2007/03/14 14:21:52 teodor Exp $
 
 subdir = contrib/hstore
 top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 
 MODULE_big = hstore
-OBJS = hstore_io.o hstore_op.o hstore_gist.o crc32.o
+OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o crc32.o
 
 DATA_built = hstore.sql
 DATA = uninstall_hstore.sql
diff --git a/contrib/hstore/README.hstore b/contrib/hstore/README.hstore
index 5fdceb1b986d4c30169a511de94e05c3b07af74e..b8c9711389343215eec3618be6b698eafd9f28ec 100644
--- a/contrib/hstore/README.hstore
+++ b/contrib/hstore/README.hstore
@@ -117,13 +117,14 @@ regression=# select * from each('a=>1,b=>2');
  a   | 1
  b   | 2
 
-    * exist (hstore,text) - returns 'true if key is exists in hstore and 
-	false otherwise. 
+    * exist (hstore,text) 
+	* hstore ? text 
+	  - returns 'true if key is exists in hstore and false otherwise. 
 
-regression=# select exist('a=>1','a');
- exist 
-----------
- t
+regression=# select exist('a=>1','a'), 'a=>1' ? 'a';
+ exist | ?column? 
+-------+----------
+ t     | t
 
     * defined (hstore,text) - returns true if key is exists in hstore and 
 	  its value is not NULL. 
@@ -135,9 +136,10 @@ regression=# select defined('a=>NULL','a');
 
 Indices
 
-Module provides index support for '@>' and '<@' operations.
+Module provides index support for '@>' and '?' operations.
 
 create index hidx on testhstore using gist(h);
+create index hidx on testhstore using gin(h);
 
 Note
 
diff --git a/contrib/hstore/data/hstore.data b/contrib/hstore/data/hstore.data
index 7651a10f084a397ab3c2b369efd74d0ef519801a..b7391daffb7d827cc2ed3882974b0c3314750ecf 100644
--- a/contrib/hstore/data/hstore.data
+++ b/contrib/hstore/data/hstore.data
@@ -998,3 +998,4 @@ auth=>BC, title=>CAC, subtitle=>BA, line=>997, date=>BAA
 wait=>AB, user=>ABC, line=>998, pos=>41, node=>CAC
 state=>4, title=>AC, bad=>t, status=>59, line=>999, disabled=>t
 user=>BC, line=>1000
+wait=>NULL, line=>1000
diff --git a/contrib/hstore/expected/hstore.out b/contrib/hstore/expected/hstore.out
index 94194a6d00b91381e51d5145a9023fbb92aacd4c..eee23d3a05abc786a268abcf790391d54b22541f 100644
--- a/contrib/hstore/expected/hstore.out
+++ b/contrib/hstore/expected/hstore.out
@@ -272,6 +272,12 @@ select ('aa=>NULL, c=>d , b=>16'::hstore->'aa') is null;
  t
 (1 row)
 
+select ('aa=>"NULL", c=>d , b=>16'::hstore->'aa') is null;
+ ?column? 
+----------
+ f
+(1 row)
+
 -- exists/defined
 select exist('a=>NULL, b=>qq', 'a');
  exist 
@@ -291,6 +297,12 @@ select exist('a=>NULL, b=>qq', 'c');
  f
 (1 row)
 
+select exist('a=>"NULL", b=>qq', 'a');
+ exist 
+-------
+ t
+(1 row)
+
 select defined('a=>NULL, b=>qq', 'a');
  defined 
 ---------
@@ -309,6 +321,12 @@ select defined('a=>NULL, b=>qq', 'c');
  f
 (1 row)
 
+select defined('a=>"NULL", b=>qq', 'a');
+ defined 
+---------
+ t
+(1 row)
+
 -- delete 
 select delete('a=>1 , b=>2, c=>3'::hstore, 'a');
        delete       
@@ -384,6 +402,18 @@ select 'a=>g, b=>c'::hstore || ( 'b'=>'gf' );
  "a"=>"g", "b"=>"gf"
 (1 row)
 
+select 'a=>g, b=>c'::hstore || ( 'b'=>'NULL' );
+       ?column?        
+-----------------------
+ "a"=>"g", "b"=>"NULL"
+(1 row)
+
+select 'a=>g, b=>c'::hstore || ( 'b'=>NULL );
+      ?column?       
+---------------------
+ "a"=>"g", "b"=>NULL
+(1 row)
+
 -- keys/values
 select akeys('aa=>1 , b=>2, cq=>3'::hstore || 'cq=>l, b=>g, fg=>f');
     akeys     
@@ -485,19 +515,19 @@ select * from each('aaa=>bq, b=>NULL, ""=>1 ');
 (3 rows)
 
 -- @>
-select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>NULL';
+select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b';
  ?column? 
 ----------
  t
 (1 row)
 
-select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>NULL, c=>NULL';
+select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, c=>NULL';
  ?column? 
 ----------
  t
 (1 row)
 
-select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>NULL, g=>NULL';
+select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, g=>NULL';
  ?column? 
 ----------
  f
@@ -521,12 +551,6 @@ select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b';
  t
 (1 row)
 
-select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, c=>NULL';
- ?column? 
-----------
- t
-(1 row)
-
 select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, c=>q';
  ?column? 
 ----------
@@ -538,7 +562,7 @@ CREATE TABLE testhstore (h hstore);
 select count(*) from testhstore where h @> 'wait=>NULL';
  count 
 -------
-   189
+     1
 (1 row)
 
 select count(*) from testhstore where h @> 'wait=>CC';
@@ -553,12 +577,18 @@ select count(*) from testhstore where h @> 'wait=>CC, public=>t';
      2
 (1 row)
 
+select count(*) from testhstore where h ? 'public';
+ count 
+-------
+   194
+(1 row)
+
 create index hidx on testhstore using gist(h);
 set enable_seqscan=off;
 select count(*) from testhstore where h @> 'wait=>NULL';
  count 
 -------
-   189
+     1
 (1 row)
 
 select count(*) from testhstore where h @> 'wait=>CC';
@@ -573,16 +603,49 @@ select count(*) from testhstore where h @> 'wait=>CC, public=>t';
      2
 (1 row)
 
+select count(*) from testhstore where h ? 'public';
+ count 
+-------
+   194
+(1 row)
+
+drop index hidx;
+create index hidx on testhstore using gin (h);
+set enable_seqscan=off;
+select count(*) from testhstore where h @> 'wait=>NULL';
+ count 
+-------
+     1
+(1 row)
+
+select count(*) from testhstore where h @> 'wait=>CC';
+ count 
+-------
+    15
+(1 row)
+
+select count(*) from testhstore where h @> 'wait=>CC, public=>t';
+ count 
+-------
+     2
+(1 row)
+
+select count(*) from testhstore where h ? 'public';
+ count 
+-------
+   194
+(1 row)
+
 select count(*) from (select (each(h)).key from testhstore) as wow ;
  count 
 -------
-  4779
+  4781
 (1 row)
 
 select key, count(*) from (select (each(h)).key from testhstore) as wow group by key order by count desc, key;
     key    | count 
 -----------+-------
- line      |   883
+ line      |   884
  query     |   207
  pos       |   203
  node      |   202
@@ -590,9 +653,9 @@ select key, count(*) from (select (each(h)).key from testhstore) as wow group by
  status    |   195
  public    |   194
  title     |   190
+ wait      |   190
  org       |   189
  user      |   189
- wait      |   189
  coauthors |   188
  disabled  |   185
  indexed   |   184
diff --git a/contrib/hstore/hstore.h b/contrib/hstore/hstore.h
index a601906764b0be30794a67b922f5acbbc64c7173..5ef18abd8e8b5c95744b49184204fff2d22265d5 100644
--- a/contrib/hstore/hstore.h
+++ b/contrib/hstore/hstore.h
@@ -50,4 +50,7 @@ typedef struct
 int			comparePairs(const void *a, const void *b);
 int			uniquePairs(Pairs * a, int4 l, int4 *buflen);
 
+#define HStoreContainsStrategyNumber    7
+#define HStoreExistsStrategyNumber      9
+
 #endif
diff --git a/contrib/hstore/hstore.sql.in b/contrib/hstore/hstore.sql.in
index 95cecf15d29c95b08f95733f39d11bfe5147cf93..3e0821a952594864818d5da91345969f472e2aca 100644
--- a/contrib/hstore/hstore.sql.in
+++ b/contrib/hstore/hstore.sql.in
@@ -40,6 +40,14 @@ RETURNS bool
 AS 'MODULE_PATHNAME','exists'
 LANGUAGE 'C' with (isstrict,iscachable);
 
+CREATE OPERATOR ? (
+	LEFTARG = hstore,
+	RIGHTARG = text,
+	PROCEDURE = exist,
+	RESTRICT = contsel,
+	JOIN = contjoinsel
+);
+
 CREATE FUNCTION isdefined(hstore,text)
 RETURNS bool
 AS 'MODULE_PATHNAME','defined'
@@ -116,7 +124,7 @@ CREATE OPERATOR ~ (
 CREATE FUNCTION tconvert(text,text)
 RETURNS hstore
 AS 'MODULE_PATHNAME'
-LANGUAGE 'C' with (isstrict,iscachable);
+LANGUAGE 'C' with (iscachable);
 
 CREATE OPERATOR => (
 	LEFTARG = text,
@@ -210,7 +218,8 @@ LANGUAGE 'C';
 CREATE OPERATOR CLASS gist_hstore_ops
 DEFAULT FOR TYPE hstore USING gist
 AS
-        OPERATOR        7       @>       RECHECK,
+       	OPERATOR        7       @>       RECHECK,
+       	OPERATOR        9       ?(hstore,text)       RECHECK,
         --OPERATOR        8       <@       RECHECK,
         OPERATOR        13      @       RECHECK,
         --OPERATOR        14      ~       RECHECK,
@@ -223,4 +232,33 @@ AS
         FUNCTION        7       ghstore_same (internal, internal, internal),
         STORAGE         ghstore;
 
+-- define the GIN support methods
+
+CREATE FUNCTION gin_extract_hstore(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C;
+
+CREATE FUNCTION gin_extract_hstore_query(internal, internal, int2)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C;
+
+CREATE FUNCTION gin_consistent_hstore(internal, int2, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C;
+
+CREATE OPERATOR CLASS gin_hstore_ops
+DEFAULT FOR TYPE hstore USING gin
+AS
+	OPERATOR        7       @> RECHECK,
+    OPERATOR        9       ?(hstore,text),
+	FUNCTION        1       bttextcmp(text,text),
+	FUNCTION        2       gin_extract_hstore(internal, internal),
+	FUNCTION        3       gin_extract_hstore_query(internal, internal, int2),
+	FUNCTION        4       gin_consistent_hstore(internal, int2, internal),
+STORAGE         text;
+
+
 END;
diff --git a/contrib/hstore/hstore_gin.c b/contrib/hstore/hstore_gin.c
new file mode 100644
index 0000000000000000000000000000000000000000..f6fab2b89d6e4ff1ef76219d7493148759aeaa95
--- /dev/null
+++ b/contrib/hstore/hstore_gin.c
@@ -0,0 +1,135 @@
+#include "hstore.h"
+
+#include "access/gin.h"   
+
+#define	KEYFLAG		'K'
+#define	VALFLAG		'V'
+#define	NULLFLAG	'N'
+
+PG_FUNCTION_INFO_V1(gin_extract_hstore);
+Datum       gin_extract_hstore(PG_FUNCTION_ARGS);
+
+static text*
+makeitem( char *str, int len )
+{
+	text	*item;
+
+	item = (text*)palloc( VARHDRSZ + len + 1 );
+	SET_VARSIZE(item, VARHDRSZ + len + 1);
+
+	if ( str && len > 0 )
+		memcpy( VARDATA(item)+1, str, len );
+
+	return item;
+}
+
+Datum
+gin_extract_hstore(PG_FUNCTION_ARGS)
+{
+	HStore	*hs = PG_GETARG_HS(0);
+	int32	*nentries = (int32 *) PG_GETARG_POINTER(1);
+	Datum	*entries = NULL;
+
+	*nentries = 2*hs->size;
+
+	if ( hs->size > 0 )
+	{
+		HEntry	*ptr = ARRPTR(hs);
+		char    *words = STRPTR(hs);
+		int		i=0;
+
+		entries = (Datum*)palloc( sizeof(Datum) * 2 * hs->size );
+
+		while (ptr - ARRPTR(hs) < hs->size)
+		{
+			text	*item;
+
+			item = makeitem( words + ptr->pos, ptr->keylen ); 
+			*VARDATA(item) = KEYFLAG;
+			entries[i++] = PointerGetDatum(item);
+
+			if ( ptr->valisnull )
+			{
+				item = makeitem( NULL, 0 ); 
+				*VARDATA(item) = NULLFLAG;
+
+			}
+			else
+			{
+				item = makeitem( words + ptr->pos + ptr->keylen, ptr->vallen ); 
+				*VARDATA(item) = VALFLAG;
+			}
+			entries[i++] = PointerGetDatum(item);
+
+			ptr++;
+		}
+	}
+
+	PG_FREE_IF_COPY(hs,0);
+	PG_RETURN_POINTER(entries);
+}
+
+PG_FUNCTION_INFO_V1(gin_extract_hstore_query);
+Datum       gin_extract_hstore_query(PG_FUNCTION_ARGS);
+
+Datum
+gin_extract_hstore_query(PG_FUNCTION_ARGS)
+{
+	StrategyNumber strategy = PG_GETARG_UINT16(2);
+
+	if ( strategy == HStoreContainsStrategyNumber )
+	{
+		PG_RETURN_DATUM( DirectFunctionCall2(
+				gin_extract_hstore,
+				PG_GETARG_DATUM(0),
+				PG_GETARG_DATUM(1)
+		));
+	}
+	else if ( strategy == HStoreExistsStrategyNumber )
+	{
+		text *item, *q = PG_GETARG_TEXT_P(0);
+		int32	*nentries = (int32 *) PG_GETARG_POINTER(1);
+		Datum	*entries = NULL;
+
+		*nentries = 1;
+		entries = (Datum*)palloc( sizeof(Datum) );
+
+		item = makeitem( VARDATA(q), VARSIZE(q)-VARHDRSZ );
+		*VARDATA(item) = KEYFLAG;
+		entries[0] = PointerGetDatum(item);
+
+		PG_RETURN_POINTER(entries);
+	}
+	else
+		elog(ERROR, "Unsupported strategy number: %d", strategy);
+
+	PG_RETURN_POINTER(NULL);
+}
+
+PG_FUNCTION_INFO_V1(gin_consistent_hstore);
+Datum       gin_consistent_hstore(PG_FUNCTION_ARGS);
+
+Datum
+gin_consistent_hstore(PG_FUNCTION_ARGS)
+{
+	StrategyNumber strategy = PG_GETARG_UINT16(1);
+	bool	res = true;
+
+	if ( strategy == HStoreContainsStrategyNumber )
+	{
+		bool    *check = (bool *) PG_GETARG_POINTER(0);
+		HStore	*query = PG_GETARG_HS(2);
+		int 	i;
+
+		for(i=0;res && i<2*query->size;i++)
+			if ( check[i] == false )
+				res = false;
+	}
+	else if ( strategy == HStoreExistsStrategyNumber )
+		res = true;
+	else
+		elog(ERROR, "Unsupported strategy number: %d", strategy);
+
+	PG_RETURN_BOOL(res);
+}
+
diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index c3923dacf253e48785d072d42c5ae5c8bab6f5cb..fbee64be7da71b207608f0d736cba2265e994e39 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -492,37 +492,48 @@ Datum
 ghstore_consistent(PG_FUNCTION_ARGS)
 {
 	GISTTYPE   *entry = (GISTTYPE *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
-	HStore	   *query = PG_GETARG_HS(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
 	bool		res = true;
-	HEntry	   *qe = ARRPTR(query);
-	char	   *qv = STRPTR(query);
 	BITVECP		sign;
 
 	if (ISALLTRUE(entry))
-	{
-		PG_FREE_IF_COPY(query, 1);
 		PG_RETURN_BOOL(true);
-	}
 
 	sign = GETSIGN(entry);
-	while (res && qe - ARRPTR(query) < query->size)
+
+	if ( strategy == HStoreContainsStrategyNumber || strategy == 13 /* hack for old strats */ )
 	{
-		int			crc = crc32_sz((char *) (qv + qe->pos), qe->keylen);
+		HStore	   *query = PG_GETARG_HS(1);
+		HEntry	   *qe = ARRPTR(query);
+		char	   *qv = STRPTR(query);
 
-		if (GETBIT(sign, HASHVAL(crc)))
+		while (res && qe - ARRPTR(query) < query->size)
 		{
-			if (!qe->valisnull)
+			int			crc = crc32_sz((char *) (qv + qe->pos), qe->keylen);
+
+			if (GETBIT(sign, HASHVAL(crc)))
 			{
-				crc = crc32_sz((char *) (qv + qe->pos + qe->keylen), qe->vallen);
-				if (!GETBIT(sign, HASHVAL(crc)))
-					res = false;
+				if (!qe->valisnull)
+				{
+					crc = crc32_sz((char *) (qv + qe->pos + qe->keylen), qe->vallen);
+					if (!GETBIT(sign, HASHVAL(crc)))
+						res = false;
+				}
 			}
+			else
+				res = false;
+			qe++;
 		}
-		else
-			res = false;
-		qe++;
 	}
+	else if ( strategy == HStoreExistsStrategyNumber )
+	{
+		text	*query = PG_GETARG_TEXT_P(1);
+		int		crc = crc32_sz( VARDATA(query), VARSIZE(query)-VARHDRSZ );
+
+		res = (GETBIT(sign, HASHVAL(crc))) ? true : false;
+	}
+	else
+		elog(ERROR, "Unsupported strategy number: %d", strategy);
 
-	PG_FREE_IF_COPY(query, 1);
 	PG_RETURN_BOOL(res);
 }
diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c
index ef3eb86ca3eaae154ced1b91e84a91b79fa045ec..326948afc146d17eb5fb4bc8e7381fa5eba098c6 100644
--- a/contrib/hstore/hstore_op.c
+++ b/contrib/hstore/hstore_op.c
@@ -270,26 +270,48 @@ Datum		tconvert(PG_FUNCTION_ARGS);
 Datum
 tconvert(PG_FUNCTION_ARGS)
 {
-	text	   *key = PG_GETARG_TEXT_P(0);
-	text	   *val = PG_GETARG_TEXT_P(1);
+	text	   *key;
+	text	   *val = NULL;
 	int			len;
 	HStore	   *out;
 
-	len = CALCDATASIZE(1, VARSIZE(key) + VARSIZE(val) - 2 * VARHDRSZ);
+	if ( PG_ARGISNULL(0) )
+		PG_RETURN_NULL();
+
+	key = PG_GETARG_TEXT_P(0);
+
+	if ( PG_ARGISNULL(1) )
+		len = CALCDATASIZE(1, VARSIZE(key) );
+	else
+	{
+		val = PG_GETARG_TEXT_P(1);
+		len = CALCDATASIZE(1, VARSIZE(key) + VARSIZE(val) - 2 * VARHDRSZ);
+	}
 	out = palloc(len);
 	SET_VARSIZE(out, len);
 	out->size = 1;
 
 	ARRPTR(out)->keylen = VARSIZE(key) - VARHDRSZ;
-	ARRPTR(out)->vallen = VARSIZE(val) - VARHDRSZ;
-	ARRPTR(out)->valisnull = false;
+	if ( PG_ARGISNULL(1) )
+	{
+		ARRPTR(out)->vallen = 0;
+		ARRPTR(out)->valisnull = true;
+	}
+	else
+	{
+		ARRPTR(out)->vallen = VARSIZE(val) - VARHDRSZ;
+		ARRPTR(out)->valisnull = false;
+	}
 	ARRPTR(out)->pos = 0;
 
 	memcpy(STRPTR(out), VARDATA(key), ARRPTR(out)->keylen);
-	memcpy(STRPTR(out) + ARRPTR(out)->keylen, VARDATA(val), ARRPTR(out)->vallen);
+	if (!PG_ARGISNULL(1))
+	{
+		memcpy(STRPTR(out) + ARRPTR(out)->keylen, VARDATA(val), ARRPTR(out)->vallen);
+		PG_FREE_IF_COPY(val, 1);
+	}
 
 	PG_FREE_IF_COPY(key, 0);
-	PG_FREE_IF_COPY(val, 1);
 
 	PG_RETURN_POINTER(out);
 }
@@ -515,17 +537,18 @@ hs_contains(PG_FUNCTION_ARGS)
 
 		if (entry)
 		{
-			if (!te->valisnull)
+			if ( te->valisnull || entry->valisnull )
 			{
-				if (entry->valisnull || !(
-										  te->vallen == entry->vallen &&
+				if ( !(te->valisnull && entry->valisnull) )
+					res = false;
+			}
+			else if ( te->vallen != entry->vallen ||  
 										  strncmp(
 											 vv + entry->pos + entry->keylen,
 												  tv + te->pos + te->keylen,
-												  te->vallen) == 0
-										  ))
+												  te->vallen) 
+										  )
 					res = false;
-			}
 		}
 		else
 			res = false;
diff --git a/contrib/hstore/sql/hstore.sql b/contrib/hstore/sql/hstore.sql
index f268da557c8e80dbfd8968c9ecda2c1d7e6af244..9da6cd13dff9fd587e0864726279cbab721c68ac 100644
--- a/contrib/hstore/sql/hstore.sql
+++ b/contrib/hstore/sql/hstore.sql
@@ -63,15 +63,18 @@ select 'aa=>b, c=>d , b=>16'::hstore->'b';
 select 'aa=>b, c=>d , b=>16'::hstore->'aa';
 select ('aa=>b, c=>d , b=>16'::hstore->'gg') is null;
 select ('aa=>NULL, c=>d , b=>16'::hstore->'aa') is null;
+select ('aa=>"NULL", c=>d , b=>16'::hstore->'aa') is null;
 
 -- exists/defined
 
 select exist('a=>NULL, b=>qq', 'a');
 select exist('a=>NULL, b=>qq', 'b');
 select exist('a=>NULL, b=>qq', 'c');
+select exist('a=>"NULL", b=>qq', 'a');
 select defined('a=>NULL, b=>qq', 'a');
 select defined('a=>NULL, b=>qq', 'b');
 select defined('a=>NULL, b=>qq', 'c');
+select defined('a=>"NULL", b=>qq', 'a');
 
 -- delete 
 
@@ -91,6 +94,8 @@ select ''::hstore || 'cq=>l, b=>g, fg=>f';
 -- =>
 select 'a=>g, b=>c'::hstore || ( 'asd'=>'gf' );
 select 'a=>g, b=>c'::hstore || ( 'b'=>'gf' );
+select 'a=>g, b=>c'::hstore || ( 'b'=>'NULL' );
+select 'a=>g, b=>c'::hstore || ( 'b'=>NULL );
 
 -- keys/values
 select akeys('aa=>1 , b=>2, cq=>3'::hstore || 'cq=>l, b=>g, fg=>f');
@@ -112,13 +117,12 @@ select * from svals('');
 select * from each('aaa=>bq, b=>NULL, ""=>1 ');
 
 -- @>
-select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>NULL';
-select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>NULL, c=>NULL';
-select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>NULL, g=>NULL';
+select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b';
+select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, c=>NULL';
+select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, g=>NULL';
 select 'a=>b, b=>1, c=>NULL'::hstore @> 'g=>NULL';
 select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>c';
 select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b';
-select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, c=>NULL';
 select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, c=>q';
 
 CREATE TABLE testhstore (h hstore);
@@ -127,6 +131,7 @@ CREATE TABLE testhstore (h hstore);
 select count(*) from testhstore where h @> 'wait=>NULL';
 select count(*) from testhstore where h @> 'wait=>CC';
 select count(*) from testhstore where h @> 'wait=>CC, public=>t';
+select count(*) from testhstore where h ? 'public';
 
 create index hidx on testhstore using gist(h);
 set enable_seqscan=off;
@@ -134,6 +139,16 @@ set enable_seqscan=off;
 select count(*) from testhstore where h @> 'wait=>NULL';
 select count(*) from testhstore where h @> 'wait=>CC';
 select count(*) from testhstore where h @> 'wait=>CC, public=>t';
+select count(*) from testhstore where h ? 'public';
+
+drop index hidx;
+create index hidx on testhstore using gin (h);
+set enable_seqscan=off;
+
+select count(*) from testhstore where h @> 'wait=>NULL';
+select count(*) from testhstore where h @> 'wait=>CC';
+select count(*) from testhstore where h @> 'wait=>CC, public=>t';
+select count(*) from testhstore where h ? 'public';
 
 select count(*) from (select (each(h)).key from testhstore) as wow ;
 select key, count(*) from (select (each(h)).key from testhstore) as wow group by key order by count desc, key;
diff --git a/contrib/hstore/uninstall_hstore.sql b/contrib/hstore/uninstall_hstore.sql
index bfa2e738dce2ffcddaba5c99c723b82fc34b8028..a24bc72f9f808b40e9000576a2acb4697589fc97 100644
--- a/contrib/hstore/uninstall_hstore.sql
+++ b/contrib/hstore/uninstall_hstore.sql
@@ -1,7 +1,9 @@
 BEGIN;
 
 DROP OPERATOR CLASS gist_hstore_ops USING gist CASCADE;
+DROP OPERATOR CLASS gin_hstore_ops USING gin CASCADE;
 
+DROP OPERATOR ? ( hstore, text );
 DROP OPERATOR ->( hstore, text );
 DROP OPERATOR ||( hstore, hstore );
 DROP OPERATOR @>( hstore, hstore );
@@ -33,6 +35,9 @@ DROP FUNCTION ghstore_picksplit(internal, internal);
 DROP FUNCTION ghstore_union(internal, internal);
 DROP FUNCTION ghstore_same(internal, internal, internal);
 DROP FUNCTION ghstore_consistent(internal,internal,int4);
+DROP FUNCTION gin_consistent_hstore(internal, smallint, internal);
+DROP FUNCTION gin_extract_hstore(internal, internal);
+DROP FUNCTION gin_extract_hstore_query(internal, internal, smallint);
 
 DROP TYPE hstore CASCADE;
 DROP TYPE hs_each CASCADE;