Order GiST procs by strategy number
authorPeter Geoghegan <[email protected]>
Thu, 6 Mar 2014 00:09:23 +0000 (16:09 -0800)
committerPeter Geoghegan <[email protected]>
Thu, 6 Mar 2014 00:09:23 +0000 (16:09 -0800)
src/backend/utils/adt/jsonb_gist.c
src/include/utils/jsonb.h

index e7391b8daf7c9516663512059b17b977c09de961..83c721de85340dfc8efcd78e6af31f9cf1b1bf96 100644 (file)
@@ -91,20 +91,6 @@ typedef struct
 
 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
 
-Datum
-gjsonb_in(PG_FUNCTION_ARGS)
-{
-   elog(ERROR, "not implemented");
-   PG_RETURN_DATUM(0);
-}
-
-Datum
-gjsonb_out(PG_FUNCTION_ARGS)
-{
-   elog(ERROR, "not implemented");
-   PG_RETURN_DATUM(0);
-}
-
 static int
 crc32_JsonbValue(JsonbValue *v, uint32 r)
 {
@@ -166,112 +152,6 @@ crc32_Key(char *buf, int sz)
    return crc;
 }
 
-Datum
-gjsonb_compress(PG_FUNCTION_ARGS)
-{
-   GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
-   GISTENTRY  *retval = entry;
-
-   if (entry->leafkey)
-   {
-       GISTTYPE        *res = (GISTTYPE *) palloc0(CALCGTSIZE(0));
-       Jsonb           *val = (Jsonb*) PG_DETOAST_DATUM(PG_GETARG_POINTER(0));
-
-
-       SET_VARSIZE(res, CALCGTSIZE(0));
-
-       if (!JB_ISEMPTY(val))
-       {
-           int             r;
-           JsonbIterator   *it = JsonbIteratorInit(VARDATA(val));
-           JsonbValue      v;
-
-           while((r = JsonbIteratorGet(&it, &v, false)) != 0)
-           {
-               if ((r == WJB_ELEM || r == WJB_KEY || r == WJB_VALUE) &&
-                   v.type != jbvNull)
-               {
-                   int   h = crc32_JsonbValue(&v, r);
-
-                   HASH(GETSIGN(res), h);
-               }
-           }
-       }
-
-       retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
-       gistentryinit(*retval, PointerGetDatum(res),
-                     entry->rel, entry->page,
-                     entry->offset,
-                     FALSE);
-   }
-   else if (!ISALLTRUE(DatumGetPointer(entry->key)))
-   {
-       int32       i;
-       GISTTYPE   *res;
-       BITVECP     sign = GETSIGN(DatumGetPointer(entry->key));
-
-       LOOPBYTE
-       {
-           if ((sign[i] & 0xff) != 0xff)
-               PG_RETURN_POINTER(retval);
-       }
-
-       res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE));
-       SET_VARSIZE(res, CALCGTSIZE(ALLISTRUE));
-       res->flag = ALLISTRUE;
-
-       retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
-       gistentryinit(*retval, PointerGetDatum(res),
-                     entry->rel, entry->page,
-                     entry->offset,
-                     FALSE);
-   }
-
-   PG_RETURN_POINTER(retval);
-}
-
-/*
- * Since type gjsonb isn't toastable (and doesn't need to be),
- * this function can be a no-op.
- */
-Datum
-gjsonb_decompress(PG_FUNCTION_ARGS)
-{
-   PG_RETURN_POINTER(PG_GETARG_POINTER(0));
-}
-
-Datum
-gjsonb_same(PG_FUNCTION_ARGS)
-{
-   GISTTYPE   *a = (GISTTYPE *) PG_GETARG_POINTER(0);
-   GISTTYPE   *b = (GISTTYPE *) PG_GETARG_POINTER(1);
-   bool       *result = (bool *) PG_GETARG_POINTER(2);
-
-   if (ISALLTRUE(a) && ISALLTRUE(b))
-       *result = true;
-   else if (ISALLTRUE(a))
-       *result = false;
-   else if (ISALLTRUE(b))
-       *result = false;
-   else
-   {
-       int32       i;
-       BITVECP     sa = GETSIGN(a),
-                   sb = GETSIGN(b);
-
-       *result = true;
-       LOOPBYTE
-       {
-           if (sa[i] != sb[i])
-           {
-               *result = false;
-               break;
-           }
-       }
-   }
-   PG_RETURN_POINTER(result);
-}
-
 static int32
 sizebitvec(BITVECP sign)
 {
@@ -322,11 +202,183 @@ unionkey(BITVECP sbase, GISTTYPE *add)
    int32       i;
    BITVECP     sadd = GETSIGN(add);
 
-   if (ISALLTRUE(add))
-       return 1;
-   LOOPBYTE
-       sbase[i] |= sadd[i];
-   return 0;
+   if (ISALLTRUE(add))
+       return 1;
+   LOOPBYTE
+       sbase[i] |= sadd[i];
+   return 0;
+}
+
+typedef struct
+{
+   OffsetNumber pos;
+   int32       cost;
+} SPLITCOST;
+
+static int
+comparecost(const void *a, const void *b)
+{
+   return ((const SPLITCOST *) a)->cost - ((const SPLITCOST *) b)->cost;
+}
+
+Datum
+gjsonb_in(PG_FUNCTION_ARGS)
+{
+   elog(ERROR, "not implemented");
+   PG_RETURN_DATUM(0);
+}
+
+Datum
+gjsonb_out(PG_FUNCTION_ARGS)
+{
+   elog(ERROR, "not implemented");
+   PG_RETURN_DATUM(0);
+}
+
+Datum
+gjsonb_consistent(PG_FUNCTION_ARGS)
+{
+   GISTTYPE   *entry = (GISTTYPE *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+   StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+   /* Oid      subtype = PG_GETARG_OID(3); */
+   bool       *recheck = (bool *) PG_GETARG_POINTER(4);
+   bool        res = true;
+   BITVECP     sign;
+
+   /* All cases served by this function are inexact */
+   *recheck = true;
+
+   if (ISALLTRUE(entry))
+       PG_RETURN_BOOL(true);
+
+   sign = GETSIGN(entry);
+
+   if (strategy == JsonbContainsStrategyNumber)
+   {
+       BITVECP     qe;
+       int         i;
+
+       qe = fcinfo->flinfo->fn_extra;
+       if (qe == NULL)
+       {
+           Jsonb           *query = (Jsonb*) PG_DETOAST_DATUM(PG_GETARG_POINTER(1));
+
+           qe = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(BITVEC));
+           memset(qe, 0, sizeof(BITVEC));
+
+           if (!JB_ISEMPTY(query))
+           {
+               int             r;
+               JsonbIterator   *it = JsonbIteratorInit(VARDATA(query));
+               JsonbValue      v;
+
+               while((r = JsonbIteratorGet(&it, &v, false)) != 0)
+               {
+                   if ((r == WJB_ELEM || r == WJB_KEY || r == WJB_VALUE) && v.type != jbvNull)
+                   {
+                       int   crc = crc32_JsonbValue(&v, r);
+
+                       HASH(qe, crc);
+                   }
+               }
+           }
+
+           fcinfo->flinfo->fn_extra = qe;
+       }
+
+       LOOPBYTE
+       {
+           if ((sign[i] & qe[i]) != qe[i])
+           {
+               res = false;
+               break;
+           }
+       }
+   }
+   else if (strategy == JsonbExistsStrategyNumber)
+   {
+       int     *qval;
+
+       qval = fcinfo->flinfo->fn_extra;
+       if (qval == NULL)
+       {
+           text       *query = PG_GETARG_TEXT_PP(1);
+           int         crc = crc32_Key(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query));
+
+           qval = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(*qval));
+           *qval = HASHVAL(crc);
+
+           fcinfo->flinfo->fn_extra = qval;
+       }
+
+       res = (GETBIT(sign, *qval)) ? true : false;
+   }
+   else if (strategy == JsonbExistsAllStrategyNumber ||
+            strategy == JsonbExistsAnyStrategyNumber)
+   {
+       BITVECP arrentry;
+       int     i;
+
+       arrentry = fcinfo->flinfo->fn_extra;
+       if (arrentry == NULL)
+       {
+           ArrayType  *query = PG_GETARG_ARRAYTYPE_P(1);
+           Datum      *key_datums;
+           bool       *key_nulls;
+           int         key_count;
+
+           arrentry = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
+                                         sizeof(BITVEC));
+           memset(arrentry, 0, sizeof(BITVEC));
+
+           deconstruct_array(query,
+                             TEXTOID, -1, false, 'i',
+                             &key_datums, &key_nulls, &key_count);
+
+           for (i = 0; i < key_count; ++i)
+           {
+               int         crc;
+
+               if (key_nulls[i])
+                   continue;
+               crc = crc32_Key(VARDATA(key_datums[i]),
+                               VARSIZE(key_datums[i]) - VARHDRSZ);
+               HASH(arrentry, crc);
+           }
+
+           fcinfo->flinfo->fn_extra = arrentry;
+       }
+
+       if (strategy == JsonbExistsAllStrategyNumber)
+       {
+           LOOPBYTE
+           {
+               if ((sign[i] & arrentry[i]) != arrentry[i])
+               {
+                   res = false;
+                   break;
+               }
+           }
+       }
+       else /* JsonbExistsAnyStrategyNumber */
+       {
+           res = false;
+
+           LOOPBYTE
+           {
+               if (sign[i] & arrentry[i])
+               {
+                   res = true;
+                   break;
+               }
+           }
+       }
+   }
+   else
+       elog(ERROR, "unsupported strategy number: %d", strategy);
+
+   PG_RETURN_BOOL(res);
 }
 
 Datum
