Fix hypopg_stats for pre-rls pg versions.

Also fix the view for multi-level hypothetical partitioning.
This commit is contained in:
Julien Rouhaud 2018-07-22 11:31:03 +02:00
parent 37d6cb56ce
commit e15aca553d

View file

@ -111,78 +111,166 @@ AS '$libdir/hypopg', 'hypopg_statistic';
-- The original anyarray columns must be casted to text, because it's not
-- allowed to create a column of such a type.
CREATE VIEW hypopg_stats
WITH (security_barrier = true)
AS
SELECT n.nspname AS schemaname,
t.tablename AS tablename,
a.attname,
s.stainherit AS inherited,
s.stanullfrac AS null_frac,
s.stawidth AS avg_width,
s.stadistinct AS n_distinct,
CASE
WHEN s.stakind1 = 1 THEN s.stavalues1::text
WHEN s.stakind2 = 1 THEN s.stavalues2::text
WHEN s.stakind3 = 1 THEN s.stavalues3::text
WHEN s.stakind4 = 1 THEN s.stavalues4::text
WHEN s.stakind5 = 1 THEN s.stavalues5::text
ELSE NULL::text
END AS most_common_vals,
CASE
WHEN s.stakind1 = 1 THEN s.stanumbers1
WHEN s.stakind2 = 1 THEN s.stanumbers2
WHEN s.stakind3 = 1 THEN s.stanumbers3
WHEN s.stakind4 = 1 THEN s.stanumbers4
WHEN s.stakind5 = 1 THEN s.stanumbers5
ELSE NULL::real[]
END AS most_common_freqs,
CASE
WHEN s.stakind1 = 2 THEN s.stavalues1::text
WHEN s.stakind2 = 2 THEN s.stavalues2::text
WHEN s.stakind3 = 2 THEN s.stavalues3::text
WHEN s.stakind4 = 2 THEN s.stavalues4::text
WHEN s.stakind5 = 2 THEN s.stavalues5::text
ELSE NULL::text
END AS histogram_bounds,
CASE
WHEN s.stakind1 = 3 THEN s.stanumbers1[1]
WHEN s.stakind2 = 3 THEN s.stanumbers2[1]
WHEN s.stakind3 = 3 THEN s.stanumbers3[1]
WHEN s.stakind4 = 3 THEN s.stanumbers4[1]
WHEN s.stakind5 = 3 THEN s.stanumbers5[1]
ELSE NULL::real
END AS correlation,
CASE
WHEN s.stakind1 = 4 THEN s.stavalues1::text
WHEN s.stakind2 = 4 THEN s.stavalues2::text
WHEN s.stakind3 = 4 THEN s.stavalues3::text
WHEN s.stakind4 = 4 THEN s.stavalues4::text
WHEN s.stakind5 = 4 THEN s.stavalues5::text
ELSE NULL::text
END AS most_common_elems,
CASE
WHEN s.stakind1 = 4 THEN s.stanumbers1
WHEN s.stakind2 = 4 THEN s.stanumbers2
WHEN s.stakind3 = 4 THEN s.stanumbers3
WHEN s.stakind4 = 4 THEN s.stanumbers4
WHEN s.stakind5 = 4 THEN s.stanumbers5
ELSE NULL::real[]
END AS most_common_elem_freqs,
CASE
WHEN s.stakind1 = 5 THEN s.stanumbers1
WHEN s.stakind2 = 5 THEN s.stanumbers2
WHEN s.stakind3 = 5 THEN s.stanumbers3
WHEN s.stakind4 = 5 THEN s.stanumbers4
WHEN s.stakind5 = 5 THEN s.stanumbers5
ELSE NULL::real[]
END AS elem_count_histogram
FROM hypopg_statistic() s
JOIN hypopg_table() t ON t.relid = s.starelid
-- TODO change this when multilevel partitioning will be handled
JOIN pg_class c ON c.oid = COALESCE(t.parentid, t.relid)
JOIN pg_attribute a ON c.oid = a.attrelid AND a.attnum = s.staattnum
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE NOT a.attisdropped
AND has_column_privilege(c.oid, a.attnum, 'select'::text)
AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
DO
$_$
DECLARE
v_has_rls bool;
BEGIN
SELECT COUNT(*) = 1 INTO v_has_rls
FROM pg_class c
JOIN pg_attribute a ON a.attrelid = c.oid
WHERE c.relname = 'pg_class'
AND a.attname = 'relrowsecurity';
IF v_has_rls THEN
CREATE VIEW hypopg_stats
WITH (security_barrier = true)
AS
SELECT n.nspname AS schemaname,
t.tablename AS tablename,
a.attname,
s.stainherit AS inherited,
s.stanullfrac AS null_frac,
s.stawidth AS avg_width,
s.stadistinct AS n_distinct,
CASE
WHEN s.stakind1 = 1 THEN s.stavalues1::text
WHEN s.stakind2 = 1 THEN s.stavalues2::text
WHEN s.stakind3 = 1 THEN s.stavalues3::text
WHEN s.stakind4 = 1 THEN s.stavalues4::text
WHEN s.stakind5 = 1 THEN s.stavalues5::text
ELSE NULL::text
END AS most_common_vals,
CASE
WHEN s.stakind1 = 1 THEN s.stanumbers1
WHEN s.stakind2 = 1 THEN s.stanumbers2
WHEN s.stakind3 = 1 THEN s.stanumbers3
WHEN s.stakind4 = 1 THEN s.stanumbers4
WHEN s.stakind5 = 1 THEN s.stanumbers5
ELSE NULL::real[]
END AS most_common_freqs,
CASE
WHEN s.stakind1 = 2 THEN s.stavalues1::text
WHEN s.stakind2 = 2 THEN s.stavalues2::text
WHEN s.stakind3 = 2 THEN s.stavalues3::text
WHEN s.stakind4 = 2 THEN s.stavalues4::text
WHEN s.stakind5 = 2 THEN s.stavalues5::text
ELSE NULL::text
END AS histogram_bounds,
CASE
WHEN s.stakind1 = 3 THEN s.stanumbers1[1]
WHEN s.stakind2 = 3 THEN s.stanumbers2[1]
WHEN s.stakind3 = 3 THEN s.stanumbers3[1]
WHEN s.stakind4 = 3 THEN s.stanumbers4[1]
WHEN s.stakind5 = 3 THEN s.stanumbers5[1]
ELSE NULL::real
END AS correlation,
CASE
WHEN s.stakind1 = 4 THEN s.stavalues1::text
WHEN s.stakind2 = 4 THEN s.stavalues2::text
WHEN s.stakind3 = 4 THEN s.stavalues3::text
WHEN s.stakind4 = 4 THEN s.stavalues4::text
WHEN s.stakind5 = 4 THEN s.stavalues5::text
ELSE NULL::text
END AS most_common_elems,
CASE
WHEN s.stakind1 = 4 THEN s.stanumbers1
WHEN s.stakind2 = 4 THEN s.stanumbers2
WHEN s.stakind3 = 4 THEN s.stanumbers3
WHEN s.stakind4 = 4 THEN s.stanumbers4
WHEN s.stakind5 = 4 THEN s.stanumbers5
ELSE NULL::real[]
END AS most_common_elem_freqs,
CASE
WHEN s.stakind1 = 5 THEN s.stanumbers1
WHEN s.stakind2 = 5 THEN s.stanumbers2
WHEN s.stakind3 = 5 THEN s.stanumbers3
WHEN s.stakind4 = 5 THEN s.stanumbers4
WHEN s.stakind5 = 5 THEN s.stanumbers5
ELSE NULL::real[]
END AS elem_count_histogram
FROM hypopg_statistic() s
JOIN hypopg_table() t ON t.relid = s.starelid
JOIN pg_class c ON c.oid = t.rootid
JOIN pg_attribute a ON c.oid = a.attrelid AND a.attnum = s.staattnum
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE NOT a.attisdropped
AND has_column_privilege(c.oid, a.attnum, 'select'::text)
AND (c.relrowsecurity = false OR NOT row_security_active(c.oid));
ELSE
CREATE VIEW hypopg_stats
WITH (security_barrier = true)
AS
SELECT n.nspname AS schemaname,
t.tablename AS tablename,
a.attname,
s.stainherit AS inherited,
s.stanullfrac AS null_frac,
s.stawidth AS avg_width,
s.stadistinct AS n_distinct,
CASE
WHEN s.stakind1 = 1 THEN s.stavalues1::text
WHEN s.stakind2 = 1 THEN s.stavalues2::text
WHEN s.stakind3 = 1 THEN s.stavalues3::text
WHEN s.stakind4 = 1 THEN s.stavalues4::text
WHEN s.stakind5 = 1 THEN s.stavalues5::text
ELSE NULL::text
END AS most_common_vals,
CASE
WHEN s.stakind1 = 1 THEN s.stanumbers1
WHEN s.stakind2 = 1 THEN s.stanumbers2
WHEN s.stakind3 = 1 THEN s.stanumbers3
WHEN s.stakind4 = 1 THEN s.stanumbers4
WHEN s.stakind5 = 1 THEN s.stanumbers5
ELSE NULL::real[]
END AS most_common_freqs,
CASE
WHEN s.stakind1 = 2 THEN s.stavalues1::text
WHEN s.stakind2 = 2 THEN s.stavalues2::text
WHEN s.stakind3 = 2 THEN s.stavalues3::text
WHEN s.stakind4 = 2 THEN s.stavalues4::text
WHEN s.stakind5 = 2 THEN s.stavalues5::text
ELSE NULL::text
END AS histogram_bounds,
CASE
WHEN s.stakind1 = 3 THEN s.stanumbers1[1]
WHEN s.stakind2 = 3 THEN s.stanumbers2[1]
WHEN s.stakind3 = 3 THEN s.stanumbers3[1]
WHEN s.stakind4 = 3 THEN s.stanumbers4[1]
WHEN s.stakind5 = 3 THEN s.stanumbers5[1]
ELSE NULL::real
END AS correlation,
CASE
WHEN s.stakind1 = 4 THEN s.stavalues1::text
WHEN s.stakind2 = 4 THEN s.stavalues2::text
WHEN s.stakind3 = 4 THEN s.stavalues3::text
WHEN s.stakind4 = 4 THEN s.stavalues4::text
WHEN s.stakind5 = 4 THEN s.stavalues5::text
ELSE NULL::text
END AS most_common_elems,
CASE
WHEN s.stakind1 = 4 THEN s.stanumbers1
WHEN s.stakind2 = 4 THEN s.stanumbers2
WHEN s.stakind3 = 4 THEN s.stanumbers3
WHEN s.stakind4 = 4 THEN s.stanumbers4
WHEN s.stakind5 = 4 THEN s.stanumbers5
ELSE NULL::real[]
END AS most_common_elem_freqs,
CASE
WHEN s.stakind1 = 5 THEN s.stanumbers1
WHEN s.stakind2 = 5 THEN s.stanumbers2
WHEN s.stakind3 = 5 THEN s.stanumbers3
WHEN s.stakind4 = 5 THEN s.stanumbers4
WHEN s.stakind5 = 5 THEN s.stanumbers5
ELSE NULL::real[]
END AS elem_count_histogram
FROM hypopg_statistic() s
JOIN hypopg_table() t ON t.relid = s.starelid
JOIN pg_class c ON c.oid = t.rootid
JOIN pg_attribute a ON c.oid = a.attrelid AND a.attnum = s.staattnum
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE NOT a.attisdropped
AND has_column_privilege(c.oid, a.attnum, 'select'::text);
END IF;
END;
$_$ language plpgsql;