]> granicus.if.org Git - postgresql/commitdiff
Fix pg_mcv_list deserialization
authorTomas Vondra <tomas.vondra@postgresql.org>
Mon, 15 Apr 2019 22:01:39 +0000 (00:01 +0200)
committerTomas Vondra <tomas.vondra@postgresql.org>
Mon, 15 Apr 2019 22:01:39 +0000 (00:01 +0200)
The memcpy() was copying type OIDs in the wrong direction, so the
deserialized MCV list always had them as 0. This is mostly harmless
except when printing the data in pg_mcv_list_items(), in which case
it reported

    ERROR:  cache lookup failed for type 0

Also added a simple regression test for pg_mcv_list_items() function,
printing a single-item MCV list.

Reported-By: Dean Rasheed
Discussion: https://postgr.es/m/CAEZATCX6T0iDTTZrqyec4Cd6b4yuL7euu4=rQRXaVBAVrUi1Cg@mail.gmail.com

src/backend/statistics/mcv.c
src/test/regress/expected/stats_ext.out
src/test/regress/sql/stats_ext.sql

index 2daefb26868c1ae597ace41b2cf51661f563c300..05ab6c9bb7aee99edeb0afc94848a2d8cdf04b7a 100644 (file)
@@ -905,7 +905,7 @@ statext_mcv_deserialize(bytea *data)
                         VARSIZE_ANY(data), expected_size);
 
        /* Now copy the array of type Oids. */
-       memcpy(ptr, mcvlist->types, sizeof(Oid) * ndims);
+       memcpy(mcvlist->types, ptr, sizeof(Oid) * ndims);
        ptr += (sizeof(Oid) * ndims);
 
        /* ensure alignment of the pointer (after the header fields) */
index b32663459d6beaacaf60345d67217faad6f9d778..add968abec2a1cf0a56c61abccd096fc07b64d29 100644 (file)
@@ -717,6 +717,17 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND
         50 |     50
 (1 row)
 
+-- test pg_mcv_list_items with a very simple (single item) MCV list
+TRUNCATE mcv_lists;
+INSERT INTO mcv_lists (a, b, c) SELECT 1, 2, 3 FROM generate_series(1,1000) s(i);
+ANALYZE mcv_lists;
+SELECT m.* FROM pg_statistic_ext,
+              pg_mcv_list_items(stxmcv) m WHERE stxname = 'mcv_lists_stats';
+ index |  values   |  nulls  | frequency | base_frequency 
+-------+-----------+---------+-----------+----------------
+     0 | {1, 2, 3} | {f,f,f} |         1 |              1
+(1 row)
+
 RESET random_page_cost;
 -- mcv with arrays
 CREATE TABLE mcv_lists_arrays (
index 2a6a23c06d4389921a749aa8320f2c102444c671..d4b2732493adac4d369ec51e4d3bd9fe973511d6 100644 (file)
@@ -411,6 +411,14 @@ SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND
 
 SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL');
 
+-- test pg_mcv_list_items with a very simple (single item) MCV list
+TRUNCATE mcv_lists;
+INSERT INTO mcv_lists (a, b, c) SELECT 1, 2, 3 FROM generate_series(1,1000) s(i);
+ANALYZE mcv_lists;
+
+SELECT m.* FROM pg_statistic_ext,
+              pg_mcv_list_items(stxmcv) m WHERE stxname = 'mcv_lists_stats';
+
 RESET random_page_cost;
 
 -- mcv with arrays