aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Vondra <tomas.vondra@postgresql.org>2019-04-16 00:01:39 +0200
committerTomas Vondra <tomas.vondra@postgresql.org>2019-04-16 00:01:39 +0200
commit3824ca30d162611fdaade403d3aec449fecd0924 (patch)
treee0d283b730858a43c31ccce486b20cd1d916b0ac
parent4b40e44f07c727c7a82b291d3b60098dd99f3f64 (diff)
downloadpostgresql-3824ca30d162611fdaade403d3aec449fecd0924.tar.gz
postgresql-3824ca30d162611fdaade403d3aec449fecd0924.zip
Fix pg_mcv_list deserialization
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
-rw-r--r--src/backend/statistics/mcv.c2
-rw-r--r--src/test/regress/expected/stats_ext.out11
-rw-r--r--src/test/regress/sql/stats_ext.sql8
3 files changed, 20 insertions, 1 deletions
diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c
index 2daefb26868..05ab6c9bb7a 100644
--- a/src/backend/statistics/mcv.c
+++ b/src/backend/statistics/mcv.c
@@ -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) */
diff --git a/src/test/regress/expected/stats_ext.out b/src/test/regress/expected/stats_ext.out
index b32663459d6..add968abec2 100644
--- a/src/test/regress/expected/stats_ext.out
+++ b/src/test/regress/expected/stats_ext.out
@@ -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 (
diff --git a/src/test/regress/sql/stats_ext.sql b/src/test/regress/sql/stats_ext.sql
index 2a6a23c06d4..d4b2732493a 100644
--- a/src/test/regress/sql/stats_ext.sql
+++ b/src/test/regress/sql/stats_ext.sql
@@ -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