extstats: change output functions to emit valid JSON
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 2 May 2017 21:49:32 +0000 (18:49 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 2 May 2017 21:49:32 +0000 (18:49 -0300)
Manipulating extended statistics is more convenient as JSON than the
current ad-hoc format, so let's change before it's too late.

Discussion: https://postgr.es/m/20170420193828.k3fliiock5hdnehn@alvherre.pgsql

doc/src/sgml/perform.sgml
src/backend/statistics/dependencies.c
src/backend/statistics/mvdistinct.c
src/test/regress/expected/stats_ext.out

index a8bebb14363a4ca06f9389c2352db158cd0a224f..b10b734b901b93a29c8cef5df4b51cd83696a3d7 100644 (file)
@@ -1138,9 +1138,9 @@ ANALYZE zipcodes;
 SELECT stxname, stxkeys, stxdependencies
   FROM pg_statistic_ext
  WHERE stxname = 'stts';
- stxname | stxkeys |              stxdependencies               
----------+---------+--------------------------------------------
- stts    | 1 5     | [{1 => 5 : 1.000000}, {5 => 1 : 0.423130}]
+ stxname | stxkeys |             stxdependencies               
+---------+---------+------------------------------------------
+ stts    | 1 5     | {"1 => 5": 1.000000, "5 => 1": 0.423130}
 (1 row)
 </programlisting>
      where it can be seen that column 1 (a zip code) fully determines column
@@ -1225,10 +1225,9 @@ ANALYZE zipcodes;
 SELECT stxkeys AS k, stxndistinct AS nd
   FROM pg_statistic_ext
  WHERE stxname = 'stts2';
--[ RECORD 1 ]---------------------------------------------
+-[ RECORD 1 ]--------------------------------------------------------
 k  | 1 2 5
-nd | [{(b 1 2), 33178.000000}, {(b 1 5), 33178.000000},
-      {(b 2 5), 27435.000000}, {(b 1 2 5), 33178.000000}]
+nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178}
 (1 row)
 </programlisting>
      which indicates that there are three combinations of columns that
index 0890514bf789effc932020353d9129f2ecfcd1f6..fe9a9ef5de0c77f15cba9eba64a39f9a5394bc52 100644 (file)
@@ -624,7 +624,7 @@ dependency_is_fully_matched(MVDependency * dependency, Bitmapset *attnums)
  *     check that the attnum matches is implied by the functional dependency
  */
 static bool
