Skip to content

Commit 868ccab

Browse files
Add support of DEPENDS/NO DEPENDS ON EXTENSION for MATERIALIZED VIEW. #6390
1 parent 39b6f40 commit 868ccab

35 files changed

+2304
-9
lines changed

web/pgadmin/browser/server_groups/servers/databases/schemas/views/__init__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,15 @@ def _getSQL_existing(self, did, data, vid):
19571957
if 'schema' not in data:
19581958
data['schema'] = res['schema']
19591959

1960+
if self.node_type == 'mview' and (
1961+
old_data.get('dependsonextensions') is None or
1962+
data.get('dependsonextensions') is None
1963+
):
1964+
old_data['dependsonextensions'] = \
1965+
old_data.get('dependsonextensions') or []
1966+
data['dependsonextensions'] = \
1967+
data.get('dependsonextensions') or []
1968+
19601969
# merge vacuum lists into one
19611970
data['vacuum_data'] = {}
19621971
data['vacuum_data']['changed'] = []
@@ -2026,6 +2035,12 @@ def _getSQL_new(self, data):
20262035
if data.get('toast_autovacuum', False):
20272036
data['vacuum_data'] += vacuum_toast
20282037

2038+
if self.node_type == 'mview' and (
2039+
data.get('dependsonextensions') is None
2040+
):
2041+
data['dependsonextensions'] = \
2042+
data.get('dependsonextensions') or []
2043+
20292044
# Privileges
20302045
for aclcol in self.allowed_acls:
20312046
if aclcol in data:

