]> granicus.if.org Git - postgresql/commitdiff
Fix two new-in-9.0 bugs in hstore.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 16 Sep 2010 02:54:07 +0000 (02:54 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 16 Sep 2010 02:54:07 +0000 (02:54 +0000)
There was an incorrect Assert in hstoreValidOldFormat(), which would cause
immediate core dumps when attempting to work with pre-9.0 hstore data,
but of course only in an assert-enabled build.

Also, ghstore_decompress() incorrectly applied DatumGetHStoreP() to a datum
that wasn't actually an hstore, but rather a ghstore (ie, a gist signature
bitstring).  That used to be harmless, but could now result in misbehavior
if the hstore format conversion code happened to trigger.  In reality,
since ghstore is not marked toastable (and doesn't need to be), this
function is useless anyway; we can lobotomize it down to returning the
passed-in pointer.

Both bugs found by Andrew Gierth, though this isn't exactly his proposed
patch.

contrib/hstore/hstore_compat.c
contrib/hstore/hstore_gist.c

index 033d945f9ca7a150d80f60d6cbdbbeda294ee18c..53ca4d79f9c28a3b6e8a76c3e425b79344164e28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/hstore/hstore_compat.c,v 1.2 2010/02/26 02:00:32 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/hstore/hstore_compat.c,v 1.2.4.1 2010/09/16 02:54:07 tgl Exp $
  *
  * Notes on old/new hstore format disambiguation.
  *
@@ -180,7 +180,8 @@ hstoreValidOldFormat(HStore *hs)
        if (hs->size_ & HS_FLAG_NEWVERSION)
                return 0;
 
-       Assert(sizeof(HOldEntry) == sizeof(HEntry));
+       /* New format uses an HEntry for key and another for value */
+       Assert(sizeof(HOldEntry) == (2 * sizeof(HEntry)));
 
        if (count == 0)
                return 2;
index db58fb62ddfd768b8ebb2850553564e77cc757d8..ce2bc4339ce56aa5c3e24177de72dbf4737a1c18 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/hstore/hstore_gist.c,v 1.12 2010/02/26 02:00:32 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/hstore/hstore_gist.c,v 1.12.4.1 2010/09/16 02:54:07 tgl Exp $
  */
 #include "postgres.h"
 
@@ -168,28 +168,14 @@ ghstore_compress(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(retval);
 }
 
+/*
+ * Since type ghstore isn't toastable (and doesn't need to be),
+ * this function can be a no-op.
+ */
 Datum
 ghstore_decompress(PG_FUNCTION_ARGS)
 {
-       GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-       GISTENTRY  *retval;
-       HStore     *key;
-
-       key = DatumGetHStoreP(entry->key);
-
-       if (key != (HStore *) DatumGetPointer(entry->key))
-       {
-               /* need to pass back the decompressed item */
-               retval = palloc(sizeof(GISTENTRY));
-               gistentryinit(*retval, PointerGetDatum(key),
-                                         entry->rel, entry->page, entry->offset, entry->leafkey);
-               PG_RETURN_POINTER(retval);
-       }
-       else
-       {
-               /* we can return the entry as-is */
-               PG_RETURN_POINTER(entry);
-       }
+       PG_RETURN_POINTER(PG_GETARG_POINTER(0));
 }
 
 Datum