Fixed issue where icon for Partitioned tables was the same as Non Partitioned tables for GreenPlum database. Fixes #3308
parent
2ace6a60f3
commit
966279c1b3
|
@ -18,3 +18,4 @@ Bug fixes
|
||||||
| `Bug #3257 <https://redmine.postgresql.org/issues/3257>`_ - Catch errors when trying to EXPLAIN an invalid query
|
| `Bug #3257 <https://redmine.postgresql.org/issues/3257>`_ - Catch errors when trying to EXPLAIN an invalid query
|
||||||
| `Bug #3290 <https://redmine.postgresql.org/issues/3290>`_ - Close button added to the alertify message box, which pops up in case of backend error
|
| `Bug #3290 <https://redmine.postgresql.org/issues/3290>`_ - Close button added to the alertify message box, which pops up in case of backend error
|
||||||
| `Bug #3306 <https://redmine.postgresql.org/issues/3306>`_ - Fixed display SQL of table with index for GreenPlum database
|
| `Bug #3306 <https://redmine.postgresql.org/issues/3306>`_ - Fixed display SQL of table with index for GreenPlum database
|
||||||
|
| `Bug #3308 <https://redmine.postgresql.org/issues/3308>`_ - Fixed issue where icon for Partitioned tables was the same as Non Partitioned tables for GreenPlum database
|
|
@ -303,21 +303,17 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
||||||
if len(rset['rows']) == 0:
|
if len(rset['rows']) == 0:
|
||||||
return gone(gettext("Could not find the table."))
|
return gone(gettext("Could not find the table."))
|
||||||
|
|
||||||
if 'is_partitioned' in rset['rows'][0] and \
|
table_information = rset['rows'][0]
|
||||||
rset['rows'][0]['is_partitioned']:
|
icon = self.get_icon_css_class(table_information)
|
||||||
icon = "icon-partition"
|
|
||||||
else:
|
|
||||||
icon = "icon-table"
|
|
||||||
|
|
||||||
res = self.blueprint.generate_browser_node(
|
res = self.blueprint.generate_browser_node(
|
||||||
rset['rows'][0]['oid'],
|
table_information['oid'],
|
||||||
scid,
|
scid,
|
||||||
rset['rows'][0]['name'],
|
table_information['name'],
|
||||||
icon=icon,
|
icon=icon,
|
||||||
tigger_count=rset['rows'][0]['triggercount'],
|
tigger_count=table_information['triggercount'],
|
||||||
has_enable_triggers=rset['rows'][0]['has_enable_triggers'],
|
has_enable_triggers=table_information['has_enable_triggers'],
|
||||||
is_partitioned=rset['rows'][0]['is_partitioned'] if
|
is_partitioned=self.is_table_partitioned(table_information)
|
||||||
'is_partitioned' in rset['rows'][0] else False
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return make_json_response(
|
return make_json_response(
|
||||||
|
@ -350,10 +346,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
||||||
return internal_server_error(errormsg=rset)
|
return internal_server_error(errormsg=rset)
|
||||||
|
|
||||||
for row in rset['rows']:
|
for row in rset['rows']:
|
||||||
if 'is_partitioned' in row and row['is_partitioned']:
|
icon = self.get_icon_css_class(row)
|
||||||
icon = "icon-partition"
|
|
||||||
else:
|
|
||||||
icon = "icon-table"
|
|
||||||
|
|
||||||
res.append(
|
res.append(
|
||||||
self.blueprint.generate_browser_node(
|
self.blueprint.generate_browser_node(
|
||||||
|
@ -363,8 +356,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
||||||
icon=icon,
|
icon=icon,
|
||||||
tigger_count=row['triggercount'],
|
tigger_count=row['triggercount'],
|
||||||
has_enable_triggers=row['has_enable_triggers'],
|
has_enable_triggers=row['has_enable_triggers'],
|
||||||
is_partitioned=row['is_partitioned'] if
|
is_partitioned=self.is_table_partitioned(row),
|
||||||
'is_partitioned' in row else False,
|
|
||||||
rows_cnt=0
|
rows_cnt=0
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@ -968,13 +960,11 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
partitions_sql = ''
|
partitions_sql = ''
|
||||||
partitioned = False
|
if self.is_table_partitioned(data):
|
||||||
if 'is_partitioned' in data and data['is_partitioned']:
|
|
||||||
data['relkind'] = 'p'
|
data['relkind'] = 'p'
|
||||||
# create partition scheme
|
# create partition scheme
|
||||||
data['partition_scheme'] = self.get_partition_scheme(data)
|
data['partition_scheme'] = self.get_partition_scheme(data)
|
||||||
partitions_sql = self.get_partitions_sql(data)
|
partitions_sql = self.get_partitions_sql(data)
|
||||||
partitioned = True
|
|
||||||
|
|
||||||
SQL = render_template(
|
SQL = render_template(
|
||||||
"/".join([self.table_template_path, 'create.sql']),
|
"/".join([self.table_template_path, 'create.sql']),
|
||||||
|
@ -1021,8 +1011,8 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
||||||
tid,
|
tid,
|
||||||
scid,
|
scid,
|
||||||
data['name'],
|
data['name'],
|
||||||
icon="icon-partition" if partitioned else "icon-table",
|
icon=self.get_icon_css_class(data),
|
||||||
is_partitioned=partitioned
|
is_partitioned=self.is_table_partitioned(data)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
class BasePartitionTable:
|
||||||
|
def is_table_partitioned(self, table_info):
|
||||||
|
if (
|
||||||
|
getattr(self, 'node_type', '') == 'partition' or
|
||||||
|
('is_partitioned' in table_info and table_info['is_partitioned'])
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_icon_css_class(self, table_info):
|
||||||
|
if self.is_table_partitioned(table_info):
|
||||||
|
return 'icon-partition'
|
||||||
|
return 'icon-table'
|
|
@ -308,7 +308,7 @@ class PartitionsView(BaseTableView, DataTypeReader, VacuumSettings):
|
||||||
row['oid'],
|
row['oid'],
|
||||||
tid,
|
tid,
|
||||||
row['name'],
|
row['name'],
|
||||||
icon="icon-partition",
|
icon=self.get_icon_css_class({}),
|
||||||
tigger_count=row['triggercount'],
|
tigger_count=row['triggercount'],
|
||||||
has_enable_triggers=row['has_enable_triggers'],
|
has_enable_triggers=row['has_enable_triggers'],
|
||||||
is_partitioned=row['is_partitioned'],
|
is_partitioned=row['is_partitioned'],
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
SELECT rel.oid, rel.relname AS name,
|
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) AS triggercount,
|
||||||
(SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgenabled = 'O') AS has_enable_triggers
|
(SELECT count(*) FROM pg_trigger WHERE tgrelid=rel.oid AND tgenabled = 'O') AS has_enable_triggers,
|
||||||
|
(CASE WHEN (SELECT count(*) from pg_partition where parrelid = rel.oid) > 0 THEN true ELSE false END) AS is_partitioned
|
||||||
FROM pg_class rel
|
FROM pg_class rel
|
||||||
WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ scid }}::oid
|
WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = {{ scid }}::oid
|
||||||
AND rel.relname NOT IN (SELECT partitiontablename FROM pg_partitions)
|
AND rel.relname NOT IN (SELECT partitiontablename FROM pg_partitions)
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas\
|
||||||
|
.tables.base_partition_table import BasePartitionTable
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class TestBasePartitionTable(BaseTestGenerator):
|
||||||
|
scenarios = [
|
||||||
|
('#is_table_partitioned when table information does not '
|
||||||
|
'have partition information, '
|
||||||
|
'it returns false',
|
||||||
|
dict(
|
||||||
|
test='is_table_partitioned',
|
||||||
|
input_parameters=dict(),
|
||||||
|
expected_return=False
|
||||||
|
)),
|
||||||
|
('#is_table_partitioned when table information '
|
||||||
|
'has partition information and table is partitioned, '
|
||||||
|
'it returns true',
|
||||||
|
dict(
|
||||||
|
test='is_table_partitioned',
|
||||||
|
input_parameters=dict(
|
||||||
|
is_partitioned=True
|
||||||
|
),
|
||||||
|
expected_return=True
|
||||||
|
)),
|
||||||
|
('#is_table_partitioned when table information '
|
||||||
|
'has partition information and table is not partitioned, '
|
||||||
|
'it returns false',
|
||||||
|
dict(
|
||||||
|
test='is_table_partitioned',
|
||||||
|
input_parameters=dict(
|
||||||
|
is_partitioned=False
|
||||||
|
),
|
||||||
|
expected_return=False
|
||||||
|
)),
|
||||||
|
('#is_table_partitioned when node_type is present '
|
||||||
|
'and is partition, '
|
||||||
|
'it returns true',
|
||||||
|
dict(
|
||||||
|
test='is_table_partitioned',
|
||||||
|
input_parameters=dict(
|
||||||
|
is_partitioned=False
|
||||||
|
),
|
||||||
|
node_type='partition',
|
||||||
|
expected_return=True
|
||||||
|
)),
|
||||||
|
('#is_table_partitioned when node_type is present '
|
||||||
|
'and is not partition '
|
||||||
|
'and table is not partitioned '
|
||||||
|
'it returns true',
|
||||||
|
dict(
|
||||||
|
test='is_table_partitioned',
|
||||||
|
input_parameters=dict(
|
||||||
|
is_partitioned=False
|
||||||
|
),
|
||||||
|
node_type='table',
|
||||||
|
expected_return=False
|
||||||
|
)),
|
||||||
|
|
||||||
|
|
||||||
|
('#get_icon_css_class when table is partitioned '
|
||||||
|
'it returns icon-partition class',
|
||||||
|
dict(
|
||||||
|
test='get_icon_css_class',
|
||||||
|
input_parameters=dict(
|
||||||
|
is_partitioned=True
|
||||||
|
),
|
||||||
|
expected_return='icon-partition'
|
||||||
|
)),
|
||||||
|
('#get_icon_css_class when table is not partitioned '
|
||||||
|
'it returns icon-table class',
|
||||||
|
dict(
|
||||||
|
test='get_icon_css_class',
|
||||||
|
input_parameters=dict(
|
||||||
|
is_partitioned=False
|
||||||
|
),
|
||||||
|
expected_return='icon-table'
|
||||||
|
))
|
||||||
|
]
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
if self.test == 'is_table_partitioned':
|
||||||
|
self.__test_is_table_partitioned()
|
||||||
|
elif self.test == 'get_icon_css_class':
|
||||||
|
self.__test_get_icon_css_class()
|
||||||
|
|
||||||
|
def __test_is_table_partitioned(self):
|
||||||
|
subject = BasePartitionTable()
|
||||||
|
if hasattr(self, 'node_type'):
|
||||||
|
subject.node_type = self.node_type
|
||||||
|
|
||||||
|
self.assertEqual(subject.is_table_partitioned(self.input_parameters),
|
||||||
|
self.expected_return)
|
||||||
|
|
||||||
|
def __test_get_icon_css_class(self):
|
||||||
|
subject = BasePartitionTable()
|
||||||
|
|
||||||
|
self.assertEqual(subject.get_icon_css_class(self.input_parameters),
|
||||||
|
self.expected_return)
|
|
@ -14,6 +14,9 @@ from functools import wraps
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
from flask import render_template, jsonify, request
|
from flask import render_template, jsonify, request
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
|
|
||||||
|
from pgadmin.browser.server_groups.servers.databases.schemas\
|
||||||
|
.tables.base_partition_table import BasePartitionTable
|
||||||
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
|
make_response as ajax_response
|
||||||
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
|
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
|
||||||
|
@ -27,7 +30,7 @@ from pgadmin.utils.driver import get_driver
|
||||||
from config import PG_DEFAULT_DRIVER
|
from config import PG_DEFAULT_DRIVER
|
||||||
|
|
||||||
|
|
||||||
class BaseTableView(PGChildNodeView):
|
class BaseTableView(PGChildNodeView, BasePartitionTable):
|
||||||
"""
|
"""
|
||||||
This class is base class for tables and partitioned tables.
|
This class is base class for tables and partitioned tables.
|
||||||
|
|
||||||
|
@ -2067,13 +2070,7 @@ class BaseTableView(PGChildNodeView):
|
||||||
partitions_oid['created'] = created
|
partitions_oid['created'] = created
|
||||||
partitions_oid['attached'] = attached
|
partitions_oid['attached'] = attached
|
||||||
|
|
||||||
if self.node_type == 'partition':
|
icon = self.get_icon_css_class(res['rows'][0])
|
||||||
icon = "icon-partition"
|
|
||||||
elif 'is_partitioned' in res['rows'][0] and \
|
|
||||||
res['rows'][0]['is_partitioned']:
|
|
||||||
icon = "icon-partition"
|
|
||||||
else:
|
|
||||||
icon = "icon-table"
|
|
||||||
|
|
||||||
if 'relkind' in res['rows'][0] and \
|
if 'relkind' in res['rows'][0] and \
|
||||||
res['rows'][0]['relkind'] == 'p':
|
res['rows'][0]['relkind'] == 'p':
|
||||||
|
|
Loading…
Reference in New Issue