@@ -362,6 +414,80 @@ gjsonb_union(PG_FUNCTION_ARGS)
    PG_RETURN_POINTER(result);
 }
 
+Datum
+gjsonb_compress(PG_FUNCTION_ARGS)
+{
+   GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+   GISTENTRY  *retval = entry;
+
+   if (entry->leafkey)
+   {
+       GISTTYPE        *res = (GISTTYPE *) palloc0(CALCGTSIZE(0));
+       Jsonb           *val = (Jsonb*) PG_DETOAST_DATUM(PG_GETARG_POINTER(0));
+
+
+       SET_VARSIZE(res, CALCGTSIZE(0));
+
+       if (!JB_ISEMPTY(val))
+       {
+           int             r;
+           JsonbIterator   *it = JsonbIteratorInit(VARDATA(val));
+           JsonbValue      v;
+
+           while((r = JsonbIteratorGet(&it, &v, false)) != 0)
+           {
+               if ((r == WJB_ELEM || r == WJB_KEY || r == WJB_VALUE) &&
+                   v.type != jbvNull)
+               {
+                   int   h = crc32_JsonbValue(&v, r);
+
+                   HASH(GETSIGN(res), h);
+               }
+           }
+       }
+
+       retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
+       gistentryinit(*retval, PointerGetDatum(res),
+                     entry->rel, entry->page,
+                     entry->offset,
+                     FALSE);
+   }
+   else if (!ISALLTRUE(DatumGetPointer(entry->key)))
+   {
+       int32       i;
+       GISTTYPE   *res;
+       BITVECP     sign = GETSIGN(DatumGetPointer(entry->key));
+
+       LOOPBYTE
+       {
+           if ((sign[i] & 0xff) != 0xff)
+               PG_RETURN_POINTER(retval);
+       }
+
+       res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE));
+       SET_VARSIZE(res, CALCGTSIZE(ALLISTRUE));
+       res->flag = ALLISTRUE;
+
+       retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
+       gistentryinit(*retval, PointerGetDatum(res),
+                     entry->rel, entry->page,
+                     entry->offset,
+                     FALSE);
+   }
+
+   PG_RETURN_POINTER(retval);
+}
+
+/*
+ * Since type gjsonb isn't toastable (and doesn't need to be),
+ * this function can be a no-op.
+ */
+Datum
+gjsonb_decompress(PG_FUNCTION_ARGS)
+{
+   PG_RETURN_POINTER(PG_GETARG_POINTER(0));
+}
+
 Datum
 gjsonb_penalty(PG_FUNCTION_ARGS)
 {
@@ -375,20 +501,6 @@ gjsonb_penalty(PG_FUNCTION_ARGS)
    PG_RETURN_POINTER(penalty);
 }
 