web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ define('pgadmin.node.mview', [
132132
}]);
133133
},
134134
getSchema: function(treeNodeInfo, itemNodeData) {
135+
let nodeObj = pgBrowser.Nodes['extension'];
135136
return new MViewSchema(
136137
(privileges)=>getNodePrivilegeRoleSchema('', treeNodeInfo, itemNodeData, privileges),
137138
()=>getNodeVacuumSettingsSchema(this, treeNodeInfo, itemNodeData),
@@ -142,6 +143,16 @@ define('pgadmin.node.mview', [
142143
return (m.label != 'pg_global');
143144
}),
144145
table_amname_list: ()=>getNodeAjaxOptions('get_access_methods', this, treeNodeInfo, itemNodeData),
146+
extensionsList:()=>getNodeAjaxOptions('nodes', nodeObj, treeNodeInfo, itemNodeData, { cacheLevel: 'server'},
147+
(data)=>{
148+
let res = [];
149+
if (data && _.isArray(data)) {
150+
_.each(data, function(d) {
151+
res.push({label: d.label, value: d.label, data: d});
152+
});
153+
}
154+
return res;
155+
}),
145156
nodeInfo: treeNodeInfo,
146157
},
147158
{

web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.ui.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,23 @@ export default class MViewSchema extends BaseUISchema {
106106
id: 'fillfactor', label: gettext('Fill factor'),
107107
group: gettext('Definition'), mode: ['edit', 'create'],
108108
noEmpty: false, type: 'int', controlProps: {min: 10, max: 100}
109-
},{
109+
},
110+
{
111+
id: 'dependsonextensions',
112+
label: gettext('Depends on extensions'),
113+
group: gettext('Definition'),
114+
type: 'select',
115+
options: this.fieldOptions.extensionsList,
116+
controlProps: {
117+
multiple: true,
118+
allowClear: true,
119+
allowSelectAll: true,
120+
placeholder: gettext('Select the Depends on extensions...'),
121+
},
122+
min_version: 130000,
123+
mode: ['create', 'edit', 'properties']
124+
},
125+
{
110126
id: 'vacuum_settings_str', label: gettext('Storage settings'),
111127
type: 'multiline', group: gettext('Definition'), mode: ['properties'],
112128
},{
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{# ===================== Create new view ===================== #}
2+
{% if display_comments %}
3+
-- View: {{ data.schema }}.{{ data.name }}
4+
5+
-- DROP MATERIALIZED VIEW IF EXISTS {{ conn|qtIdent(data.schema, data.name) }};
6+
7+
{% endif %}
8+
{% if data.name and data.schema and data.definition %}
9+
CREATE MATERIALIZED VIEW{% if add_not_exists_clause %} IF NOT EXISTS{% endif %} {{ conn|qtIdent(data.schema, data.name) }}
10+
{% if data.default_amname and data.default_amname != data.amname %}
11+
USING {{data.amname}}
12+
{% elif not data.default_amname and data.amname %}
13+
USING {{data.amname}}
14+
{% endif %}
15+
{% if(data.fillfactor or data.autovacuum_enabled in ('t', 'f') or data.toast_autovacuum_enabled in ('t', 'f') or data['vacuum_data']|length > 0) %}
16+
{% set ns = namespace(add_comma=false) %}
17+
WITH (
18+
{% if data.fillfactor %}
19+
FILLFACTOR = {{ data.fillfactor }}{% set ns.add_comma = true%}{% endif %}{% if data.autovacuum_enabled in ('t', 'f') %}
20+
{% if ns.add_comma %},
21+
{% endif %}
22+
autovacuum_enabled = {% if data.autovacuum_enabled == 't' %}TRUE{% else %}FALSE{% endif %}{% set ns.add_comma = true%}{% endif %}{% if data.toast_autovacuum_enabled in ('t', 'f') %}
23+
{% if ns.add_comma %},
24+
{% endif %}
25+
toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled == 't' %}TRUE{% else %}FALSE{% endif %}{% set ns.add_comma = true%}{% endif %}
26+
{% for field in data['vacuum_data'] %}
27+
{% if field.value is defined and field.value != '' and field.value != none %}
28+
{% if ns.add_comma %},
29+
{% endif %} {{ field.name }} = {{ field.value|lower }}{% set ns.add_comma = true%}{% endif %}{% endfor %}
30+
{{ '\n' }})
31+
{% endif %}
32+
{% if data.spcname %}TABLESPACE {{ data.spcname }}
33+
{% endif %}AS
34+
{{ data.definition.rstrip(';') }}
35+
{% if data.with_data %}
36+
WITH DATA;
37+
{% else %}
38+
WITH NO DATA;
39+
{% endif %}
40+
{% if data.owner %}
41+
42+
ALTER TABLE IF EXISTS {{ conn|qtIdent(data.schema, data.name) }}
43+
OWNER TO {{ conn|qtIdent(data.owner) }};
44+
{% endif %}
45+
{% if data.dependsonextensions %}
46+
{% for ext in data.dependsonextensions %}
47+
48+
ALTER MATERIALIZED VIEW {{ conn|qtIdent(data.schema, data.name) }}
49+
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
50+
{% endfor %}
51+
{% endif %}
52+
{% if data.comment %}
53+
54+
COMMENT ON MATERIALIZED VIEW {{ conn|qtIdent(data.schema, data.name) }}
55+
IS {{ data.comment|qtLiteral(conn) }};
56+
{% endif %}
57+
{% endif %}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
{# ========================== Fetch Materialized View Properties ========================= #}
2+
{% if (vid and datlastsysoid) or scid %}
3+
SELECT
4+
c.oid,
5+
c.xmin,
6+
c.relname AS name,
7+
c.reltablespace AS spcoid,
8+
c.relispopulated AS with_data,
9+
CASE WHEN length(spcname::text) > 0 THEN spcname ELSE
10+
(SELECT sp.spcname FROM pg_catalog.pg_database dtb
11+
JOIN pg_catalog.pg_tablespace sp ON dtb.dattablespace=sp.oid
12+
WHERE dtb.oid = {{ did }}::oid)
13+
END as spcname,
14+
(SELECT st.setting from pg_catalog.pg_show_all_settings() st
15+
WHERE st.name = 'default_table_access_method') as default_amname,
16+
c.relacl,
17+
nsp.nspname as schema,
18+
pg_catalog.pg_get_userbyid(c.relowner) AS owner,
19+
description AS comment,
20+
(
21+
SELECT array_agg(DISTINCT e.extname)
22+
FROM pg_depend d
23+
JOIN pg_extension e ON d.refobjid = e.oid
24+
WHERE d.objid = c.oid
25+
) AS dependsonextensions,
26+
pg_catalog.pg_get_viewdef(c.oid, true) AS definition,
27+
{# ============= Checks if it is system view ================ #}
28+
{% if vid and datlastsysoid %}
29+
CASE WHEN {{vid}} <= {{datlastsysoid}} THEN True ELSE False END AS system_view,
30+
{% endif %}
31+
pg_catalog.array_to_string(c.relacl::text[], ', ') AS acl,
32+
(SELECT pg_catalog.array_agg(provider || '=' || label) FROM pg_catalog.pg_seclabels sl1 WHERE sl1.objoid=c.oid AND sl1.objsubid=0) AS seclabels,
33+
substring(pg_catalog.array_to_string(c.reloptions, ',')
34+
FROM 'fillfactor=([0-9]*)') AS fillfactor,
35+
(substring(pg_catalog.array_to_string(c.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)'))::BOOL AS autovacuum_enabled,
36+
substring(pg_catalog.array_to_string(c.reloptions, ',')
37+
FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold,
38+
substring(pg_catalog.array_to_string(c.reloptions, ',')
39+
FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_vacuum_scale_factor,
40+
substring(pg_catalog.array_to_string(c.reloptions, ',')
41+
FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold,
42+
substring(pg_catalog.array_to_string(c.reloptions, ',')
43+
FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS autovacuum_analyze_scale_factor,
44+
substring(pg_catalog.array_to_string(c.reloptions, ',')
45+
FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay,
46+
substring(pg_catalog.array_to_string(c.reloptions, ',')
47+
FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit,
48+
substring(pg_catalog.array_to_string(c.reloptions, ',')
49+
FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age,
50+
substring(pg_catalog.array_to_string(c.reloptions, ',')
51+
FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age,
52+
substring(pg_catalog.array_to_string(c.reloptions, ',')
53+
FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age,
54+
(substring(pg_catalog.array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)'))::BOOL AS toast_autovacuum_enabled,
55+
substring(pg_catalog.array_to_string(tst.reloptions, ',')
56+
FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold,
57+
substring(pg_catalog.array_to_string(tst.reloptions, ',')
58+
FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_vacuum_scale_factor,
59+
substring(pg_catalog.array_to_string(tst.reloptions, ',')
60+
FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold,
61+
substring(pg_catalog.array_to_string(tst.reloptions, ',')
62+
FROM 'autovacuum_analyze_scale_factor=([0-9]*[.]?[0-9]*)') AS toast_autovacuum_analyze_scale_factor,
63+
substring(pg_catalog.array_to_string(tst.reloptions, ',')
64+
FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay,
65+
substring(pg_catalog.array_to_string(tst.reloptions, ',')
66+
FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit,
67+
substring(pg_catalog.array_to_string(tst.reloptions, ',')
68+
FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age,
69+
substring(pg_catalog.array_to_string(tst.reloptions, ',')
70+
FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age,
71+
substring(pg_catalog.array_to_string(tst.reloptions, ',')
72+
FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age,
73+
c.reloptions AS reloptions, tst.reloptions AS toast_reloptions, am.amname,
74+
(CASE WHEN c.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable
75+
FROM
76+
pg_catalog.pg_class c
77+
LEFT OUTER JOIN pg_catalog.pg_namespace nsp on nsp.oid = c.relnamespace
78+
LEFT OUTER JOIN pg_catalog.pg_tablespace spc on spc.oid=c.reltablespace
79+
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=c.oid and des.objsubid=0 AND des.classoid='pg_class'::regclass)
80+
LEFT OUTER JOIN pg_catalog.pg_class tst ON tst.oid = c.reltoastrelid
81+
LEFT OUTER JOIN pg_catalog.pg_am am ON am.oid = c.relam
82+
WHERE ((c.relhasrules AND (EXISTS (
83+
SELECT
84+
r.rulename
85+
FROM
86+
pg_catalog.pg_rewrite r
87+
WHERE
88+
((r.ev_class = c.oid)
89+
AND (pg_catalog.bpchar(r.ev_type) = '1'::bpchar)) )))
90+
AND (c.relkind = 'm'::char)
91+
)
92+
{% if (vid and datlastsysoid) %}
93+
AND c.oid = {{vid}}::oid
94+
{% elif scid %}
95+
AND c.relnamespace = {{scid}}::oid
96+
ORDER BY
97+
c.relname
98+
{% endif %}
99+
100+
{% elif type == 'roles' %}
101+
SELECT
102+
pr.rolname
103+
FROM
104+
pg_catalog.pg_roles pr
105+
WHERE
106+
pr.rolcanlogin
107+
ORDER BY
108+
pr.rolname
109+
110+
{% elif type == 'schemas' %}
111+
SELECT
112+
nsp.nspname
113+
FROM
114+
pg_catalog.pg_namespace nsp
115+
WHERE
116+
(nsp.nspname NOT LIKE E'pg\\_%'
117+
AND nsp.nspname != 'information_schema')
118+
{% endif %}

0 commit comments

Comments
 (0)