Hi Hackers,
Attached is a patch that makes ACI tree works better with Greenplum.
When connected to a Greenplum database server
- Hide items that not work with GPDB, such as Triggers, FDW, FTS_*, etc
- Tables/Views/Catalogs/Language node can expand correctly
- Views/Languages/Catalogs can show properties dialog with correct
information
- Show a greenplum icon at the server node
Regards,
Teng Zhang & Hao Wang
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/casts/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/casts/__init__.py
index c4c841a4..fd0e8e3a 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/casts/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/casts/__init__.py
@@ -53,6 +53,7 @@ class CastModule(CollectionNodeModule):
def __init__(self, *args, **kwargs):
super(CastModule, self).__init__(*args, **kwargs)
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/event_triggers/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/event_triggers/__init__.py
index 603b7f9e..32dc151c 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/event_triggers/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/event_triggers/__init__.py
@@ -60,6 +60,7 @@ class EventTriggerModule(CollectionNodeModule):
super(EventTriggerModule, self).__init__(*args, **kwargs)
self.min_ver = 90300
self.max_ver = None
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py
index 8d9d108f..46a09237 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/extensions/__init__.py
@@ -60,6 +60,7 @@ class ExtensionModule(CollectionNodeModule):
Initialising the base class
"""
super(ExtensionModule, self).__init__(*args, **kwargs)
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/__init__.py
index d4ba568e..5b6624d5 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/foreign_data_wrappers/__init__.py
@@ -64,6 +64,7 @@ class ForeignDataWrapperModule(CollectionNodeModule):
self.max_ver = None
super(ForeignDataWrapperModule, self).__init__(*args, **kwargs)
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/languages/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/languages/__init__.py
index b1e796e6..80ba7c70 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/languages/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/languages/__init__.py
@@ -223,7 +223,9 @@ class LanguageView(PGChildNodeView):
self.manager = self.driver.connection_manager(kwargs['sid'])
self.conn = self.manager.connection(did=kwargs['did'])
# Set the template path for the SQL scripts
- self.template_path =
"languages/sql/#{0}#".format(self.manager.version)
+ self.template_path =
("languages/sql/#gpdb#{0}#".format(self.manager.version)
+ if self.manager.server_type == 'gpdb'
+ else
"languages/sql/#{0}#".format(self.manager.version))
return f(*args, **kwargs)
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/languages/templates/languages/sql/gpdb_5.0_plus/acl.sql
b/web/pgadmin/browser/server_groups/servers/databases/languages/templates/languages/sql/gpdb_5.0_plus/acl.sql
new file mode 100644
index 00000000..ef55a511
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/languages/templates/languages/sql/gpdb_5.0_plus/acl.sql
@@ -0,0 +1,34 @@
+SELECT 'lanacl' as deftype, COALESCE(gt.rolname, 'PUBLIC') grantee, g.rolname
grantor,
+ array_agg(privilege_type) as privileges, array_agg(is_grantable) as
grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT lanacl FROM pg_language lan
+ LEFT OUTER JOIN pg_shdescription descr ON (lan.oid=descr.objoid
AND descr.classoid='pg_language'::regclass)
+ WHERE lan.oid = {{ lid|qtLiteral }}::OID
+ ) acl,
+ (SELECT
+ u_grantor.oid AS grantor,
+ grantee.oid AS grantee,
+ pr.type AS privilege_type,
+ aclcontains(lan1.lanacl, makeaclitem(grantee.oid, u_grantor.oid,
pr.type, true)) AS is_grantable
+ FROM pg_language lan1, pg_authid u_grantor, (
+ SELECT pg_authid.oid, pg_authid.rolname
+ FROM pg_authid
+ UNION ALL
+ SELECT 0::oid AS oid, 'PUBLIC') grantee(oid, rolname),
+ (SELECT 'USAGE') pr(type)
+ WHERE aclcontains(lan1.lanacl, makeaclitem(grantee.oid, u_grantor.oid,
pr.type, false))
+ AND (pg_has_role(u_grantor.oid, 'USAGE'::text) OR
pg_has_role(grantee.oid, 'USAGE'::text)
+ OR grantee.rolname = 'PUBLIC'::name)
+ AND lan1.oid = {{ lid|qtLiteral }}::OID
+ ) d
+ ) d
+LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/languages/templates/languages/sql/gpdb_5.0_plus/properties.sql
b/web/pgadmin/browser/server_groups/servers/databases/languages/templates/languages/sql/gpdb_5.0_plus/properties.sql
new file mode 100644
index 00000000..ba45c087
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/languages/templates/languages/sql/gpdb_5.0_plus/properties.sql
@@ -0,0 +1,22 @@
+SELECT
+ lan.oid as oid, lanname as name, lanpltrusted as trusted,
+ array_to_string(lanacl::text[], ', ') as acl, hp.proname as lanproc,
+ vp.proname as lanval, description,
+ pg_get_userbyid(lan.lanowner) as lanowner, ip.proname as laninl
+FROM
+ pg_language lan JOIN pg_proc hp ON hp.oid=lanplcallfoid
+ LEFT OUTER JOIN pg_proc ip ON ip.oid=laninline
+ LEFT OUTER JOIN pg_proc vp ON vp.oid=lanvalidator
+ LEFT OUTER JOIN pg_description des
+ ON (
+ des.objoid=lan.oid AND des.objsubid=0 AND
+ des.classoid='pg_language'::regclass
+ )
+WHERE lanispl IS TRUE
+{% if lid %} AND
+ lan.oid={{lid}}::oid
+{% endif %}
+{% if lanname %} AND
+ lanname={{ lanname|qtLiteral }}::text
+{% endif %}
+ORDER BY lanname
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/__init__.py
index 4e1f011b..04d24326 100644
--- a/web/pgadmin/browser/server_groups/servers/databases/schemas/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/__init__.py
@@ -139,11 +139,13 @@ def check_precondition(f):
self.conn = self.manager.connection(did=kwargs['did'])
# Set the template path for the SQL scripts
- self.template_path = self.template_initial + '/' + (
- self.ppas_template_path(self.manager.version)
- if self.manager.server_type == 'ppas' else
- self.pg_template_path(self.manager.version)
- )
+ if self.manager.server_type == 'gpdb':
+ _temp = self.gpdb_template_path(self.manager.version)
+ elif self.manager.server_type == 'ppas':
+ _temp = self.ppas_template_path(self.manager.version)
+ else:
+ _temp = self.pg_template_path(self.manager.version)
+ self.template_path = self.template_initial + '/' + _temp
return f(*args, **kwargs)
@@ -250,6 +252,13 @@ class SchemaView(PGChildNodeView):
"""
return 'pg/#{0}#'.format(ver)
+ @staticmethod
+ def gpdb_template_path(ver):
+ """
+ Returns the template path for GreenPlum servers.
+ """
+ return '#gpdb#{0}#'.format(ver)
+
def format_request_acls(self, data, modified=False, specific=None):
acls = {}
try:
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/__init__.py
index 9cbbf62a..3f3f80bf 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/__init__.py
@@ -65,6 +65,7 @@ class CollationModule(SchemaChildModule):
super(CollationModule, self).__init__(*args, **kwargs)
self.min_ver = 90100
self.max_ver = None
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did, scid):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/__init__.py
index cecdcd97..d00b1872 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/domains/__init__.py
@@ -56,6 +56,7 @@ class DomainModule(SchemaChildModule):
super(DomainModule, self).__init__(*args, **kwargs)
self.min_ver = None
self.max_ver = None
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did, scid):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/__init__.py
index ed383942..1c1d17f8 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/__init__.py
@@ -63,6 +63,7 @@ class ForeignTableModule(SchemaChildModule):
super(ForeignTableModule, self).__init__(*args, **kwargs)
self.min_ver = None
self.max_ver = None
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did, scid):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/__init__.py
index 63ba26df..41fe8a27 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_configurations/__init__.py
@@ -59,6 +59,7 @@ class FtsConfigurationModule(SchemaChildModule):
self.max_ver = None
self.manager = None
super(FtsConfigurationModule, self).__init__(*args, **kwargs)
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did, scid):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/__init__.py
index f0f619e4..658a7bff 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_dictionaries/__init__.py
@@ -58,6 +58,7 @@ class FtsDictionaryModule(SchemaChildModule):
self.max_ver = None
self.manager = None
super(FtsDictionaryModule, self).__init__(*args, **kwargs)
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did, scid):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/__init__.py
index f80b4a12..ba81ff27 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_parser/__init__.py
@@ -48,6 +48,10 @@ class FtsParserModule(SchemaChildModule):
NODE_TYPE = 'fts_parser'
COLLECTION_LABEL = _('FTS Parsers')
+ def __init__(self, *args, **kwargs):
+ super(FtsParserModule, self).__init__(*args, **kwargs)
+ self.min_gpdbver = 1000000000
+
def get_nodes(self, gid, sid, did, scid):
"""
Generate the collection node
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/__init__.py
index fa4df5d0..310ef64b 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/fts_templates/__init__.py
@@ -55,6 +55,7 @@ class FtsTemplateModule(SchemaChildModule):
self.min_ver = None
self.max_ver = None
super(FtsTemplateModule, self).__init__(*args, **kwargs)
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did, scid):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/__init__.py
index e3277e34..dd677a1d 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/__init__.py
@@ -74,6 +74,7 @@ class FunctionModule(SchemaChildModule):
self.min_ver = 90100
self.max_ver = None
self.server_type = None
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did, scid):
"""
@@ -1550,6 +1551,7 @@ class ProcedureModule(SchemaChildModule):
self.min_ver = 90100
self.max_ver = None
+ self.min_gpdbver = 1000000000
self.server_type = ['ppas']
def get_nodes(self, gid, sid, did, scid):
@@ -1661,6 +1663,7 @@ class TriggerFunctionModule(SchemaChildModule):
self.min_ver = 90100
self.max_ver = None
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did, scid):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/__init__.py
index d886596c..7419abe1 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/sequences/__init__.py
@@ -60,6 +60,7 @@ class SequenceModule(SchemaChildModule):
super(SequenceModule, self).__init__(*args, **kwargs)
self.min_ver = None
self.max_ver = None
+ self.min_gpdbver = 1000000000
def get_nodes(self, gid, sid, did, scid):
"""
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
index 41918164..25b38b6e 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py
@@ -88,6 +88,8 @@ class PartitionsModule(CollectionNodeModule):
"""
Load this module if it is a partition table
"""
+ if manager.server_type == 'gpdb':
+ return False
if 'tid' in kwargs and CollectionNodeModule.BackendSupported(self,
manager, **kwargs):
conn = manager.connection(did=kwargs['did'])
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
index 19dcf8af..7b2c6101 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/__init__.py
@@ -62,6 +62,7 @@ class TriggerModule(CollectionNodeModule):
"""
self.min_ver = None
self.max_ver = None
+ self.min_gpdbver = 1000000000
super(TriggerModule, self).__init__(*args, **kwargs)
def BackendSupported(self, manager, **kwargs):
@@ -69,6 +70,8 @@ class TriggerModule(CollectionNodeModule):
Load this module if vid is view, we will not load it under
material view
"""
+ if manager.server_type == 'gpdb':
+ return False
if super(TriggerModule, self).BackendSupported(manager, **kwargs):
conn = manager.connection(did=kwargs['did'])
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/macros/catalogs.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/macros/catalogs.sql
new file mode 100644
index 00000000..f911e10f
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/macros/catalogs.sql
@@ -0,0 +1,21 @@
+{% macro LIST(tbl) -%}
+ ({{ tbl }}.nspname = 'pg_catalog' AND EXISTS
+ (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND
+ relnamespace = {{ tbl }}.oid LIMIT 1)) OR
+ ({{ tbl }}.nspname = 'information_schema' AND EXISTS
+ (SELECT 1 FROM pg_class WHERE relname = 'tables' AND
+ relnamespace = {{ tbl }}.oid LIMIT 1))
+{%- endmacro %}
+{% macro LABELS(tbl, _) -%}
+ CASE {{ tbl }}.nspname
+ WHEN 'pg_catalog' THEN '{{ _( 'PostgreSQL Catalog' ) }} (pg_catalog)'
+ WHEN 'information_schema' THEN '{{ _( 'ANSI' ) }} (information_schema)'
+ ELSE {{ tbl }}.nspname
+ END AS name
+{%- endmacro %}
+{% macro DB_SUPPORT(tbl) -%}
+ CASE
+ WHEN {{ tbl }}.nspname = ANY('{information_schema}')
+ THEN false
+ ELSE true END
+{%- endmacro %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/acl.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/acl.sql
new file mode 100644
index 00000000..a4a53863
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/acl.sql
@@ -0,0 +1,38 @@
+{# Fetch privileges for schema #}
+SELECT
+ 'nspacl' as deftype, COALESCE(gt.rolname, 'PUBLIC') AS grantee,
+ g.rolname AS grantor, array_agg(b.privilege_type) AS privileges,
+ array_agg(b.is_grantable) AS grantable
+FROM
+ (SELECT
+ (d).grantee AS grantee, (d).grantor AS grantor,
+ (d).is_grantable AS is_grantable,
+ CASE (d).privilege_type
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN - ' || (d).privilege_type
+ END AS privilege_type
+ FROM
+ (
+ SELECT
+ u_grantor.oid AS grantor,
+ grantee.oid AS grantee,
+ pr.type AS privilege_type,
+ aclcontains(nc.nspacl, makeaclitem(grantee.oid, u_grantor.oid,
pr.type, true)) AS is_grantable
+ FROM pg_namespace nc, pg_authid u_grantor, (
+ SELECT pg_authid.oid, pg_authid.rolname
+ FROM pg_authid
+ UNION ALL
+ SELECT 0::oid AS oid, 'PUBLIC') grantee(oid, rolname),
+ ( SELECT 'CREATE'
+ UNION ALL
+ SELECT 'USAGE') pr(type)
+ WHERE aclcontains(nc.nspacl, makeaclitem(grantee.oid, u_grantor.oid,
pr.type, false))
+ AND (pg_has_role(u_grantor.oid, 'USAGE'::text) OR
pg_has_role(grantee.oid, 'USAGE'::text)
+ OR grantee.rolname = 'PUBLIC'::name)
+ AND nsp.oid = {{ scid|qtLiteral }}::OID
+ ) a
+ ) b
+ LEFT JOIN pg_catalog.pg_roles g ON (b.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (b.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/create.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/create.sql
new file mode 100644
index 00000000..12dd1025
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/create.sql
@@ -0,0 +1,17 @@
+{% import 'macros/privilege.macros' as PRIVILEGE %}
+{% if data %}
+CREATE SCHEMA {{ conn|qtIdent(data.name) }}
+{% if data.namespaceowner %}
+ AUTHORIZATION {{ conn|qtIdent(data.namespaceowner) }};
+
+{% endif %}
+{% if data.description %}
+COMMENT ON SCHEMA {{ conn|qtIdent(data.name) }}
+ IS {{ data.description|qtLiteral }};
+
+{% endif %}
+{% if data.nspacl %}
+{% for priv in data.nspacl %}
+{{ PRIVILEGE.APPLY(conn, 'SCHEMA', priv.grantee, data.name,
priv.without_grant, priv.with_grant) }}{% endfor %}
+{% endif %}
+{% endif %}
\ No newline at end of file
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/get_name.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/get_name.sql
new file mode 100644
index 00000000..3c5187dc
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/get_name.sql
@@ -0,0 +1 @@
+SELECT nsp.nspname FROM pg_namespace nsp WHERE nsp.oid = {{ scid|qtLiteral }};
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/is_catalog.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/is_catalog.sql
new file mode 100644
index 00000000..9386acbf
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/is_catalog.sql
@@ -0,0 +1,9 @@
+{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
+SELECT
+ nsp.nspname as schema_name,
+ {{ CATALOGS.LIST('nsp') }} AS is_catalog,
+ {{ CATALOGS.DB_SUPPORT('nsp') }} AS db_support
+FROM
+ pg_catalog.pg_namespace nsp
+WHERE
+ nsp.oid = {{ scid|qtLiteral }}::OID;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/nodes.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/nodes.sql
new file mode 100644
index 00000000..c75e7ba5
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/nodes.sql
@@ -0,0 +1,16 @@
+{% import 'catalog/gpdb_5.0_plus/macros/catalogs.sql' as CATALOGS %}
+SELECT
+ nsp.oid,
+{{ CATALOGS.LABELS('nsp', _) }},
+ has_schema_privilege(nsp.oid, 'CREATE') as can_create,
+ has_schema_privilege(nsp.oid, 'USAGE') as has_usage
+FROM
+ pg_namespace nsp
+WHERE
+ {% if scid %}
+ nsp.oid={{scid}}::oid AND
+ {% endif %}
+ (
+{{ CATALOGS.LIST('nsp') }}
+ )
+ORDER BY 2;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/properties.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/properties.sql
new file mode 100644
index 00000000..2f443ce0
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/properties.sql
@@ -0,0 +1,24 @@
+{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
+SELECT
+ 2 AS nsptyp,
+ nsp.nspname AS name,
+ nsp.oid,
+ array_to_string(nsp.nspacl::text[], ', ') as acl,
+ r.rolname AS namespaceowner, description,
+ has_schema_privilege(nsp.oid, 'CREATE') AS can_create,
+ CASE
+ WHEN nspname LIKE E'pg\\_%' THEN true
+ ELSE false END AS is_sys_object
+FROM
+ pg_namespace nsp
+ LEFT OUTER JOIN pg_description des ON
+ (des.objoid=nsp.oid AND des.classoid='pg_namespace'::regclass)
+ LEFT JOIN pg_roles r ON (r.oid = nsp.nspowner)
+WHERE
+ {% if scid %}
+ nsp.oid={{scid}}::oid AND
+ {% endif %}
+ (
+{{ CATALOGS.LIST('nsp') }}
+ )
+ORDER BY 1, nspname;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/update.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/update.sql
new file mode 100644
index 00000000..39f7f94c
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/gpdb_5.0_plus/sql/update.sql
@@ -0,0 +1,30 @@
+{% import 'macros/security.macros' as SECLABEL %}
+{% if data %}
+{# ==== To update catalog comments ==== #}
+{% if data.description and data.description != o_data.description %}
+COMMENT ON SCHEMA {{ conn|qtIdent(o_data.name) }}
+ IS {{ data.description|qtLiteral }};
+
+{% endif %}
+{# ==== To update catalog securitylabel ==== #}
+{# The SQL generated below will change Security Label #}
+{% if data.seclabels and data.seclabels|length > 0 %}
+{% set seclabels = data.seclabels %}
+{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
+{% for r in seclabels.deleted %}
+{{ SECLABEL.DROP(conn, 'SCHEMA', o_data.name, r.provider) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in seclabels and seclabels.added|length > 0 %}
+{% for r in seclabels.added %}
+{{ SECLABEL.APPLY(conn, 'SCHEMA', o_data.name, r.provider, r.label) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
+{% for r in seclabels.changed %}
+{{ SECLABEL.APPLY(conn, 'SCHEMA', o_data.name, r.provider, r.label) }}
+{% endfor %}
+{% endif %}
+
+{% endif %}
+{% endif %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/allowed_privs.json
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/allowed_privs.json
new file mode 100644
index 00000000..61dfdfe9
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/allowed_privs.json
@@ -0,0 +1,30 @@
+{# List of allowed privileges for PostgreSQL 9.2 or later #}
+{#
+ Format for allowed privileges is:
+ "acl_col": {
+ "type": "name",
+ "acl": [...]
+ }
+#}
+{
+ "nspacl": {
+ "type": "SCHEMA",
+ "acl": ["C", "U"]
+ },
+ "deftblacl": {
+ "type": "TABLE",
+ "acl": ["r", "a", "w", "d", "D", "x", "t"]
+ },
+ "defseqacl": {
+ "type": "SEQUENCE",
+ "acl": ["U", "r", "a"]
+ },
+ "deffuncacl": {
+ "type": "FUNCTION",
+ "acl": ["X"]
+ },
+ "deftypeacl": {
+ "type": "TYPE",
+ "acl": ["U"]
+ }
+}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/acl.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/acl.sql
new file mode 100644
index 00000000..e1e64be6
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/acl.sql
@@ -0,0 +1,23 @@
+{# Fetch privileges for schema #}
+SELECT
+ 'nspacl' as deftype, COALESCE(gt.rolname, 'PUBLIC') AS grantee,
+ g.rolname AS grantor, array_agg(b.privilege_type) AS privileges,
+ array_agg(b.is_grantable) AS grantable
+FROM
+ (SELECT
+ (d).grantee AS grantee, (d).grantor AS grantor,
+ (d).is_grantable AS is_grantable,
+ CASE (d).privilege_type
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN - ' || (d).privilege_type
+ END AS privilege_type
+ FROM
+ (SELECT aclexplode(nsp.nspacl) as d
+ FROM pg_namespace nsp
+ WHERE nsp.oid = {{ scid|qtLiteral }}::OID
+ ) a
+ ) b
+ LEFT JOIN pg_catalog.pg_roles g ON (b.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (b.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/create.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/create.sql
new file mode 100644
index 00000000..2016209b
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/create.sql
@@ -0,0 +1,40 @@
+{% import 'macros/security.macros' as SECLABEL %}
+{% import 'macros/privilege.macros' as PRIVILEGE %}
+{% import 'macros/default_privilege.macros' as DEFAULT_PRIVILEGE %}
+{% if data.name %}
+CREATE SCHEMA {{ conn|qtIdent(data.name) }}{% if data.namespaceowner %}
+
+ AUTHORIZATION {{ conn|qtIdent(data.namespaceowner) }}{% endif %}{% endif
%};
+{# Alter the comment/description #}
+{% if data.description %}
+
+COMMENT ON SCHEMA {{ conn|qtIdent(data.name) }}
+ IS {{ data.description|qtLiteral }};
+{% endif %}
+{# ACL for the schema #}
+{% if data.nspacl %}
+{% for priv in data.nspacl %}
+
+{{ PRIVILEGE.APPLY(conn, 'SCHEMA', priv.grantee, data.name,
priv.without_grant, priv.with_grant) }}{% endfor %}
+{% endif %}
+{# Default privileges on tables #}
+{% for defacl, type in [
+ ('deftblacl', 'TABLES'), ('defseqacl', 'SEQUENCES'),
+ ('deffuncacl', 'FUNCTIONS'), ('deftypeacl', 'TYPES')]
+%}
+{% if data[defacl] %}{% set acl = data[defacl] %}
+{% for priv in acl %}
+
+{{ DEFAULT_PRIVILEGE.SET(
+ conn, 'SCHEMA', data.name, type, priv.grantee,
+ priv.without_grant, priv.with_grant
+ ) }}{% endfor %}
+{% endif %}
+{% endfor %}
+{# Security Labels on schema #}
+{% if data.seclabels and data.seclabels|length > 0 %}
+{% for r in data.seclabels %}
+
+{{ SECLABEL.APPLY(conn, 'SCHEMA', data.name, r.provider, r.label) }}
+{% endfor %}
+{% endif %}
\ No newline at end of file
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/defacl.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/defacl.sql
new file mode 100644
index 00000000..91c3085d
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/defacl.sql
@@ -0,0 +1,40 @@
+SELECT
+ CASE (a.deftype)
+ WHEN 'r' THEN 'deftblacl'
+ WHEN 'S' THEN 'defseqacl'
+ WHEN 'f' THEN 'deffuncacl'
+ WHEN 'T' THEN 'deftypeacl'
+ ELSE 'UNKNOWN - ' || a.deftype
+ END AS deftype,
+ COALESCE(gt.rolname, 'PUBLIC') grantee, g.rolname grantor,
array_agg(a.privilege_type) as privileges, array_agg(a.is_grantable) as
grantable
+FROM
+ (SELECT
+ (acl).grantee as grantee, (acl).grantor AS grantor, (acl).is_grantable
AS is_grantable,
+ CASE (acl).privilege_type
+ WHEN 'CONNECT' THEN 'c'
+ WHEN 'CREATE' THEN 'C'
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'EXECUTE' THEN 'X'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TEMPORARY' THEN 'T'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'TRUNCATE' THEN 'D'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'USAGE' THEN 'U'
+ ELSE 'UNKNOWN - ' || (acl).privilege_type
+ END AS privilege_type,
+ defaclobjtype as deftype
+ FROM
+ (SELECT defaclobjtype, aclexplode(defaclacl) as acl
+ FROM
+ pg_namespace nsp
+ LEFT OUTER JOIN pg_catalog.pg_default_acl dacl ON
(dacl.defaclnamespace = nsp.oid)
+ WHERE
+ nsp.oid={{scid}}::oid
+ ) d) a
+ LEFT JOIN pg_catalog.pg_roles g ON (a.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (a.grantee = gt.oid)
+GROUP BY g.rolname, gt.rolname, a.deftype
+ORDER BY a.deftype;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/delete.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/delete.sql
new file mode 100644
index 00000000..74e9126d
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/delete.sql
@@ -0,0 +1 @@
+DROP SCHEMA {{ conn|qtIdent(name) }} {% if cascade %}CASCADE{%endif%};
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/get_name.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/get_name.sql
new file mode 100644
index 00000000..3c5187dc
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/get_name.sql
@@ -0,0 +1 @@
+SELECT nsp.nspname FROM pg_namespace nsp WHERE nsp.oid = {{ scid|qtLiteral }};
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/is_catalog.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/is_catalog.sql
new file mode 100644
index 00000000..9386acbf
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/is_catalog.sql
@@ -0,0 +1,9 @@
+{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
+SELECT
+ nsp.nspname as schema_name,
+ {{ CATALOGS.LIST('nsp') }} AS is_catalog,
+ {{ CATALOGS.DB_SUPPORT('nsp') }} AS db_support
+FROM
+ pg_catalog.pg_namespace nsp
+WHERE
+ nsp.oid = {{ scid|qtLiteral }}::OID;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/nodes.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/nodes.sql
new file mode 100644
index 00000000..df742abc
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/nodes.sql
@@ -0,0 +1,20 @@
+{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
+SELECT
+ nsp.oid,
+ nsp.nspname as name,
+ has_schema_privilege(nsp.oid, 'CREATE') as can_create,
+ has_schema_privilege(nsp.oid, 'USAGE') as has_usage
+FROM
+ pg_namespace nsp
+WHERE
+ {% if scid %}
+ nsp.oid={{scid}}::oid AND
+ {% else %}
+ {% if not show_sysobj %}
+ nspname NOT LIKE E'pg\_%' AND
+ {% endif %}
+ {% endif %}
+ NOT (
+{{ CATALOGS.LIST('nsp') }}
+ )
+ORDER BY nspname;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/oid.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/oid.sql
new file mode 100644
index 00000000..c5329b39
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/oid.sql
@@ -0,0 +1 @@
+SELECT nsp.oid FROM pg_namespace nsp WHERE nsp.nspname = {{ schema|qtLiteral
}};
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/properties.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/properties.sql
new file mode 100644
index 00000000..ca2254d0
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/properties.sql
@@ -0,0 +1,57 @@
+{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %}
+SELECT
+ CASE
+ WHEN (nspname LIKE E'pg\\_temp\\_%') THEN 1
+ WHEN (nspname LIKE E'pg\\_%') THEN 0
+ ELSE 3 END AS nsptyp,
+ nsp.nspname AS name,
+ nsp.oid,
+ array_to_string(nsp.nspacl::text[], ', ') as acl,
+ r.rolname AS namespaceowner, description,
+ has_schema_privilege(nsp.oid, 'CREATE') AS can_create,
+ CASE
+ WHEN nspname LIKE E'pg\\_%' THEN true
+ ELSE false END AS is_sys_object,
+ {### Default ACL for Tables ###}
+ (SELECT array_to_string(ARRAY(
+ SELECT array_to_string(defaclacl::text[], ', ')
+ FROM pg_default_acl
+ WHERE defaclobjtype = 'r' AND defaclnamespace = nsp.oid
+ ), ', ')) AS tblacl,
+ {### Default ACL for Sequnces ###}
+ (SELECT array_to_string(ARRAY(
+ SELECT array_to_string(defaclacl::text[], ', ')
+ FROM pg_default_acl
+ WHERE defaclobjtype = 'S' AND defaclnamespace = nsp.oid
+ ), ', ')) AS seqacl,
+ {### Default ACL for Functions ###}
+ (SELECT array_to_string(ARRAY(
+ SELECT array_to_string(defaclacl::text[], ', ')
+ FROM pg_default_acl
+ WHERE defaclobjtype = 'f' AND defaclnamespace = nsp.oid
+ ), ', ')) AS funcacl,
+ {### Default ACL for Type ###}
+ (SELECT array_to_string(ARRAY(
+ SELECT array_to_string(defaclacl::text[], ', ')
+ FROM pg_default_acl
+ WHERE defaclobjtype = 'T' AND defaclnamespace = nsp.oid
+ ), ', ')) AS typeacl,
+ (SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE
sl1.objoid=nsp.oid) AS seclabels
+FROM
+ pg_namespace nsp
+ LEFT OUTER JOIN pg_description des ON
+ (des.objoid=nsp.oid AND des.classoid='pg_namespace'::regclass)
+ LEFT JOIN pg_roles r ON (r.oid = nsp.nspowner)
+WHERE
+ {% if scid %}
+ nsp.oid={{scid}}::oid AND
+ {% else %}
+ {% if show_sysobj %}
+ nspname NOT LIKE E'pg\\_temp\\_%' AND
+ nspname NOT LIKE E'pg\\_toast\\_temp\\_%' AND
+ {% endif %}
+ {% endif %}
+ NOT (
+{{ CATALOGS.LIST('nsp') }}
+ )
+ORDER BY 1, nspname;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/update.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/update.sql
new file mode 100644
index 00000000..47f6e134
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/schema/gpdb_5.0_plus/sql/update.sql
@@ -0,0 +1,83 @@
+{% import 'macros/security.macros' as SECLABEL %}
+{% import 'macros/privilege.macros' as PRIVILEGE %}
+{% import 'macros/default_privilege.macros' as DEFAULT_PRIVILEGE %}
+{# Rename the schema #}
+{% if data.name and data.name != o_data.name %}
+ALTER SCHEMA {{ conn|qtIdent(o_data.name) }}
+ RENAME TO {{ conn|qtIdent(data.name) }};
+
+{% endif %}
+{# Change the owner #}
+{% if data.namespaceowner and data.namespaceowner != o_data.namespaceowner %}
+ALTER SCHEMA {{ conn|qtIdent(data.name) }}
+ OWNER TO {{ conn|qtIdent(data.namespaceowner) }};
+
+{% endif %}
+{# Update the comments/description #}
+{% if data.description is defined and data.description != o_data.description %}
+COMMENT ON SCHEMA {{ conn|qtIdent(data.name) }}
+ IS {{ data.description|qtLiteral }};
+
+{% endif %}
+{# Change the privileges #}
+{% if data.nspacl %}
+{% if 'deleted' in data.nspacl %}
+{% for priv in data.nspacl.deleted %}
+{{ PRIVILEGE.RESETALL(conn, 'SCHEMA', priv.grantee, data.name) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.nspacl %}
+{% for priv in data.nspacl.changed %}
+{{ PRIVILEGE.RESETALL(conn, 'SCHEMA', priv.grantee, data.name) }}
+{{ PRIVILEGE.APPLY(conn, 'SCHEMA', priv.grantee, data.name,
priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.nspacl %}
+{% for priv in data.nspacl.added %}
+{{ PRIVILEGE.APPLY(conn, 'SCHEMA', priv.grantee, data.name,
priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+{# Change the default privileges #}
+{% for defacl, type in [
+ ('deftblacl', 'TABLES'), ('defseqacl', 'SEQUENCES'),
+ ('deffuncacl', 'FUNCTIONS'), ('deftypeacl', 'TYPES')]
+%}
+{% if data[defacl] %}{% set acl = data[defacl] %}
+{% if 'deleted' in acl %}
+{% for priv in acl.deleted %}
+{{ DEFAULT_PRIVILEGE.UNSET(conn, 'SCHEMA', data.name, type, priv.grantee) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in acl %}
+{% for priv in acl.changed %}
+{{ DEFAULT_PRIVILEGE.UNSET(conn, 'SCHEMA', data.name, type, priv.grantee) }}
+{{ DEFAULT_PRIVILEGE.SET(conn,'SCHEMA', data.name, type, priv.grantee,
priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in acl %}
+{% for priv in acl.added %}
+{{ DEFAULT_PRIVILEGE.SET(conn,'SCHEMA', data.name, type, priv.grantee,
priv.without_grant, priv.with_grant) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+{% endfor %}
+{# Change the security labels #}
+{% if data.seclabels and data.seclabels|length > 0 %}
+{% set seclabels = data.seclabels %}
+{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
+{% for r in seclabels.deleted %}
+{{ SECLABEL.DROP(conn, 'SCHEMA', data.name, r.provider) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in seclabels and seclabels.added|length > 0 %}
+{% for r in seclabels.added %}
+{{ SECLABEL.APPLY(conn, 'SCHEMA', data.name, r.provider, r.label) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
+{% for r in seclabels.changed %}
+{{ SECLABEL.APPLY(conn, 'SCHEMA', data.name, r.provider, r.label) }}
+{% endfor %}
+{% endif %}
+{% endif %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/__init__.py
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/__init__.py
index 30d8dd93..c57bdab3 100644
---
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/__init__.py
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/__init__.py
@@ -143,6 +143,7 @@ class MViewModule(ViewModule):
super(MViewModule, self).__init__(*args, **kwargs)
self.min_ver = 90300
self.max_ver = None
+ self.min_gpdbver = 1000000000
view_blueprint = ViewModule(__name__)
@@ -176,11 +177,13 @@ def check_precondition(f):
kwargs['did'] in self.manager.db_info else 0
# Set template path for sql scripts
- self.template_path = self.template_initial + '/' + (
- self.ppas_template_path(self.manager.version)
- if self.manager.server_type == 'ppas' else
- self.pg_template_path(self.manager.version)
- )
+ if self.manager.server_type == 'gpdb':
+ _temp = self.gpdb_template_path(self.manager.version)
+ elif self.manager.server_type == 'ppas':
+ _temp = self.ppas_template_path(self.manager.version)
+ else:
+ _temp = self.pg_template_path(self.manager.version)
+ self.template_path = self.template_initial + '/' + _temp
self.column_template_path =
'column/sql/#{0}#'.format(self.manager.version)
@@ -313,6 +316,13 @@ class ViewNode(PGChildNodeView, VacuumSettings):
"""
return 'pg/#{0}#'.format(ver)
+ @staticmethod
+ def gpdb_template_path(ver):
+ """
+ Returns the template path for GreenPlum servers.
+ """
+ return '#gpdb#{0}#'.format(ver)
+
@check_precondition
def list(self, gid, sid, did, scid):
"""
@@ -859,6 +869,9 @@ class ViewNode(PGChildNodeView, VacuumSettings):
generate their sql and render
into sql tab
"""
+ if self.manager.server_type == 'gpdb':
+ return ''
+
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
import trigger_definition
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/acl.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/acl.sql
new file mode 100644
index 00000000..64ed13b4
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/acl.sql
@@ -0,0 +1,74 @@
+{# ============================ Get ACLs ========================= #}
+{% if vid %}
+SELECT
+ 'datacl' as deftype,
+ COALESCE(gt.rolname, 'PUBLIC') grantee,
+ g.rolname grantor,
+ array_agg(privilege_type) as privileges,
+ array_agg(is_grantable) as grantable
+FROM
+ (SELECT
+ d.grantee, d.grantor, d.is_grantable,
+ CASE d.privilege_type
+ WHEN 'DELETE' THEN 'd'
+ WHEN 'INSERT' THEN 'a'
+ WHEN 'REFERENCES' THEN 'x'
+ WHEN 'SELECT' THEN 'r'
+ WHEN 'TRIGGER' THEN 't'
+ WHEN 'UPDATE' THEN 'w'
+ WHEN 'TRUNCATE' THEN 'D'
+ ELSE 'UNKNOWN'
+ END AS privilege_type
+ FROM
+ (SELECT
+ relacl
+ FROM
+ pg_class cl
+ LEFT OUTER JOIN pg_shdescription descr ON (
+ cl.oid=descr.objoid AND descr.classoid='pg_class'::regclass)
+ WHERE
+ cl.oid = {{ vid }}::OID AND relkind = 'v'
+ ) acl,
+ (SELECT
+ (d).grantee AS grantee,
+ (d).grantor AS grantor,
+ (d).is_grantable AS is_grantable,
+ (d).privilege_type AS privilege_type
+ FROM
+ (SELECT
+ u_grantor.oid AS grantor,
+ grantee.oid AS grantee,
+ pr.type AS privilege_type,
+ aclcontains(c.relacl, makeaclitem(grantee.oid, u_grantor.oid,
pr.type, true)) AS is_grantable
+ FROM pg_class c, pg_namespace nc, pg_authid u_grantor, (
+ SELECT pg_authid.oid, pg_authid.rolname
+ FROM pg_authid
+ UNION ALL
+ SELECT 0::oid AS oid, 'PUBLIC') grantee(oid, rolname),
+ ( SELECT 'SELECT'
+ UNION ALL
+ SELECT 'INSERT'
+ UNION ALL
+ SELECT 'UPDATE'
+ UNION ALL
+ SELECT 'DELETE'
+ UNION ALL
+ SELECT 'TRUNCATE'
+ UNION ALL
+ SELECT 'REFERENCES'
+ UNION ALL
+ SELECT 'TRIGGER') pr(type)
+ WHERE c.relnamespace = nc.oid
+ AND (c.relkind = ANY (ARRAY['r'::"char", 'v'::"char"]))
+ AND aclcontains(c.relacl, makeaclitem(grantee.oid, u_grantor.oid,
pr.type, false))
+ AND (pg_has_role(u_grantor.oid, 'USAGE'::text) OR
pg_has_role(grantee.oid, 'USAGE'::text)
+ OR grantee.rolname = 'PUBLIC'::name)
+ AND c.oid = {{ vid }}
+ ) d
+ ) d
+ ) d
+ LEFT JOIN pg_catalog.pg_roles g ON (d.grantor = g.oid)
+ LEFT JOIN pg_catalog.pg_roles gt ON (d.grantee = gt.oid)
+GROUP BY
+ g.rolname, gt.rolname
+{% endif %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/allowed_privs.json
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/allowed_privs.json
new file mode 100644
index 00000000..71f317fb
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/allowed_privs.json
@@ -0,0 +1,6 @@
+{
+ "datacl": {
+ "type": "VIEW",
+ "acl": ["a", "r", "w", "d", "D", "x", "t"]
+ }
+}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/create.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/create.sql
new file mode 100644
index 00000000..5720b140
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/create.sql
@@ -0,0 +1,20 @@
+{#============================Create new view=========================#}
+{% if display_comments %}
+-- View: {{ conn|qtIdent(data.schema, data.name) }}
+
+-- DROP VIEW {{ conn|qtIdent(data.schema, data.name) }};
+
+{% endif %}
+{% if data.name and data.schema and data.definition %}
+CREATE OR REPLACE VIEW {{ conn|qtIdent(data.schema, data.name) }} AS
+{{ data.definition.rstrip(';') }};
+{% if data.owner %}
+
+ALTER TABLE {{ conn|qtIdent(data.schema, data.name) }}
+ OWNER TO {{ conn|qtIdent(data.owner) }};
+{% endif %}
+{% if data.comment %}
+COMMENT ON VIEW {{ conn|qtIdent(data.schema, data.name) }}
+ IS {{ data.comment|qtLiteral }};
+{% endif %}
+{% endif %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/delete.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/delete.sql
new file mode 100644
index 00000000..b1c173f9
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/delete.sql
@@ -0,0 +1,13 @@
+{# ====================== Drop/Cascade view by name ===================== #}
+{% if vid %}
+SELECT
+ c.relname AS name,
+ nsp.nspname
+FROM
+ pg_class c
+LEFT JOIN pg_namespace nsp ON c.relnamespace = nsp.oid
+WHERE
+ c.relfilenode = {{ vid }};
+{% elif (name and nspname) %}
+DROP VIEW {{ conn|qtIdent(nspname, name) }} {% if cascade %} CASCADE {% endif
%};
+{% endif %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/get_oid.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/get_oid.sql
new file mode 100644
index 00000000..453c2444
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/get_oid.sql
@@ -0,0 +1,9 @@
+{# ===== fetch new assigned schema id ===== #}
+{% if vid %}
+SELECT
+ c.relnamespace as scid
+FROM
+ pg_class c
+WHERE
+ c.oid = {{vid}}::oid;
+{% endif %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/get_schema.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/get_schema.sql
new file mode 100644
index 00000000..3bdb5dcb
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/get_schema.sql
@@ -0,0 +1,7 @@
+{# ===== fetch schema name against schema oid ===== #}
+SELECT
+ nspname
+FROM
+ pg_namespace
+WHERE
+ oid = {{ scid }}::oid;
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/grant.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/grant.sql
new file mode 100644
index 00000000..a7e1585b
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/grant.sql
@@ -0,0 +1,6 @@
+{# ===== Grant Permissions to User Role on Views/Tables ===== #}
+{% import 'macros/schemas/security.macros' as SECLABEL %}
+{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
+{# ===== We will generate Security Label SQL using macro ===== #}
+{% if data.seclabels %}{% for r in data.seclabels %}{{ SECLABEL.SET(conn,
'VIEW', data.name, r.provider, r.label, data.schema) }}{{'\r'}}{% endfor
%}{{'\r'}}{% endif %}{% if data.datacl %}
+{% for priv in data.datacl %}{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee,
data.name, priv.without_grant, priv.with_grant, data.schema) }}{% endfor %}{%
endif %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/nodes.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/nodes.sql
new file mode 100644
index 00000000..be133967
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/nodes.sql
@@ -0,0 +1,13 @@
+SELECT
+ c.oid,
+ c.relname AS name
+FROM pg_class c
+WHERE
+ c.relkind = 'v'
+{% if (vid and datlastsysoid) %}
+ AND c.oid = {{vid}}::oid
+{% elif scid %}
+ AND c.relnamespace = {{scid}}::oid
+ORDER BY
+ c.relname
+{% endif %}
\ No newline at end of file
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/properties.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/properties.sql
new file mode 100644
index 00000000..e911287d
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/properties.sql
@@ -0,0 +1,57 @@
+{% if (vid and datlastsysoid) or scid %}
+SELECT
+ c.oid,
+ c.xmin,
+ (CASE WHEN length(spc.spcname) > 0 THEN spc.spcname ELSE 'pg_default' END)
as spcname,
+ c.relname AS name,
+ nsp.nspname AS schema,
+ description AS comment,
+ c.reltablespace AS spcoid,
+ pg_get_userbyid(c.relowner) AS owner,
+ pg_get_viewdef(c.oid, true) AS definition,
+ array_to_string(c.relacl::text[], ', ') AS acl,
+ {#=============Checks if it is system view================#}
+ {% if vid and datlastsysoid %}
+ CASE WHEN {{vid}} <= {{datlastsysoid}} THEN True ELSE False END AS
system_view,
+ {% endif %}
+ ARRAY[]::text[] AS seclabels
+FROM pg_class c
+ LEFT OUTER JOIN pg_namespace nsp on nsp.oid = c.relnamespace
+ LEFT OUTER JOIN pg_tablespace spc on spc.oid=c.reltablespace
+ LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0
AND des.classoid='pg_class'::regclass)
+WHERE ((c.relhasrules
+ AND
+ (EXISTS(
+ SELECT
+ r.rulename
+ FROM
+ pg_rewrite r
+ WHERE
+ ((r.ev_class = c.oid) AND (bpchar(r.ev_type) =
'1'::bpchar))
+ ))
+ ) AND (c.relkind = 'v'::char))
+{% if (vid and datlastsysoid) %}
+ AND c.oid = {{vid}}::oid
+{% elif scid %}
+ AND c.relnamespace = {{scid}}::oid ORDER BY c.relname
+{% endif %}
+
+{% elif type == 'roles' %}
+SELECT
+ pr.rolname
+FROM
+ pg_roles pr
+WHERE
+ pr.rolcanlogin
+ORDER BY
+ pr.rolname
+
+{% elif type == 'schemas' %}
+SELECT
+ nsp.nspname
+FROM
+ pg_namespace nsp
+WHERE
+ (nsp.nspname NOT LIKE E'pg\\_%'
+ AND nsp.nspname != 'information_schema')
+{% endif %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/update.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/update.sql
new file mode 100644
index 00000000..291b7760
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/update.sql
@@ -0,0 +1,67 @@
+{# ============================ Update View ========================= #}
+{% import 'macros/schemas/security.macros' as SECLABEL %}
+{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
+{% if data %}
+{% set view_name = data.name if data.name else o_data.name %}
+{% set view_schema = data.schema if data.schema else o_data.schema %}
+{% set def = data.definition.rstrip(';') if data.definition %}
+{% if data.name and data.name != o_data.name %}
+ALTER VIEW {{ conn|qtIdent(o_data.schema, o_data.name) }}
+ RENAME TO {{ conn|qtIdent(data.name) }};
+{% endif %}
+{% if data.schema and data.schema != o_data.schema %}
+ALTER VIEW {{ conn|qtIdent(o_data.schema, view_name ) }}
+ SET SCHEMA {{ conn|qtIdent(data.schema) }};
+{% endif %}
+{% if data.owner and data.owner != o_data.owner %}
+ALTER TABLE {{ conn|qtIdent(view_schema, view_name) }}
+ OWNER TO {{ conn|qtIdent(data.owner) }};
+{% endif %}
+{% if def and def != o_data.definition.rstrip(';') %}
+CREATE OR REPLACE VIEW {{ conn|qtIdent(view_schema, view_name) }}
+ AS{{ def }};
+{% endif %}
+{% set old_comment = o_data.comment|default('', true) %}
+{% if (data.comment is defined and (data.comment != old_comment)) %}
+COMMENT ON VIEW {{ conn|qtIdent(view_schema, view_name) }}
+ IS {{ data.comment|qtLiteral }};
+{% endif %}
+{# The SQL generated below will change privileges #}
+{% if data.datacl %}
+{% if 'deleted' in data.datacl %}
+{% for priv in data.datacl.deleted %}
+{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in data.datacl %}
+{% for priv in data.datacl.changed %}
+{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, data.name, data.schema) }}
+{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant,
priv.with_grant, data.schema) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in data.datacl %}
+{% for priv in data.datacl.added %}
+{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant,
priv.with_grant, data.schema) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+{# The SQL generated below will change Security Label #}
+{% if data.seclabels is not none and data.seclabels|length > 0 %}
+{% set seclabels = data.seclabels %}
+{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
+{% for r in seclabels.deleted %}
+{{ SECLABEL.UNSET(conn, 'VIEW', data.name, r.provider, data.schema) }}
+{% endfor %}
+{% endif %}
+{% if 'added' in seclabels and seclabels.added|length > 0 %}
+{% for r in seclabels.added %}
+{{ SECLABEL.SET(conn, 'VIEW', data.name, r.provider, r.label, data.schema) }}
+{% endfor %}
+{% endif %}
+{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
+{% for r in seclabels.changed %}
+{{ SECLABEL.SET(conn, 'VIEW', data.name, r.provider, r.label, data.schema) }}
+{% endfor %}
+{% endif %}
+{% endif %}
+{% endif %}
diff --git
a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/view_id.sql
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/view_id.sql
new file mode 100644
index 00000000..73f6da55
--- /dev/null
+++
b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/view/gpdb_5.0_plus/sql/view_id.sql
@@ -0,0 +1,4 @@
+{# ===== Below will provide view id for last created view ===== #}
+{% if data %}
+SELECT c.oid, c.relname FROM pg_class c WHERE c.relname = '{{ data.name }}';
+{% endif %}
diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py
b/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py
index 5ce8eb18..47c60b1c 100644
--- a/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py
+++ b/web/pgadmin/browser/server_groups/servers/pgagent/__init__.py
@@ -50,6 +50,9 @@ class JobModule(CollectionNodeModule):
conn = manager.connection()
+ if manager.server_type == 'gpdb':
+ return False
+
status, res = conn.execute_scalar("""
SELECT
has_table_privilege('pgagent.pga_job', 'INSERT, SELECT, UPDATE')
has_priviledge
diff --git a/web/pgadmin/browser/server_groups/servers/static/img/gpdb.png
b/web/pgadmin/browser/server_groups/servers/static/img/gpdb.png
new file mode 100644
index
0000000000000000000000000000000000000000..134393c4582c4ef5615138ff740884098800df83
GIT binary patch
literal 1244
zcmeAS@N?(olHy`uVBq!ia0vp^0zfRt!3HF+tk*dLq*&4&eH|GXHuiJ>Nn{1`6_P!I
zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC!N4G1FlSew4N!u!z$3DlfkEmO2s3J%
zTmXtOp3V%3D2ed(u}aR*)k{ptPfFFR$SnZMFfiCuSOJ;2sU?XD6}dTi#a0!zN?;XM
zKsHENUr7P1q$Jx`DZ)2E!8yMuRl!uxM9)CUj!Qv7!KNrB%__*n4XPc;vsKC{DJihh
z*Do(G*DE*H%P&gTH?*|0)Hg8FH!{)%s?aU2%qvN((9J7Wh8O}f$0fBmxhS)sBr`ux
z0c37sQhsTPt&$SRA~=A!vm`SOVN+f))LTFg>VstT4fPE4v1tQ(7VbV2T@{H15KUlT
zK`gTY8D-^Pl$i>2F33@KhBjd1QN$3AvjLiJ<y@4SSdw29lAoVr2MU4AyzJuS#DY{%
zIN0c;tAJ{@(Fb`K$@`G71&aa$*NzLQ6Bbc+Tr5{!oMvEPs`hko46zVg8tm&45-9TT
zUG1|AMPYw)+_)|>$u6JzSMckV7x`k2!pWvAj)Ge>iZ8lV``ULasdgSIn96$5DJM|y
z>>ft(ORH3xE;JSi+)8y^YWDNqTkHHH3HGSc2WKt6&v|cc|NRc*zu*v4`?pG5^2--)
zU}qCNR$FJxc0z*x@VU4>>z_;!{^FbPwSWE#<-ik`liVfeh#8!mz4F`V&6)f&ElVsp
zMO4L9I8Ja^I6iSpEpW<w5@~j_cnU+Rh}zow6)9m0@0m-e<zJhB*v@m2>gn&5Uxe?t
zT+&<CBQ)jtPci4?ksoK=h~u@pbpKKG4Y&VRvd3~CYN<D;rOixPYH?8d#ct)sdQL<2
zn@_F9s(5>KXFV}yssB*3XW_m`#~KfZ)n+$5??>Fs54eB3Z@Z1XG28O2j2m8wF3~Si
zRx2`YI^^MR9hB4^Q{BlF-GBMaEY~{%^46879^L&DkX~~}Oa82oz(du0x{(J$#d%fw
zH$OFuyW{v=;F)Tgq|e6Y4i$k&ot0DfUpJ08eD}G>ybq>*dh7KZGWkx}%sS{F6Wo1q
z&y4+t`p#MNZAt&ou;Jw~eGkjs8@I@azh&eNF`jjJ#~lZEkH?0x+(IdbmfUM(I%#;{
zIbBKd$J9gBUBc6^-uWxwym3)`*eh?*4PRN7&f%+B_klI-muQj+-wf3|{Be(_>bw)I
znIW3HuV!}g+|=~uy}1%A)T}Mnq+XTLH>lpp`#hzW<Nu-7{H+-(H=lY<wly;g6@EJB
zT!MCc<sqivhe~=~`Y#-M8lQ92@-Cb|_rzhT<#MSe=htO<b`{)H{*wRvAA4_WUR>6O
zokdKZN{4>VTH#gy{L<xVxAhGgwT;97&;8Hvd;MMYIx`nVP#NOs>gTe~DWM4f?7-Te
literal 0
HcmV?d00001
diff --git a/web/pgadmin/browser/tests/test_version_in_range.py
b/web/pgadmin/browser/tests/test_version_in_range.py
new file mode 100644
index 00000000..e090207b
--- /dev/null
+++ b/web/pgadmin/browser/tests/test_version_in_range.py
@@ -0,0 +1,68 @@
+##########################################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2017, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##########################################################################
+
+import json
+import uuid
+
+from pgadmin.utils.route import BaseTestGenerator
+from regression.python_test_utils import test_utils
+from regression.test_setup import config_data
+from pgadmin.browser.utils import is_version_in_range
+
+
+class VersionInRangeTestCase(BaseTestGenerator):
+ """
+ This class validates the version in range functionality
+ by defining different version scenarios; where dict of
+ parameters describes the scenario appended by test name.
+ """
+
+ scenarios = [
+ ('TestCase for Validating pgversion 8.23 and min_version is 91000,
should not show', dict(
+ sversion=82300,
+ min_version=90100,
+ max_version=1000000000,
+ scenario=2
+ )),
+ ('TestCase for Validating pgversion 9.2 and should show by default',
dict(
+ sversion=90200,
+ min_version=0,
+ max_version=1000000000,
+ scenario=1
+ )),
+ ('TestCase for Validating pgversion 9.2 and min/max are None, should
show by default', dict(
+ sversion=90200,
+ min_version=None,
+ max_version=None,
+ scenario=1
+ )),
+ ('TestCase for Validating pgversion 9.6 and max is lower, should not
show', dict(
+ sversion=90600,
+ min_version=None,
+ max_version=90400,
+ scenario=2
+ ))
+ ]
+
+ @classmethod
+ def setUpClass(cls):
+ pass
+
+ def runTest(self):
+ """This function will check version in range functionality."""
+ if self.scenario == 1:
+ self.test_result_is_true()
+ if self.scenario == 2:
+ self.test_result_is_false()
+
+ def test_result_is_true(self):
+ self.assertTrue(is_version_in_range(self.sversion, self.min_version,
self.max_version))
+
+ def test_result_is_false(self):
+ self.assertFalse(is_version_in_range(self.sversion, self.min_version,
self.max_version))
diff --git a/web/pgadmin/browser/utils.py b/web/pgadmin/browser/utils.py
index acc16621..5ecbe7ce 100644
--- a/web/pgadmin/browser/utils.py
+++ b/web/pgadmin/browser/utils.py
@@ -19,6 +19,17 @@ from pgadmin.utils.ajax import make_json_response,
precondition_required
from config import PG_DEFAULT_DRIVER
+def is_version_in_range(sversion, min_ver, max_ver):
+ assert (max_ver is None or isinstance(max_ver, int))
+ assert (min_ver is None or isinstance(min_ver, int))
+
+ if min_ver is None and max_ver is None:
+ return True
+
+ if min_ver is None or min_ver <= sversion:
+ if max_ver is None or max_ver >= sversion:
+ return True
+ return False
class PGChildModule(object):
"""
@@ -40,6 +51,8 @@ class PGChildModule(object):
self.min_ver = 0
self.max_ver = 1000000000
self.server_type = None
+ self.min_gpdbver = 80323
+ self.max_gpdbver = 1000000000
super(PGChildModule, self).__init__()
@@ -48,20 +61,15 @@ class PGChildModule(object):
if not self.show_node:
return False
sversion = getattr(manager, 'sversion', None)
+
if (sversion is None or not isinstance(sversion, int)):
return False
- if (self.min_ver is None and self.max_ver is None):
- return True
-
- assert (self.max_ver is None or isinstance(self.max_ver, int))
- assert (self.min_ver is None or isinstance(self.min_ver, int))
assert (self.server_type is None or isinstance(self.server_type, list))
if self.server_type is None or manager.server_type in self.server_type:
- if self.min_ver is None or self.min_ver <= sversion:
- if self.max_ver is None or self.max_ver >= sversion:
- return True
+ return is_version_in_range(sversion, self.min_gpdbver if
manager.server_type == 'gpdb' else self.min_ver,
+ self.max_gpdbver if manager.server_type
== 'gpdb' else self.max_ver)
return False