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