-
-typedef struct
-{
-   OffsetNumber pos;
-   int32       cost;
-} SPLITCOST;
-
-static int
-comparecost(const void *a, const void *b)
-{
-   return ((const SPLITCOST *) a)->cost - ((const SPLITCOST *) b)->cost;
-}
-
-
 Datum
 gjsonb_picksplit(PG_FUNCTION_ARGS)
 {
@@ -556,147 +668,34 @@ gjsonb_picksplit(PG_FUNCTION_ARGS)
 }
 
 Datum
-gjsonb_consistent(PG_FUNCTION_ARGS)
+gjsonb_same(PG_FUNCTION_ARGS)
 {
-   GISTTYPE   *entry = (GISTTYPE *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
-   StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
-
-   /* Oid      subtype = PG_GETARG_OID(3); */
-   bool       *recheck = (bool *) PG_GETARG_POINTER(4);
-   bool        res = true;
-   BITVECP     sign;
-
-   /* All cases served by this function are inexact */
-   *recheck = true;
-
-   if (ISALLTRUE(entry))
-       PG_RETURN_BOOL(true);
-
-   sign = GETSIGN(entry);
+   GISTTYPE   *a = (GISTTYPE *) PG_GETARG_POINTER(0);
+   GISTTYPE   *b = (GISTTYPE *) PG_GETARG_POINTER(1);
+   bool       *result = (bool *) PG_GETARG_POINTER(2);
 
-   if (strategy == JsonbContainsStrategyNumber)
+   if (ISALLTRUE(a) && ISALLTRUE(b))
+       *result = true;
+   else if (ISALLTRUE(a))
+       *result = false;
+   else if (ISALLTRUE(b))
+       *result = false;
+   else
    {
-       BITVECP     qe;
-       int         i;
-
-       qe = fcinfo->flinfo->fn_extra;
-       if (qe == NULL)
-       {
-           Jsonb           *query = (Jsonb*) PG_DETOAST_DATUM(PG_GETARG_POINTER(1));
-
-           qe = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(BITVEC));
-           memset(qe, 0, sizeof(BITVEC));
-
-           if (!JB_ISEMPTY(query))
-           {
-               int             r;
-               JsonbIterator   *it = JsonbIteratorInit(VARDATA(query));
-               JsonbValue      v;
-
-               while((r = JsonbIteratorGet(&it, &v, false)) != 0)
-               {
-                   if ((r == WJB_ELEM || r == WJB_KEY || r == WJB_VALUE) && v.type != jbvNull)
-                   {
-                       int   crc = crc32_JsonbValue(&v, r);
-
-                       HASH(qe, crc);
-                   }
-               }
-           }
-
-           fcinfo->flinfo->fn_extra = qe;
-       }
+       int32       i;
+       BITVECP     sa = GETSIGN(a),
+                   sb = GETSIGN(b);
 
+       *result = true;
        LOOPBYTE
        {
-           if ((sign[i] & qe[i]) != qe[i])
+           if (sa[i] != sb[i])
            {
-               res = false;
+               *result = false;
                break;
            }
        }
    }
-   else if (strategy == JsonbExistsStrategyNumber)
-   {
-       int     *qval;
-
-       qval = fcinfo->flinfo->fn_extra;
-       if (qval == NULL)
-       {
-           text       *query = PG_GETARG_TEXT_PP(1);
-           int         crc = crc32_Key(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query));
-
-           qval = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(*qval));
-           *qval = HASHVAL(crc);
-
-           fcinfo->flinfo->fn_extra = qval;
-       }
-
-       res = (GETBIT(sign, *qval)) ? true : false;
-   }
-   else if (strategy == JsonbExistsAllStrategyNumber ||
-            strategy == JsonbExistsAnyStrategyNumber)
-   {
-       BITVECP arrentry;
-       int     i;
-
-       arrentry = fcinfo->flinfo->fn_extra;
-       if (arrentry == NULL)
-       {
-           ArrayType  *query = PG_GETARG_ARRAYTYPE_P(1);
-           Datum      *key_datums;
-           bool       *key_nulls;
-           int         key_count;
-
-           arrentry = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
-                                         sizeof(BITVEC));
-           memset(arrentry, 0, sizeof(BITVEC));
-
-           deconstruct_array(query,
-                             TEXTOID, -1, false, 'i',
-                             &key_datums, &key_nulls, &key_count);
-
-           for (i = 0; i < key_count; ++i)
-           {
-               int         crc;
-
-               if (key_nulls[i])
-                   continue;
-               crc = crc32_Key(VARDATA(key_datums[i]),
-                               VARSIZE(key_datums[i]) - VARHDRSZ);
-               HASH(arrentry, crc);
-           }
-
-           fcinfo->flinfo->fn_extra = arrentry;
-       }
-
-       if (strategy == JsonbExistsAllStrategyNumber)
-       {
-           LOOPBYTE
-           {
-               if ((sign[i] & arrentry[i]) != arrentry[i])
-               {
-                   res = false;
-                   break;
-               }
-           }
-       }
-       else /* JsonbExistsAnyStrategyNumber */
-       {
-           res = false;
-
-           LOOPBYTE
-           {
-               if (sign[i] & arrentry[i])
-               {
-                   res = true;
-                   break;
-               }
-           }
-       }
-   }
-   else
-       elog(ERROR, "unsupported strategy number: %d", strategy);
-
-   PG_RETURN_BOOL(res);
+   PG_RETURN_POINTER(result);
 }
