mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Greenplum specific DDL and Dashboard display changes.
Initial patch by Sarah McAlear<smcalear@pivotal.io>.
This commit is contained in:
parent
d3babd78aa
commit
46c5df4e7b
@ -321,7 +321,8 @@ STORAGE_DIR = os.path.join(DATA_DIR, 'storage')
|
||||
##########################################################################
|
||||
DEFAULT_BINARY_PATHS = {
|
||||
"pg": "",
|
||||
"ppas": ""
|
||||
"ppas": "",
|
||||
"gpdb": ""
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
|
@ -0,0 +1,168 @@
|
||||
{% import 'macros/schemas/security.macros' as SECLABEL %}
|
||||
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'macros/variable.macros' as VARIABLE %}
|
||||
{% import 'column/macros/security.macros' as COLUMN_SECLABEL %}
|
||||
{% import 'column/macros/privilege.macros' as COLUMN_PRIVILEGE %}
|
||||
{% import 'table/sql/macros/constraints.macro' as CONSTRAINTS %}
|
||||
{% import 'type/macros/get_full_type_sql_format.macros' as GET_TYPE %}
|
||||
{#===========================================#}
|
||||
{#====== MAIN TABLE TEMPLATE STARTS HERE ======#}
|
||||
{#===========================================#}
|
||||
{#
|
||||
If user has not provided any details but only name then
|
||||
add empty bracket with table name
|
||||
#}
|
||||
{% set empty_bracket = ""%}
|
||||
{% if data.coll_inherits|length == 0 and data.columns|length == 0 and not data.typname and not data.like_relation and data.primary_key|length == 0 and data.unique_constraint|length == 0 and data.foreign_key|length == 0 and data.check_constraint|length == 0 and data.exclude_constraint|length == 0 %}
|
||||
{% set empty_bracket = "\n(\n)"%}
|
||||
{% endif %}
|
||||
CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}}
|
||||
{% if data.typname %}
|
||||
OF {{ data.typname }}
|
||||
{% endif %}
|
||||
{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %}
|
||||
(
|
||||
{% endif %}
|
||||
{% if data.like_relation %}
|
||||
LIKE {{ data.like_relation }}{% if data.like_default_value %}
|
||||
|
||||
INCLUDING DEFAULTS{% endif %}{% if data.like_constraints %}
|
||||
|
||||
INCLUDING CONSTRAINTS{% endif %}{% if data.like_indexes %}
|
||||
|
||||
INCLUDING INDEXES{% endif %}{% if data.like_storage %}
|
||||
|
||||
INCLUDING STORAGE{% endif %}{% if data.like_comments %}
|
||||
|
||||
INCLUDING COMMENTS{% endif %}{% if data.columns|length > 0 %},
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{### Add columns ###}
|
||||
{% if data.columns and data.columns|length > 0 %}
|
||||
{% for c in data.columns %}
|
||||
{% if c.name and c.cltype %}
|
||||
{% if loop.index != 1 %},
|
||||
{% endif %}
|
||||
{{conn|qtIdent(c.name)}} {% if is_sql %}{{c.displaytypname}}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, c.cltype, c.attlen, c.attprecision, c.hasSqrBracket) }}{% endif %}{% if c.collspcname %} COLLATE {{c.collspcname}}{% endif %}{% if c.attnotnull %} NOT NULL{% endif %}{% if c.defval %} DEFAULT {{c.defval}}{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{# Macro to render for constraints #}
|
||||
{% if data.primary_key|length > 0 %}{% if data.columns|length > 0 %},{% endif %}
|
||||
{{CONSTRAINTS.PRIMARY_KEY(conn, data.primary_key[0])}}{% endif %}{% if data.unique_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 %},{% endif %}
|
||||
{{CONSTRAINTS.UNIQUE(conn, data.unique_constraint)}}{% endif %}{% if data.foreign_key|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 %},{% endif %}
|
||||
{{CONSTRAINTS.FOREIGN_KEY(conn, data.foreign_key)}}{% endif %}{% if data.check_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 %},{% endif %}
|
||||
{{CONSTRAINTS.CHECK(conn, data.check_constraint)}}{% endif %}{% if data.exclude_constraint|length > 0 %}{% if data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 %},{% endif %}
|
||||
{{CONSTRAINTS.EXCLUDE(conn, data.exclude_constraint)}}{% endif %}
|
||||
{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %}
|
||||
|
||||
){% endif %}{% if data.relkind is defined and data.relkind == 'p' %} PARTITION BY {{ data.partition_scheme }} {% endif %}
|
||||
|
||||
{### If we are inheriting it from another table(s) ###}
|
||||
{% if data.coll_inherits %}
|
||||
INHERITS ({% for val in data.coll_inherits %}{% if loop.index != 1 %}, {% endif %}{{val}}{% endfor %})
|
||||
{% endif %}
|
||||
WITH (
|
||||
OIDS = {% if data.relhasoids %}TRUE{% else %}FALSE{% endif %}{% if data.fillfactor %},
|
||||
FILLFACTOR = {{ data.fillfactor }}{% endif %}{% if data.appendonly %},
|
||||
APPENDONLY = TRUE{% endif %}{% if data.compresslevel %},
|
||||
COMPRESSLEVEL = {{ data.compresslevel }}{% endif %}{% if data.blocksize %},
|
||||
BLOCKSIZE = {{ data.blocksize }}{% endif %}{% if data.orientation %},
|
||||
ORIENTATION = {{ data.orientation.upper() }}{% endif %}{% if data.compresstype %},
|
||||
COMPRESSTYPE = {{ data.compresstype.upper() }}{% endif %}{% if data.autovacuum_custom %},
|
||||
autovacuum_enabled = {% if data.autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}{% endif %}{% if data.toast_autovacuum %},
|
||||
toast.autovacuum_enabled = {% if data.toast_autovacuum_enabled %}TRUE{% else %}FALSE{% endif %}
|
||||
{% endif %}{% if data.autovacuum_enabled and data.vacuum_table|length > 0 %}
|
||||
|
||||
{% for opt in data.vacuum_table %}{% if opt.name and opt.value %}
|
||||
,
|
||||
{{opt.name}} = {{opt.value}}{% endif %}
|
||||
{% endfor %}{% endif %}{% if data.toast_autovacuum_enabled and data.vacuum_toast|length > 0 %}
|
||||
{% for opt in data.vacuum_toast %}{% if opt.name and opt.value %}
|
||||
,
|
||||
toast.{{opt.name}} = {{opt.value}}{% endif %}
|
||||
{% endfor %}{% endif %}
|
||||
|
||||
)
|
||||
{### SQL for Tablespace ###}
|
||||
{% if data.spcname %}
|
||||
TABLESPACE {{ conn|qtIdent(data.spcname) }}
|
||||
{% endif %}
|
||||
{### SQL for Distribution ###}
|
||||
{% if data.distribution %}
|
||||
DISTRIBUTED BY ({% for attrnum in data.distribution %}{% if loop.index != 1 %}, {% endif %}{{ data.columns[attrnum-1].name }}{% endfor %});
|
||||
{% else %}
|
||||
DISTRIBUTED RANDOMLY;
|
||||
{% endif %}
|
||||
|
||||
{### Alter SQL for Owner ###}
|
||||
{% if data.relowner %}
|
||||
|
||||
ALTER TABLE {{conn|qtIdent(data.schema, data.name)}}
|
||||
OWNER to {{conn|qtIdent(data.relowner)}};
|
||||
{% endif %}
|
||||
{### Security Labels on Table ###}
|
||||
{% if data.seclabels and data.seclabels|length > 0 %}
|
||||
|
||||
{% for r in data.seclabels %}
|
||||
{{ SECLABEL.SET(conn, 'TABLE', data.name, r.provider, r.label, data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{### ACL on Table ###}
|
||||
{% if data.relacl %}
|
||||
{% for priv in data.relacl %}
|
||||
{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{### SQL for COMMENT ###}
|
||||
{% if data.description %}
|
||||
COMMENT ON TABLE {{conn|qtIdent(data.schema, data.name)}}
|
||||
IS {{data.description|qtLiteral}};
|
||||
{% endif %}
|
||||
{#===========================================#}
|
||||
{#====== MAIN TABLE TEMPLATE ENDS HERE ======#}
|
||||
{#===========================================#}
|
||||
{#===========================================#}
|
||||
{# COLUMN SPECIFIC TEMPLATES STARTS HERE #}
|
||||
{#===========================================#}
|
||||
{% if data.columns and data.columns|length > 0 %}
|
||||
{% for c in data.columns %}
|
||||
{% if c.description %}
|
||||
|
||||
COMMENT ON COLUMN {{conn|qtIdent(data.schema, data.name, c.name)}}
|
||||
IS {{c.description|qtLiteral}};
|
||||
{% endif %}
|
||||
{### Add variables to column ###}
|
||||
{% if c.attoptions and c.attoptions|length > 0 %}
|
||||
|
||||
ALTER TABLE {{conn|qtIdent(data.schema, data.name)}}
|
||||
{{ VARIABLE.SET(conn, 'COLUMN', c.name, c.attoptions) }}
|
||||
{% endif %}
|
||||
{### ACL ###}
|
||||
{% if c.attacl and c.attacl|length > 0 %}
|
||||
|
||||
{% for priv in c.attacl %}
|
||||
{{ COLUMN_PRIVILEGE.APPLY(conn, data.schema, data.name, c.name, priv.grantee, priv.without_grant, priv.with_grant) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{### Security Lables ###}
|
||||
{% if c.seclabels and c.seclabels|length > 0 %}
|
||||
|
||||
{% for r in c.seclabels %}
|
||||
{{ COLUMN_SECLABEL.APPLY(conn, 'COLUMN',data.schema, data.name, c.name, r.provider, r.label) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{#===========================================#}
|
||||
{# COLUMN SPECIFIC TEMPLATES ENDS HERE #}
|
||||
{#===========================================#}
|
||||
{#======================================#}
|
||||
{# CONSTRAINTS SPECIFIC TEMPLATES #}
|
||||
{#======================================#}
|
||||
{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.primary_key)}}
|
||||
{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.unique_constraint)}}
|
||||
{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.foreign_key)}}
|
||||
{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.check_constraint)}}
|
||||
{{CONSTRAINTS.CONSTRAINT_COMMENTS(conn, data.schema, data.name, data.exclude_constraint)}}
|
@ -0,0 +1,82 @@
|
||||
SELECT *,
|
||||
(CASE when pre_coll_inherits is NULL then ARRAY[]::varchar[] else pre_coll_inherits END) as coll_inherits
|
||||
FROM (
|
||||
SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS relacl_str,
|
||||
(CASE WHEN length(spc.spcname) > 0 THEN spc.spcname ELSE
|
||||
(SELECT sp.spcname FROM pg_database dtb
|
||||
JOIN pg_tablespace sp ON dtb.dattablespace=sp.oid
|
||||
WHERE dtb.oid = {{ did }}::oid)
|
||||
END) as spcname,
|
||||
(select nspname FROM pg_namespace WHERE oid = {{scid}}::oid ) as schema,
|
||||
pg_get_userbyid(rel.relowner) AS relowner, rel.relhasoids,
|
||||
rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,
|
||||
EXISTS(select 1 FROM pg_trigger
|
||||
JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'
|
||||
JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'
|
||||
WHERE tgrelid=rel.oid) AS isrepl,
|
||||
(SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid) AS triggercount,
|
||||
(SELECT ARRAY(SELECT CASE WHEN (nspname NOT LIKE E'pg\_%') THEN
|
||||
quote_ident(nspname)||'.'||quote_ident(c.relname)
|
||||
ELSE quote_ident(c.relname) END AS inherited_tables
|
||||
FROM pg_inherits i
|
||||
JOIN pg_class c ON c.oid = i.inhparent
|
||||
JOIN pg_namespace n ON n.oid=c.relnamespace
|
||||
WHERE i.inhrelid = rel.oid ORDER BY inhseqno)) AS pre_coll_inherits,
|
||||
(SELECT count(*)
|
||||
FROM pg_inherits i
|
||||
JOIN pg_class c ON c.oid = i.inhparent
|
||||
JOIN pg_namespace n ON n.oid=c.relnamespace
|
||||
WHERE i.inhrelid = rel.oid) AS inherited_tables_cnt,
|
||||
false AS relpersistence,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'compresslevel=([0-9]*)') AS compresslevel,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'blocksize=([0-9]*)') AS blocksize,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'orientation=(row|column)') AS orientation,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'appendonly=(true|false)')::boolean AS appendonly,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'compresstype=(zlib|quicklz|rle_type|none)') AS compresstype,
|
||||
(CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true')
|
||||
THEN true ELSE false END) AS autovacuum_enabled,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_vacuum_scale_factor,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_analyze_scale_factor,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age,
|
||||
substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age,
|
||||
(CASE WHEN (substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') = 'true')
|
||||
THEN true ELSE false END) AS toast_autovacuum_enabled,
|
||||
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold,
|
||||
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_vacuum_scale_factor,
|
||||
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold,
|
||||
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_analyze_scale_factor,
|
||||
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay,
|
||||
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit,
|
||||
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age,
|
||||
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age,
|
||||
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age,
|
||||
array_to_string(rel.reloptions, ',') AS table_vacuum_settings_str,
|
||||
array_to_string(tst.reloptions, ',') AS toast_table_vacuum_settings_str,
|
||||
rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, NULL AS reloftype, NULL AS typname,
|
||||
(CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable,
|
||||
-- Added for pgAdmin4
|
||||
(CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)'))::boolean THEN true ELSE false END) AS autovacuum_custom,
|
||||
(CASE WHEN (substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)'))::boolean AND rel.reltoastrelid != 0 THEN true ELSE false END) AS toast_autovacuum,
|
||||
|
||||
ARRAY[]::varchar[] AS seclabels,
|
||||
(CASE WHEN rel.oid <= {{ datlastsysoid}}::oid THEN true ElSE false END) AS is_sys_table,
|
||||
|
||||
gdp.attrnums AS distribution
|
||||
|
||||
FROM pg_class rel
|
||||
LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace
|
||||
LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)
|
||||
LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'
|
||||
LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid
|
||||
LEFT OUTER JOIN gp_distribution_policy gdp ON gdp.localoid = rel.oid
|
||||
|
||||
WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ scid }}
|
||||
{% if tid %} AND rel.oid = {{ tid }}::oid {% endif %}
|
||||
) AS TableInformation
|
||||
ORDER BY name
|
@ -104,8 +104,13 @@ class BaseTableView(PGChildNodeView):
|
||||
did in self.manager.db_info else 0
|
||||
|
||||
ver = self.manager.version
|
||||
server_type = self.manager.server_type
|
||||
# Set the template path for the SQL scripts
|
||||
self.table_template_path = 'table/sql/#{0}#'.format(ver)
|
||||
self.table_template_path = 'table/sql/' + (
|
||||
'#{0}#{1}#'.format(server_type, ver)
|
||||
if server_type == 'gpdb' else
|
||||
'#{0}#'.format(ver)
|
||||
)
|
||||
self.partition_template_path = 'partition/sql/#{0}#'.format(ver)
|
||||
|
||||
# Template for Column ,check constraint and exclusion
|
||||
|
20
web/pgadmin/browser/server_groups/servers/gpdb.py
Normal file
20
web/pgadmin/browser/server_groups/servers/gpdb.py
Normal file
@ -0,0 +1,20 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
from flask_babel import gettext
|
||||
from pgadmin.browser.server_groups.servers.types import ServerType
|
||||
|
||||
|
||||
class GPDB(ServerType):
|
||||
def instanceOf(self, ver):
|
||||
return "Greenplum Database" in ver
|
||||
|
||||
|
||||
# Default Server Type
|
||||
GPDB('gpdb', gettext("Greenplum Database"), 3)
|
@ -218,7 +218,12 @@ def check_precondition(f):
|
||||
g.server_type = g.manager.server_type
|
||||
g.version = g.manager.version
|
||||
|
||||
g.template_path = 'dashboard/sql/#{0}#'.format(g.version)
|
||||
# Include server_type in template_path when server_type is gpdb
|
||||
g.template_path = 'dashboard/sql/' + (
|
||||
'#{0}#{1}#'.format(g.server_type, g.version)
|
||||
if g.server_type == 'gpdb' else
|
||||
'#{0}#'.format(g.version)
|
||||
)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
SELECT
|
||||
procpid AS pid,
|
||||
datname,
|
||||
usename,
|
||||
application_name,
|
||||
client_addr,
|
||||
to_char(backend_start, 'YYYY-MM-DD HH24:MI:SS TZ') AS backend_start,
|
||||
CASE WHEN current_query LIKE '<IDLE>%' THEN 'idle' ELSE 'active' END AS state,
|
||||
CASE WHEN waiting THEN '{{ _('yes') }}' ELSE '{{ _('no') }}' END AS waiting
|
||||
FROM
|
||||
pg_stat_activity
|
||||
{% if did %}WHERE
|
||||
datid = {{ did }} {% endif %}
|
||||
ORDER BY pid
|
@ -0,0 +1,22 @@
|
||||
SELECT
|
||||
pid,
|
||||
locktype,
|
||||
datname,
|
||||
relation::regclass,
|
||||
page,
|
||||
tuple,
|
||||
virtualxid
|
||||
transactionid,
|
||||
classid::regclass,
|
||||
objid,
|
||||
objsubid,
|
||||
virtualtransaction,
|
||||
mode,
|
||||
granted
|
||||
FROM
|
||||
pg_locks l
|
||||
LEFT OUTER JOIN pg_database d ON (l.database = d.oid)
|
||||
{% if did %}WHERE
|
||||
database = {{ did }}{% endif %}
|
||||
ORDER BY
|
||||
pid, locktype
|
@ -0,0 +1,4 @@
|
||||
SELECT
|
||||
(SELECT count(*) FROM pg_stat_activity{% if did %} WHERE datid = {{ did }} {% endif %}) AS "{{ _('Total') }}",
|
||||
(SELECT count(*) FROM pg_stat_activity WHERE current_query NOT LIKE '<IDLE>%'{% if did %} AND datid = {{ did }} {% endif %}) AS "{{ _('Active') }}",
|
||||
(SELECT count(*) FROM pg_stat_activity WHERE current_query LIKE '<IDLE>%'{% if did %} AND datid = {{ did }} {% endif %}) AS "{{ _('Idle') }}"
|
@ -0,0 +1 @@
|
||||
Some default SQL for GPDB
|
@ -23,7 +23,10 @@ class TestVersionedTemplateLoader(BaseTestGenerator):
|
||||
("Render a version 9.1 template when it is present", dict(scenario=2)),
|
||||
("Render a version 9.2 template when request for a higher version", dict(scenario=3)),
|
||||
("Render default version when version 9.0 was requested and only 9.1 and 9.2 are present", dict(scenario=4)),
|
||||
("Raise error when version is smaller than available templates", dict(scenario=5))
|
||||
("Raise error when version is smaller than available templates", dict(scenario=5)),
|
||||
("Render a version GPDB 5.0 template when it is present", dict(scenario=6)),
|
||||
("Render a version GPDB 5.0 template when it is in default", dict(scenario=7)),
|
||||
("Raise error when version is gpdb but template does not exist", dict(scenario=8))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
@ -40,6 +43,12 @@ class TestVersionedTemplateLoader(BaseTestGenerator):
|
||||
self.test_get_source_when_version_is_9_0_and_there_are_templates_for_9_1_and_9_2_returns_default_template()
|
||||
if self.scenario == 5:
|
||||
self.test_raise_not_found_exception_when_postgres_version_less_than_all_available_sql_templates()
|
||||
if self.scenario == 6:
|
||||
self.test_get_source_when_the_version_is_gpdb_5_0_returns_gpdb_5_0_template()
|
||||
if self.scenario == 7:
|
||||
self.test_get_source_when_the_version_is_gpdb_5_0_returns_default_template()
|
||||
if self.scenario == 8:
|
||||
self.test_raise_not_found_exception_when_the_version_is_gpdb_template_not_exist()
|
||||
|
||||
def test_get_source_returns_a_template(self):
|
||||
expected_content = "Some SQL" \
|
||||
@ -86,6 +95,31 @@ class TestVersionedTemplateLoader(BaseTestGenerator):
|
||||
except TemplateNotFound:
|
||||
return
|
||||
|
||||
def test_get_source_when_the_version_is_gpdb_5_0_returns_gpdb_5_0_template(self):
|
||||
expected_content = "Some default SQL for GPDB\n"
|
||||
# For cross platform we join the SQL path (This solves the slashes issue)
|
||||
sql_path = os.path.join("some_feature", "sql", "gpdb_5.0_plus", "some_action_with_gpdb_5_0.sql")
|
||||
content, filename, up_to_dateness = self.loader.get_source(None, "some_feature/sql/#gpdb#80323#/some_action_with_gpdb_5_0.sql")
|
||||
|
||||
self.assertEqual(expected_content, str(content).replace("\r", ""))
|
||||
self.assertIn(sql_path, filename)
|
||||
|
||||
def test_get_source_when_the_version_is_gpdb_5_0_returns_default_template(self):
|
||||
expected_content = "Some default SQL"
|
||||
# For cross platform we join the SQL path (This solves the slashes issue)
|
||||
sql_path = os.path.join("some_feature", "sql", "default", "some_action_with_default.sql")
|
||||
content, filename, up_to_dateness = self.loader.get_source(None, "some_feature/sql/#gpdb#80323#/some_action_with_default.sql")
|
||||
|
||||
self.assertEqual(expected_content, str(content).replace("\r", ""))
|
||||
self.assertIn(sql_path, filename)
|
||||
|
||||
def test_raise_not_found_exception_when_the_version_is_gpdb_template_not_exist(self):
|
||||
try:
|
||||
self.loader.get_source(None, "some_feature/sql/#gpdb#50100#/some_action.sql")
|
||||
self.fail("No exception raised")
|
||||
except TemplateNotFound:
|
||||
return
|
||||
|
||||
|
||||
class FakeApp(Flask):
|
||||
def __init__(self):
|
||||
|
@ -13,9 +13,9 @@ from jinja2 import TemplateNotFound
|
||||
|
||||
class VersionedTemplateLoader(DispatchingJinjaLoader):
|
||||
def get_source(self, environment, template):
|
||||
template_path_parts = template.split("#", 2)
|
||||
template_path_parts = template.split("#", 3)
|
||||
|
||||
server_versions = (
|
||||
postgres_versions = (
|
||||
{'name': "10_plus", 'number': 100000},
|
||||
{'name': "9.6_plus", 'number': 90600},
|
||||
{'name': "9.5_plus", 'number': 90500},
|
||||
@ -27,18 +27,29 @@ class VersionedTemplateLoader(DispatchingJinjaLoader):
|
||||
{'name': "default", 'number': 0}
|
||||
)
|
||||
|
||||
gpdb_versions = (
|
||||
{'name': "gpdb_5.0_plus", 'number': 80323},
|
||||
{'name': "default", 'number': 0}
|
||||
)
|
||||
|
||||
server_versions = postgres_versions
|
||||
if len(template_path_parts) == 1:
|
||||
return super(VersionedTemplateLoader, self).get_source(environment, template)
|
||||
|
||||
if len(template_path_parts) == 4:
|
||||
path_start, server_type, specified_version_number, file_name = template_path_parts
|
||||
if server_type == 'gpdb':
|
||||
server_versions = gpdb_versions
|
||||
else:
|
||||
for server_version in server_versions:
|
||||
path_start, specified_version_number, file_name = template_path_parts
|
||||
path_start, specified_version_number, file_name = template_path_parts
|
||||
|
||||
if server_version['number'] > int(specified_version_number):
|
||||
continue
|
||||
for server_version in server_versions:
|
||||
if server_version['number'] > int(specified_version_number):
|
||||
continue
|
||||
|
||||
template_path = path_start + '/' + server_version['name'] + '/' + file_name
|
||||
try:
|
||||
return super(VersionedTemplateLoader, self).get_source(environment, template_path)
|
||||
except TemplateNotFound:
|
||||
continue
|
||||
raise TemplateNotFound(template)
|
||||
template_path = path_start + '/' + server_version['name'] + '/' + file_name
|
||||
try:
|
||||
return super(VersionedTemplateLoader, self).get_source(environment, template_path)
|
||||
except TemplateNotFound:
|
||||
continue
|
||||
raise TemplateNotFound(template)
|
||||
|
Loading…
Reference in New Issue
Block a user