-dependency_implies_attribute(MVDependency * dependency, AttrNumber attnum)
+dependency_implies_attribute(MVDependency *dependency, AttrNumber attnum)
 {
    if (attnum == dependency->attributes[dependency->nattributes - 1])
        return true;
@@ -641,11 +641,6 @@ staext_dependencies_load(Oid mvoid)
 {
    bool        isnull;
    Datum       deps;
-
-   /*
-    * Prepare to scan pg_statistic_ext for entries having indrelid = this
-    * rel.
-    */
    HeapTuple   htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(mvoid));
 
    if (!HeapTupleIsValid(htup))
@@ -653,7 +648,6 @@ staext_dependencies_load(Oid mvoid)
 
    deps = SysCacheGetAttr(STATEXTOID, htup,
                           Anum_pg_statistic_ext_stxdependencies, &isnull);
-
    Assert(!isnull);
 
    ReleaseSysCache(htup);
@@ -687,16 +681,14 @@ pg_dependencies_in(PG_FUNCTION_ARGS)
 Datum
 pg_dependencies_out(PG_FUNCTION_ARGS)
 {
+   bytea      *data = PG_GETARG_BYTEA_PP(0);
+   MVDependencies *dependencies = statext_dependencies_deserialize(data);
    int         i,
                j;
    StringInfoData str;
 
-   bytea      *data = PG_GETARG_BYTEA_PP(0);
-
-   MVDependencies *dependencies = statext_dependencies_deserialize(data);
-
    initStringInfo(&str);
-   appendStringInfoChar(&str, '[');
+   appendStringInfoChar(&str, '{');
 
    for (i = 0; i < dependencies->ndeps; i++)
    {
@@ -705,7 +697,7 @@ pg_dependencies_out(PG_FUNCTION_ARGS)
        if (i > 0)
            appendStringInfoString(&str, ", ");
 
-       appendStringInfoChar(&str, '{');
+       appendStringInfoChar(&str, '"');
        for (j = 0; j < dependency->nattributes; j++)
        {
            if (j == dependency->nattributes - 1)
@@ -715,11 +707,10 @@ pg_dependencies_out(PG_FUNCTION_ARGS)
 
            appendStringInfo(&str, "%d", dependency->attributes[j]);
        }
-       appendStringInfo(&str, " : %f", dependency->degree);
-       appendStringInfoChar(&str, '}');
+       appendStringInfo(&str, "\": %f", dependency->degree);
    }
 
-   appendStringInfoChar(&str, ']');
+   appendStringInfoChar(&str, '}');
 
    PG_RETURN_CSTRING(str.data);
 }
index b77113fb393c08e598cbde3e6eccbce63f6e78de..f67f57623601c0a713fbd5ef5dd1e5d89e80b61c 100644 (file)
@@ -354,21 +354,26 @@ pg_ndistinct_out(PG_FUNCTION_ARGS)
    StringInfoData str;
 
    initStringInfo(&str);
-   appendStringInfoChar(&str, '[');
+   appendStringInfoChar(&str, '{');
 
    for (i = 0; i < ndist->nitems; i++)
    {
        MVNDistinctItem item = ndist->items[i];
+       int     x = -1;
+       bool    first = true;
 
        if (i > 0)
            appendStringInfoString(&str, ", ");
 
-       appendStringInfoChar(&str, '{');
-       outBitmapset(&str, item.attrs);
-       appendStringInfo(&str, ", %f}", item.ndistinct);
+       while ((x = bms_next_member(item.attrs, x)) >= 0)
+       {
+           appendStringInfo(&str, "%s%d", first ? "\"" : ", ", x);
+           first = false;
+       }
+       appendStringInfo(&str, "\": %d", (int) item.ndistinct);
    }
 
-   appendStringInfoChar(&str, ']');
+   appendStringInfoChar(&str, '}');
 
    PG_RETURN_CSTRING(str.data);
 }
index 72b1014195dc5a05f01a31dede7f3bc63701ad55..92ac84ac67143d63dcd18c7d26e338da8eb9ecf6 100644 (file)
@@ -175,9 +175,9 @@ CREATE STATISTICS s10 ON (a, b, c) FROM ndistinct;
 ANALYZE ndistinct;
 SELECT stxkind, stxndistinct
   FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass;
- stxkind |                                          stxndistinct                                          
----------+------------------------------------------------------------------------------------------------
- {d,f}   | [{(b 3 4), 301.000000}, {(b 3 6), 301.000000}, {(b 4 6), 301.000000}, {(b 3 4 6), 301.000000}]
+ stxkind |                      stxndistinct                       
+---------+---------------------------------------------------------
+ {d,f}   | {"3, 4": 301, "3, 6": 301, "4, 6": 301, "3, 4, 6": 301}
 (1 row)
 
 -- Hash Aggregate, thanks to estimates improved by the statistic
@@ -241,9 +241,9 @@ INSERT INTO ndistinct (a, b, c, filler1)
 ANALYZE ndistinct;
 SELECT stxkind, stxndistinct
   FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass;
- stxkind |                                            stxndistinct                                            
----------+----------------------------------------------------------------------------------------------------
- {d,f}   | [{(b 3 4), 2550.000000}, {(b 3 6), 800.000000}, {(b 4 6), 1632.000000}, {(b 3 4 6), 10000.000000}]
+ stxkind |                        stxndistinct                         
+---------+-------------------------------------------------------------
+ {d,f}   | {"3, 4": 2550, "3, 6": 800, "4, 6": 1632, "3, 4, 6": 10000}
 (1 row)
 
 -- plans using Group Aggregate, thanks to using correct esimates