mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Display partitions in Greenplum. Fixes #3036
This commit is contained in:
parent
8df006343b
commit
678699c408
@ -733,6 +733,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
|||||||
"/".join([self.table_template_path, 'get_inherits.sql']),
|
"/".join([self.table_template_path, 'get_inherits.sql']),
|
||||||
show_system_objects=self.blueprint.show_system_objects,
|
show_system_objects=self.blueprint.show_system_objects,
|
||||||
tid=tid,
|
tid=tid,
|
||||||
|
scid=scid,
|
||||||
server_type=self.manager.server_type
|
server_type=self.manager.server_type
|
||||||
)
|
)
|
||||||
status, rset = self.conn.execute_2darray(SQL)
|
status, rset = self.conn.execute_2darray(SQL)
|
||||||
|
@ -16,6 +16,7 @@ import pgadmin.browser.server_groups.servers.databases as database
|
|||||||
from flask import render_template, request, jsonify
|
from flask import render_template, request, jsonify
|
||||||
from flask_babel import gettext
|
from flask_babel import gettext
|
||||||
from pgadmin.browser.collection import CollectionNodeModule
|
from pgadmin.browser.collection import CollectionNodeModule
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tables.partitions import backend_supported
|
||||||
from pgadmin.browser.utils import PGChildNodeView
|
from pgadmin.browser.utils import PGChildNodeView
|
||||||
from pgadmin.utils.ajax import make_json_response, internal_server_error, \
|
from pgadmin.utils.ajax import make_json_response, internal_server_error, \
|
||||||
make_response as ajax_response, gone
|
make_response as ajax_response, gone
|
||||||
@ -74,17 +75,7 @@ class IndexesModule(CollectionNodeModule):
|
|||||||
|
|
||||||
# In case of partitioned table return false.
|
# In case of partitioned table return false.
|
||||||
if 'tid' in kwargs and manager.version >= 100000:
|
if 'tid' in kwargs and manager.version >= 100000:
|
||||||
partition_path = 'partition/sql/#{0}#'.format(manager.version)
|
return backend_supported(self, manager, **kwargs)
|
||||||
SQL = render_template(
|
|
||||||
"/".join([partition_path, 'backend_support.sql']),
|
|
||||||
tid=kwargs['tid']
|
|
||||||
)
|
|
||||||
status, res = conn.execute_scalar(SQL)
|
|
||||||
|
|
||||||
# check if any errors
|
|
||||||
if not status:
|
|
||||||
return internal_server_error(errormsg=res)
|
|
||||||
return not res
|
|
||||||
|
|
||||||
if 'vid' not in kwargs:
|
if 'vid' not in kwargs:
|
||||||
return True
|
return True
|
||||||
|
@ -26,6 +26,21 @@ from config import PG_DEFAULT_DRIVER
|
|||||||
from pgadmin.browser.utils import PGChildModule
|
from pgadmin.browser.utils import PGChildModule
|
||||||
|
|
||||||
|
|
||||||
|
def backend_supported(module, manager, **kwargs):
|
||||||
|
if 'tid' in kwargs and CollectionNodeModule.BackendSupported(module, manager, **kwargs):
|
||||||
|
conn = manager.connection(did=kwargs['did'])
|
||||||
|
|
||||||
|
template_path = 'partition/sql/{0}/#{0}#{1}#'.format(manager.server_type, manager.version)
|
||||||
|
SQL = render_template("/".join(
|
||||||
|
[template_path, 'backend_support.sql']), tid=kwargs['tid'])
|
||||||
|
status, res = conn.execute_scalar(SQL)
|
||||||
|
|
||||||
|
# check if any errors
|
||||||
|
if not status:
|
||||||
|
return internal_server_error(errormsg=res)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
class PartitionsModule(CollectionNodeModule):
|
class PartitionsModule(CollectionNodeModule):
|
||||||
"""
|
"""
|
||||||
class PartitionsModule(CollectionNodeModule)
|
class PartitionsModule(CollectionNodeModule)
|
||||||
@ -88,21 +103,7 @@ class PartitionsModule(CollectionNodeModule):
|
|||||||
"""
|
"""
|
||||||
Load this module if it is a partition table
|
Load this module if it is a partition table
|
||||||
"""
|
"""
|
||||||
if manager.server_type == 'gpdb':
|
return backend_supported(self, manager, **kwargs)
|
||||||
return False
|
|
||||||
if 'tid' in kwargs and CollectionNodeModule.BackendSupported(self, manager, **kwargs):
|
|
||||||
conn = manager.connection(did=kwargs['did'])
|
|
||||||
|
|
||||||
template_path = 'partition/sql/#{0}#'.format(manager.version)
|
|
||||||
SQL = render_template("/".join(
|
|
||||||
[template_path, 'backend_support.sql']), tid=kwargs['tid'])
|
|
||||||
status, res = conn.execute_scalar(SQL)
|
|
||||||
|
|
||||||
# check if any errors
|
|
||||||
if not status:
|
|
||||||
return internal_server_error(errormsg=res)
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
def register(self, app, options, first_registration=False):
|
def register(self, app, options, first_registration=False):
|
||||||
"""
|
"""
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas.tables.partitions import PartitionsModule
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
|
||||||
|
if sys.version_info < (3, 3):
|
||||||
|
from mock import patch, Mock, call
|
||||||
|
else:
|
||||||
|
from unittest.mock import patch, Mock, call
|
||||||
|
|
||||||
|
|
||||||
|
class TestBackendSupport(BaseTestGenerator):
|
||||||
|
scenarios = [
|
||||||
|
('when tid is not present in arguments, should return None and no query should be done',
|
||||||
|
dict(
|
||||||
|
manager=dict(
|
||||||
|
server_type="",
|
||||||
|
version=""
|
||||||
|
),
|
||||||
|
input_arguments=dict(did=432),
|
||||||
|
|
||||||
|
collection_node_active=True,
|
||||||
|
connection_execution_return_value=[],
|
||||||
|
|
||||||
|
expected_return_value=None,
|
||||||
|
expect_error_response=False,
|
||||||
|
expected_number_calls_on_render_template=0
|
||||||
|
)),
|
||||||
|
('when tid is present in arguments and CollectionNodeModule does not support, '
|
||||||
|
'should return None and no query should be done',
|
||||||
|
dict(
|
||||||
|
manager=dict(
|
||||||
|
server_type="",
|
||||||
|
version=""
|
||||||
|
),
|
||||||
|
input_arguments=dict(did=432, tid=123),
|
||||||
|
|
||||||
|
collection_node_active=False,
|
||||||
|
connection_execution_return_value=[],
|
||||||
|
|
||||||
|
expected_return_value=None,
|
||||||
|
expect_error_response=False,
|
||||||
|
expected_number_calls_on_render_template=0
|
||||||
|
)),
|
||||||
|
('when table is partitioned, '
|
||||||
|
'should return the table identifier',
|
||||||
|
dict(
|
||||||
|
manager=dict(
|
||||||
|
server_type="gpdb",
|
||||||
|
version="5"
|
||||||
|
),
|
||||||
|
input_arguments=dict(did=432, tid=123),
|
||||||
|
|
||||||
|
collection_node_active=True,
|
||||||
|
connection_execution_return_value=[True, 123],
|
||||||
|
|
||||||
|
expected_return_value=123,
|
||||||
|
expect_error_response=False,
|
||||||
|
expected_number_calls_on_render_template=1,
|
||||||
|
expect_render_template_to_be_called_with=call('partition/sql/gpdb/#gpdb#5#/backend_support.sql', tid=123)
|
||||||
|
)),
|
||||||
|
('when error happens while querying the database, '
|
||||||
|
'should return an internal server error',
|
||||||
|
dict(
|
||||||
|
manager=dict(
|
||||||
|
server_type="pg",
|
||||||
|
version="10"
|
||||||
|
),
|
||||||
|
input_arguments=dict(did=432, tid=123),
|
||||||
|
|
||||||
|
collection_node_active=True,
|
||||||
|
connection_execution_return_value=[False, "Some ugly error"],
|
||||||
|
|
||||||
|
expected_return_value=None,
|
||||||
|
expect_error_response=True,
|
||||||
|
expected_number_calls_on_render_template=1,
|
||||||
|
expect_render_template_to_be_called_with=call('partition/sql/pg/#pg#10#/backend_support.sql', tid=123)
|
||||||
|
))
|
||||||
|
]
|
||||||
|
|
||||||
|
@patch('pgadmin.browser.server_groups.servers.databases.schemas.tables.partitions.internal_server_error')
|
||||||
|
@patch('pgadmin.browser.server_groups.servers.databases.schemas.tables.partitions.CollectionNodeModule')
|
||||||
|
@patch('pgadmin.browser.server_groups.servers.databases.schemas.tables.partitions.render_template')
|
||||||
|
def runTest(self, render_template_mock, CollectionNodeModule_mock, internal_server_error_mock):
|
||||||
|
module = PartitionsModule("partition")
|
||||||
|
module.manager = Mock()
|
||||||
|
module.manager.server_type = self.manager['server_type']
|
||||||
|
module.manager.version = self.manager['version']
|
||||||
|
connection_mock = Mock()
|
||||||
|
connection_mock.execute_scalar.return_value = self.connection_execution_return_value
|
||||||
|
module.manager.connection.return_value = connection_mock
|
||||||
|
CollectionNodeModule_mock.BackendSupported.return_value = self.collection_node_active
|
||||||
|
|
||||||
|
result = module.BackendSupported(module.manager, **self.input_arguments)
|
||||||
|
|
||||||
|
if self.expected_number_calls_on_render_template == 0:
|
||||||
|
render_template_mock.assert_not_called()
|
||||||
|
else:
|
||||||
|
render_template_mock.assert_has_calls([self.expect_render_template_to_be_called_with])
|
||||||
|
|
||||||
|
if self.expect_error_response:
|
||||||
|
internal_server_error_mock.assert_called_with(errormsg=self.connection_execution_return_value[1])
|
||||||
|
else:
|
||||||
|
self.assertEqual(result, self.expected_return_value)
|
@ -0,0 +1,6 @@
|
|||||||
|
SELECT ct.conindid AS oid,
|
||||||
|
ct.conname AS name,
|
||||||
|
NOT convalidated AS convalidated
|
||||||
|
FROM pg_constraint ct
|
||||||
|
WHERE contype='x' AND
|
||||||
|
conrelid = {{tid}}::oid LIMIT 1;
|
@ -0,0 +1,10 @@
|
|||||||
|
SELECT conindid as oid,
|
||||||
|
conname as name,
|
||||||
|
NOT convalidated as convalidated
|
||||||
|
FROM pg_constraint ct
|
||||||
|
WHERE contype='x' AND
|
||||||
|
conrelid = {{tid}}::oid
|
||||||
|
{% if exid %}
|
||||||
|
AND conindid = {{exid}}::oid
|
||||||
|
{% endif %}
|
||||||
|
ORDER BY conname
|
@ -1,6 +1,6 @@
|
|||||||
SELECT ct.conindid AS oid,
|
SELECT ct.conindid AS oid,
|
||||||
ct.conname AS name,
|
ct.conname AS name,
|
||||||
NOT convalidated AS convalidated
|
true AS convalidated
|
||||||
FROM pg_constraint ct
|
FROM pg_constraint ct
|
||||||
WHERE contype='x' AND
|
WHERE contype='x' AND
|
||||||
conrelid = {{tid}}::oid LIMIT 1;
|
conrelid = {{tid}}::oid LIMIT 1;
|
@ -1,10 +1,3 @@
|
|||||||
SELECT conindid as oid,
|
SELECT '' AS oid, '' AS conname, '' AS convalidated
|
||||||
conname as name,
|
|
||||||
NOT convalidated as convalidated
|
|
||||||
FROM pg_constraint ct
|
FROM pg_constraint ct
|
||||||
WHERE contype='x' AND
|
WHERE false
|
||||||
conrelid = {{tid}}::oid
|
|
||||||
{% if exid %}
|
|
||||||
AND conindid = {{exid}}::oid
|
|
||||||
{% endif %}
|
|
||||||
ORDER BY conname
|
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
SELECT ct.oid,
|
||||||
|
NOT convalidated as convalidated
|
||||||
|
FROM pg_constraint ct
|
||||||
|
WHERE contype='f' AND
|
||||||
|
ct.conname = {{ name|qtLiteral }};
|
@ -0,0 +1,6 @@
|
|||||||
|
SELECT ct.oid,
|
||||||
|
ct.conname as name,
|
||||||
|
NOT convalidated as convalidated
|
||||||
|
FROM pg_constraint ct
|
||||||
|
WHERE contype='f' AND
|
||||||
|
conrelid = {{tid}}::oid LIMIT 1;
|
@ -0,0 +1,7 @@
|
|||||||
|
SELECT ct.oid,
|
||||||
|
conname as name,
|
||||||
|
NOT convalidated as convalidated
|
||||||
|
FROM pg_constraint ct
|
||||||
|
WHERE contype='f' AND
|
||||||
|
conrelid = {{tid}}::oid
|
||||||
|
ORDER BY conname
|
@ -1,5 +1,5 @@
|
|||||||
SELECT ct.oid,
|
SELECT ct.oid,
|
||||||
NOT convalidated as convalidated
|
true as convalidated
|
||||||
FROM pg_constraint ct
|
FROM pg_constraint ct
|
||||||
WHERE contype='f' AND
|
WHERE contype='f' AND
|
||||||
ct.conname = {{ name|qtLiteral }};
|
ct.conname = {{ name|qtLiteral }};
|
@ -1,6 +1,6 @@
|
|||||||
SELECT ct.oid,
|
SELECT ct.oid,
|
||||||
ct.conname as name,
|
ct.conname as name,
|
||||||
NOT convalidated as convalidated
|
true as convalidated
|
||||||
FROM pg_constraint ct
|
FROM pg_constraint ct
|
||||||
WHERE contype='f' AND
|
WHERE contype='f' AND
|
||||||
conrelid = {{tid}}::oid LIMIT 1;
|
conrelid = {{tid}}::oid LIMIT 1;
|
@ -1,6 +1,6 @@
|
|||||||
SELECT ct.oid,
|
SELECT ct.oid,
|
||||||
conname as name,
|
conname as name,
|
||||||
NOT convalidated as convalidated
|
true as convalidated
|
||||||
FROM pg_constraint ct
|
FROM pg_constraint ct
|
||||||
WHERE contype='f' AND
|
WHERE contype='f' AND
|
||||||
conrelid = {{tid}}::oid
|
conrelid = {{tid}}::oid
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
SELECT CASE WHEN number_of_rows > 0
|
||||||
|
THEN TRUE
|
||||||
|
ELSE FALSE END AS ptable
|
||||||
|
FROM (
|
||||||
|
SELECT count(*) AS number_of_rows
|
||||||
|
FROM pg_class
|
||||||
|
INNER JOIN pg_partitions ON relname = tablename
|
||||||
|
WHERE pg_class.oid = {{ tid }}::oid
|
||||||
|
) AS number_of_partitions
|
@ -0,0 +1,39 @@
|
|||||||
|
SELECT
|
||||||
|
table_class.oid,
|
||||||
|
partitions.partitiontablename AS name,
|
||||||
|
(SELECT count(*)
|
||||||
|
FROM pg_trigger
|
||||||
|
WHERE tgrelid = table_class.oid AND tgisconstraint = FALSE) AS triggercount,
|
||||||
|
(SELECT count(*)
|
||||||
|
FROM pg_trigger
|
||||||
|
WHERE tgrelid = table_class.oid AND tgisconstraint = FALSE AND tgenabled = 'O') AS has_enable_triggers,
|
||||||
|
partitions.partitionboundary AS partition_value,
|
||||||
|
partitions.partitionschemaname AS schema_id,
|
||||||
|
schema_name,
|
||||||
|
CASE WHEN sub_partitions.n > 0
|
||||||
|
THEN TRUE
|
||||||
|
ELSE FALSE END is_partitioned,
|
||||||
|
'' AS partition_scheme
|
||||||
|
FROM
|
||||||
|
(SELECT
|
||||||
|
table_class.relnamespace,
|
||||||
|
nsp.nspname AS schema_name,
|
||||||
|
partitions.partitiontablename,
|
||||||
|
partitions.partitionboundary,
|
||||||
|
partitions.partitionschemaname
|
||||||
|
FROM pg_class table_class
|
||||||
|
INNER JOIN pg_partitions partitions
|
||||||
|
ON (relname = tablename AND parentpartitiontablename IS NULL) OR relname = parentpartitiontablename
|
||||||
|
LEFT JOIN pg_namespace nsp ON table_class.relnamespace = nsp.oid
|
||||||
|
WHERE
|
||||||
|
{% if ptid %} table_class.oid = {{ ptid }}::OID {% endif %}
|
||||||
|
{% if not ptid %} table_class.oid = {{ tid }}::OID {% endif %}
|
||||||
|
) AS partitions
|
||||||
|
LEFT JOIN (SELECT
|
||||||
|
parentpartitiontablename,
|
||||||
|
count(*) AS n
|
||||||
|
FROM pg_partitions
|
||||||
|
GROUP BY parentpartitiontablename) sub_partitions
|
||||||
|
ON partitions.partitiontablename = sub_partitions.parentpartitiontablename
|
||||||
|
LEFT JOIN pg_class table_class ON partitions.relnamespace = table_class.relnamespace AND partitions.partitiontablename = table_class.relname
|
||||||
|
ORDER BY partitions.partitiontablename;
|
@ -0,0 +1,85 @@
|
|||||||
|
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 parent_schema,
|
||||||
|
nsp.nspname as schema,
|
||||||
|
pg_get_userbyid(rel.relowner) AS relowner, rel.relhasoids,
|
||||||
|
(CASE WHEN partitions.number_of_partitions > 0 THEN true ELSE false END) AS relispartition,
|
||||||
|
rel.relhassubclass, rel.reltuples::bigint, 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 AND tgisconstraint = FALSE) AS triggercount,
|
||||||
|
(SELECT ARRAY(SELECT CASE WHEN (nspname NOT LIKE '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 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,
|
||||||
|
(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, rel.reltype, typ.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,
|
||||||
|
NULL AS seclabels,
|
||||||
|
(CASE WHEN rel.oid <= {{ datlastsysoid}}::oid THEN true ElSE false END) AS is_sys_table,
|
||||||
|
-- Added for partition table
|
||||||
|
(CASE WHEN rel.relkind = 'p' THEN true ELSE false END) AS is_partitioned,
|
||||||
|
'' AS partition_scheme,
|
||||||
|
{% if ptid %}
|
||||||
|
(CASE WHEN partitions.number_of_partitions > 0 THEN partitions.expression ELSE '' END) AS partition_value,
|
||||||
|
(SELECT relname FROM pg_class WHERE oid = {{ tid }}::oid) AS partitioned_table_name
|
||||||
|
{% else %}
|
||||||
|
partitions.expression AS partition_value
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
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 JOIN pg_type typ ON rel.reltype=typ.oid
|
||||||
|
LEFT JOIN pg_inherits inh ON inh.inhrelid = rel.oid
|
||||||
|
LEFT JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
|
||||||
|
LEFT JOIN (SELECT tablename, partitionboundary as expression, count(*) number_of_partitions FROM pg_partitions GROUP BY tablename, expression) partitions ON rel.relname = tablename
|
||||||
|
WHERE inh.inhparent = {{ tid }}::oid
|
||||||
|
{% if ptid %} AND rel.oid = {{ ptid }}::oid {% endif %}
|
||||||
|
ORDER BY rel.relname;
|
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE {{conn|qtIdent(data.parent_schema, data.partitioned_table_name)}} ATTACH PARTITION {{conn|qtIdent(data.schema, data.name)}}
|
||||||
|
{{ data.partition_value }};
|
@ -0,0 +1,36 @@
|
|||||||
|
{% import 'table/sql/macros/constraints.macro' as CONSTRAINTS %}
|
||||||
|
{#===========================================#}
|
||||||
|
{#====== MAIN TABLE TEMPLATE STARTS HERE ======#}
|
||||||
|
{#===========================================#}
|
||||||
|
{### CREATE TABLE STATEMENT FOR partitions ###}
|
||||||
|
CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{% if data.relispartition is defined and data.relispartition %} PARTITION OF {{conn|qtIdent(data.parent_schema, data.partitioned_table_name)}}{% endif %}
|
||||||
|
|
||||||
|
{# Macro to render for constraints #}
|
||||||
|
{% if 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.primary_key|length > 0 %}{{CONSTRAINTS.PRIMARY_KEY(conn, data.primary_key[0])}}{% endif %}{% if data.unique_constraint|length > 0 %}{% if data.primary_key|length > 0 %},{% endif %}
|
||||||
|
{{CONSTRAINTS.UNIQUE(conn, data.unique_constraint)}}{% endif %}{% if data.foreign_key|length > 0 %}{% if 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.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.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.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 %}
|
||||||
|
{{ data.partition_value }}{% if data.is_partitioned is defined and data.is_partitioned %}
|
||||||
|
|
||||||
|
PARTITION BY {{ data.partition_scheme }}{% endif %}
|
||||||
|
{### SQL for Tablespace ###}
|
||||||
|
{% if data.spcname %}
|
||||||
|
|
||||||
|
TABLESPACE {{ conn|qtIdent(data.spcname) }};
|
||||||
|
{% else %}
|
||||||
|
;
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{### Alter SQL for Owner ###}
|
||||||
|
{% if data.relowner %}
|
||||||
|
|
||||||
|
ALTER TABLE {{conn|qtIdent(data.schema, data.name)}}
|
||||||
|
OWNER to {{conn|qtIdent(data.relowner)}};
|
||||||
|
{% endif %}
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE {{conn|qtIdent(data.parent_schema, data.partitioned_table_name)}} DETACH PARTITION {{conn|qtIdent(data.schema, data.name)}};
|
@ -0,0 +1,23 @@
|
|||||||
|
SELECT oid, quote_ident(nspname)||'.'||quote_ident(relname) AS table_name FROM
|
||||||
|
(SELECT
|
||||||
|
r.oid, r.relname, n.nspname, array_agg(a.attname) attnames, array_agg(a.atttypid) atttypes
|
||||||
|
FROM
|
||||||
|
(SELECT oid, relname, relnamespace FROM pg_catalog.pg_class
|
||||||
|
WHERE relkind in ('r', 'p') AND NOT relispartition) r
|
||||||
|
JOIN (SELECT oid AS nspoid, nspname FROM
|
||||||
|
pg_catalog.pg_namespace WHERE nspname NOT LIKE 'pg\_%') n
|
||||||
|
ON (r.relnamespace = n.nspoid)
|
||||||
|
JOIN (SELECT attrelid, attname, atttypid FROM
|
||||||
|
pg_catalog.pg_attribute WHERE attnum > 0 ORDER BY attrelid, attnum) a
|
||||||
|
ON (r.oid = a.attrelid)
|
||||||
|
GROUP BY r.oid, r.relname, r.relnamespace, n.nspname) all_tables
|
||||||
|
JOIN
|
||||||
|
(SELECT
|
||||||
|
attrelid, array_agg(attname) attnames, array_agg(atttypid) atttypes
|
||||||
|
FROM
|
||||||
|
(SELECT * FROM pg_catalog.pg_attribute
|
||||||
|
WHERE attrelid = {{ tid }} AND attnum > 0
|
||||||
|
ORDER BY attrelid, attnum) attributes
|
||||||
|
GROUP BY attrelid) current_table ON current_table.attrelid != all_tables.oid
|
||||||
|
AND current_table.attnames = all_tables.attnames
|
||||||
|
AND current_table.atttypes = all_tables.atttypes
|
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE {{conn|qtIdent(data.parent_schema, data.partitioned_table_name)}} ATTACH PARTITION {{conn|qtIdent(data.schema, data.name)}}
|
||||||
|
{{ data.partition_value }};
|
@ -0,0 +1,9 @@
|
|||||||
|
{#=============Checks if it is partitioned table========#}
|
||||||
|
{% if tid %}
|
||||||
|
SELECT
|
||||||
|
CASE WHEN c.relkind = 'p' THEN True ELSE False END As ptable
|
||||||
|
FROM
|
||||||
|
pg_class c
|
||||||
|
WHERE
|
||||||
|
c.oid = {{ tid }}::oid
|
||||||
|
{% endif %}
|
@ -0,0 +1,36 @@
|
|||||||
|
{% import 'table/sql/macros/constraints.macro' as CONSTRAINTS %}
|
||||||
|
{#===========================================#}
|
||||||
|
{#====== MAIN TABLE TEMPLATE STARTS HERE ======#}
|
||||||
|
{#===========================================#}
|
||||||
|
{### CREATE TABLE STATEMENT FOR partitions ###}
|
||||||
|
CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data.schema, data.name)}}{% if data.relispartition is defined and data.relispartition %} PARTITION OF {{conn|qtIdent(data.parent_schema, data.partitioned_table_name)}}{% endif %}
|
||||||
|
|
||||||
|
{# Macro to render for constraints #}
|
||||||
|
{% if 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.primary_key|length > 0 %}{{CONSTRAINTS.PRIMARY_KEY(conn, data.primary_key[0])}}{% endif %}{% if data.unique_constraint|length > 0 %}{% if data.primary_key|length > 0 %},{% endif %}
|
||||||
|
{{CONSTRAINTS.UNIQUE(conn, data.unique_constraint)}}{% endif %}{% if data.foreign_key|length > 0 %}{% if 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.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.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.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 %}
|
||||||
|
{{ data.partition_value }}{% if data.is_partitioned is defined and data.is_partitioned %}
|
||||||
|
|
||||||
|
PARTITION BY {{ data.partition_scheme }}{% endif %}
|
||||||
|
{### SQL for Tablespace ###}
|
||||||
|
{% if data.spcname %}
|
||||||
|
|
||||||
|
TABLESPACE {{ conn|qtIdent(data.spcname) }};
|
||||||
|
{% else %}
|
||||||
|
;
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{### Alter SQL for Owner ###}
|
||||||
|
{% if data.relowner %}
|
||||||
|
|
||||||
|
ALTER TABLE {{conn|qtIdent(data.schema, data.name)}}
|
||||||
|
OWNER to {{conn|qtIdent(data.relowner)}};
|
||||||
|
{% endif %}
|
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE {{conn|qtIdent(data.parent_schema, data.partitioned_table_name)}} DETACH PARTITION {{conn|qtIdent(data.schema, data.name)}};
|
@ -0,0 +1,23 @@
|
|||||||
|
SELECT oid, quote_ident(nspname)||'.'||quote_ident(relname) AS table_name FROM
|
||||||
|
(SELECT
|
||||||
|
r.oid, r.relname, n.nspname, array_agg(a.attname) attnames, array_agg(a.atttypid) atttypes
|
||||||
|
FROM
|
||||||
|
(SELECT oid, relname, relnamespace FROM pg_catalog.pg_class
|
||||||
|
WHERE relkind in ('r', 'p') AND NOT relispartition) r
|
||||||
|
JOIN (SELECT oid AS nspoid, nspname FROM
|
||||||
|
pg_catalog.pg_namespace WHERE nspname NOT LIKE 'pg\_%') n
|
||||||
|
ON (r.relnamespace = n.nspoid)
|
||||||
|
JOIN (SELECT attrelid, attname, atttypid FROM
|
||||||
|
pg_catalog.pg_attribute WHERE attnum > 0 ORDER BY attrelid, attnum) a
|
||||||
|
ON (r.oid = a.attrelid)
|
||||||
|
GROUP BY r.oid, r.relname, r.relnamespace, n.nspname) all_tables
|
||||||
|
JOIN
|
||||||
|
(SELECT
|
||||||
|
attrelid, array_agg(attname) attnames, array_agg(atttypid) atttypes
|
||||||
|
FROM
|
||||||
|
(SELECT * FROM pg_catalog.pg_attribute
|
||||||
|
WHERE attrelid = {{ tid }} AND attnum > 0
|
||||||
|
ORDER BY attrelid, attnum) attributes
|
||||||
|
GROUP BY attrelid) current_table ON current_table.attrelid != all_tables.oid
|
||||||
|
AND current_table.attnames = all_tables.attnames
|
||||||
|
AND current_table.atttypes = all_tables.atttypes
|
@ -0,0 +1,15 @@
|
|||||||
|
SELECT rel.oid, rel.relname AS name,
|
||||||
|
(SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount,
|
||||||
|
(SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgisinternal = FALSE AND tgenabled = 'O') AS has_enable_triggers,
|
||||||
|
pg_get_expr(rel.relpartbound, rel.oid) AS partition_value,
|
||||||
|
rel.relnamespace AS schema_id,
|
||||||
|
nsp.nspname AS schema_name,
|
||||||
|
(CASE WHEN rel.relkind = 'p' THEN true ELSE false END) AS is_partitioned,
|
||||||
|
(CASE WHEN rel.relkind = 'p' THEN pg_get_partkeydef(rel.oid::oid) ELSE '' END) AS partition_scheme
|
||||||
|
FROM
|
||||||
|
(SELECT * FROM pg_inherits WHERE inhparent = {{ tid }}::oid) inh
|
||||||
|
LEFT JOIN pg_class rel ON inh.inhrelid = rel.oid
|
||||||
|
LEFT JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
|
||||||
|
WHERE rel.relispartition
|
||||||
|
{% if ptid %} AND rel.oid = {{ ptid }}::OID {% endif %}
|
||||||
|
ORDER BY rel.relname;
|
@ -0,0 +1,82 @@
|
|||||||
|
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 parent_schema,
|
||||||
|
nsp.nspname as schema,
|
||||||
|
pg_get_userbyid(rel.relowner) AS relowner, rel.relhasoids, rel.relispartition,
|
||||||
|
rel.relhassubclass, rel.reltuples::bigint, 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 AND tgisinternal = FALSE) AS triggercount,
|
||||||
|
(SELECT ARRAY(SELECT CASE WHEN (nspname NOT LIKE '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 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,
|
||||||
|
(CASE WHEN rel.relpersistence = 'u' THEN true ELSE false END) AS relpersistence,
|
||||||
|
substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor,
|
||||||
|
(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, rel.reloftype, typ.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,
|
||||||
|
|
||||||
|
(SELECT array_agg(provider || '=' || label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS seclabels,
|
||||||
|
(CASE WHEN rel.oid <= {{ datlastsysoid}}::oid THEN true ElSE false END) AS is_sys_table,
|
||||||
|
-- Added for partition table
|
||||||
|
(CASE WHEN rel.relkind = 'p' THEN true ELSE false END) AS is_partitioned,
|
||||||
|
(CASE WHEN rel.relkind = 'p' THEN pg_get_partkeydef(rel.oid::oid) ELSE '' END) AS partition_scheme,
|
||||||
|
{% if ptid %}
|
||||||
|
(CASE WHEN rel.relispartition THEN pg_get_expr(rel.relpartbound, {{ ptid }}::oid) ELSE '' END) AS partition_value,
|
||||||
|
(SELECT relname FROM pg_class WHERE oid = {{ tid }}::oid) AS partitioned_table_name
|
||||||
|
{% else %}
|
||||||
|
pg_get_expr(rel.relpartbound, rel.oid) AS partition_value
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
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 JOIN pg_type typ ON rel.reloftype=typ.oid
|
||||||
|
LEFT JOIN pg_inherits inh ON inh.inhrelid = rel.oid
|
||||||
|
LEFT JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid
|
||||||
|
WHERE rel.relispartition AND inh.inhparent = {{ tid }}::oid
|
||||||
|
{% if ptid %} AND rel.oid = {{ ptid }}::oid {% endif %}
|
||||||
|
ORDER BY rel.relname;
|
@ -0,0 +1,17 @@
|
|||||||
|
{% import 'table/sql/macros/db_catalogs.macro' as CATALOG %}
|
||||||
|
SELECT c.oid, c.relname , nspname,
|
||||||
|
CASE WHEN nspname NOT LIKE 'pg\_%' THEN
|
||||||
|
quote_ident(nspname)||'.'||quote_ident(c.relname)
|
||||||
|
ELSE quote_ident(c.relname)
|
||||||
|
END AS inherits
|
||||||
|
FROM pg_class c
|
||||||
|
JOIN pg_namespace n
|
||||||
|
ON n.oid=c.relnamespace
|
||||||
|
WHERE relkind='r'
|
||||||
|
{% if not show_system_objects %}
|
||||||
|
{{ CATALOG.VALID_CATALOGS(server_type) }}
|
||||||
|
{% endif %}
|
||||||
|
{% if tid %}
|
||||||
|
AND c.oid != tid
|
||||||
|
{% endif %}
|
||||||
|
ORDER BY relnamespace, c.relname
|
@ -14,4 +14,5 @@ WHERE relkind='r'
|
|||||||
{% if tid %}
|
{% if tid %}
|
||||||
AND c.oid != tid
|
AND c.oid != tid
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
AND c.relnamespace = {{ scid }}
|
||||||
ORDER BY relnamespace, c.relname
|
ORDER BY relnamespace, c.relname
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
SELECT rel.oid, rel.relname AS name,
|
||||||
|
(SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid) AS triggercount,
|
||||||
|
(SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgenabled = 'O') AS has_enable_triggers
|
||||||
|
FROM pg_class rel
|
||||||
|
WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ scid }}::oid
|
||||||
|
AND rel.relname NOT IN (SELECT partitiontablename FROM pg_partitions)
|
||||||
|
{% if tid %}
|
||||||
|
AND rel.oid = {{tid}}::OID
|
||||||
|
{% endif %}
|
||||||
|
ORDER BY rel.relname;
|
@ -116,7 +116,7 @@ class BaseTableView(PGChildNodeView):
|
|||||||
if server_type == 'gpdb' else
|
if server_type == 'gpdb' else
|
||||||
'#{0}#'.format(ver)
|
'#{0}#'.format(ver)
|
||||||
)
|
)
|
||||||
self.partition_template_path = 'partition/sql/#{0}#'.format(ver)
|
self.partition_template_path = 'partition/sql/{0}/#{0}#{1}#'.format(server_type, ver)
|
||||||
|
|
||||||
# Template for Column ,check constraint and exclusion
|
# Template for Column ,check constraint and exclusion
|
||||||
# constraint node
|
# constraint node
|
||||||
@ -600,7 +600,8 @@ class BaseTableView(PGChildNodeView):
|
|||||||
# system columns
|
# system columns
|
||||||
SQL = render_template("/".join([self.table_template_path,
|
SQL = render_template("/".join([self.table_template_path,
|
||||||
'get_inherits.sql']),
|
'get_inherits.sql']),
|
||||||
show_system_objects=False
|
show_system_objects=False,
|
||||||
|
scid=scid
|
||||||
)
|
)
|
||||||
status, rset = self.conn.execute_2darray(SQL)
|
status, rset = self.conn.execute_2darray(SQL)
|
||||||
if not status:
|
if not status:
|
||||||
|
@ -29,6 +29,7 @@ class VersionedTemplateLoader(DispatchingJinjaLoader):
|
|||||||
|
|
||||||
gpdb_versions = (
|
gpdb_versions = (
|
||||||
{'name': "gpdb_5.0_plus", 'number': 80323},
|
{'name': "gpdb_5.0_plus", 'number': 80323},
|
||||||
|
{'name': "5_plus", 'number': 80323},
|
||||||
{'name': "default", 'number': 0}
|
{'name': "default", 'number': 0}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user