+
index ccf8c3e514e8111fac53720bcbc4b5b1727a9d75..138a5b0368347530bfee47caab7c6f60bfb5f047 100644 (file)
@@ -237,6 +237,7 @@ extern Datum jsonb_out(PG_FUNCTION_ARGS);
 extern Datum jsonb_recv(PG_FUNCTION_ARGS);
 extern Datum jsonb_send(PG_FUNCTION_ARGS);
 
+/* Indexing-related ops */
 extern Datum jsonb_exists(PG_FUNCTION_ARGS);
 extern Datum jsonb_exists_idx(PG_FUNCTION_ARGS);
 extern Datum jsonb_exists_path(PG_FUNCTION_ARGS);
@@ -263,12 +264,13 @@ extern Datum gin_extract_hstore_hash_query(PG_FUNCTION_ARGS);
 
 /* GiST support functions */
 extern Datum gjsonb_consistent(PG_FUNCTION_ARGS);
+extern Datum gjsonb_union(PG_FUNCTION_ARGS);
 extern Datum gjsonb_compress(PG_FUNCTION_ARGS);
 extern Datum gjsonb_decompress(PG_FUNCTION_ARGS);
 extern Datum gjsonb_penalty(PG_FUNCTION_ARGS);
 extern Datum gjsonb_picksplit(PG_FUNCTION_ARGS);
-extern Datum gjsonb_union(PG_FUNCTION_ARGS);
 extern Datum gjsonb_same(PG_FUNCTION_ARGS);
+/* Dummy GiST routines */
 extern Datum gjsonb_in(PG_FUNCTION_ARGS);
 extern Datum gjsonb_out(PG_FUNCTION_ARGS);