Proper SQL should be generated when create domain of type interval with precision. Fixes #3853

This commit is contained in:
Khushboo Vashi 2019-01-22 17:53:36 +05:30 committed by Akshay Joshi
parent ea87d6da8f
commit c6bae69b6f
4 changed files with 177 additions and 5 deletions

View File

@ -26,6 +26,7 @@ Bug fixes
| `Bug #3838 <https://redmine.postgresql.org/issues/3838>`_ - Proper SQL should be generated when creating/changing column with custom type argument.
| `Bug #3840 <https://redmine.postgresql.org/issues/3840>`_ - Ensure that file format combo box value should be retained when hidden files checkbox is toggled.
| `Bug #3846 <https://redmine.postgresql.org/issues/3846>`_ - Proper SQL should be generated when create procedure with custom type arguments.
| `Bug #3853 <https://redmine.postgresql.org/issues/3853>`_ - Proper SQL should be generated when create domain of type interval with precision.
| `Bug #3858 <https://redmine.postgresql.org/issues/3858>`_ - Drop-down should be closed when click on any other toolbar button.
| `Bug #3862 <https://redmine.postgresql.org/issues/3862>`_ - Fixed keyboard navigation for dialog tabs.
| `Bug #3871 <https://redmine.postgresql.org/issues/3871>`_ - Fixed alignment of tree arrow icons for Internet Explorer.

View File

@ -442,11 +442,10 @@ It may have been removed by another user or moved to another schema.
substr = basetype[basetype.find("(") + 1:len(
basetype) - 1]
typlen = substr.split(",")
typ_len = typlen[0]
if len(typlen) > 1:
typ_len = typlen[0]
typ_precision = typlen[1]
else:
typ_len = typlen
typ_precision = ''
return {'typlen': typ_len, 'precision': typ_precision}

View File

@ -0,0 +1,117 @@
##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2019, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
import uuid
import json
import re
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
utils as schema_utils
from pgadmin.browser.server_groups.servers.databases.tests import utils as \
database_utils
from pgadmin.utils.route import BaseTestGenerator
from regression import parent_node_dict
from regression.python_test_utils import test_utils as utils
from . import utils as domain_utils
class DomainReverseEngineeredSQLTestCase(BaseTestGenerator):
""" This class will verify reverse engineered sql for domain
under schema node. """
scenarios = [
# Fetching default URL for domain node.
('Domain Reverse Engineered SQL with char',
dict(url='/browser/domain/sql/',
domain_name='domain_get_%s' % (str(uuid.uuid4())[1:8]),
domain_sql='AS "char";'
)
),
('Domain Reverse Engineered SQL with Length, Precision and Default',
dict(url='/browser/domain/sql/',
domain_name='domain_get_%s' % (str(uuid.uuid4())[1:8]),
domain_sql='AS numeric(12,2) DEFAULT 12 NOT NULL;'
)
),
('Domain Reverse Engineered SQL with Length',
dict(url='/browser/domain/sql/',
domain_name='domain_get_%s' % (str(uuid.uuid4())[1:8]),
domain_sql='AS interval(6);'
)
),
]
def setUp(self):
self.database_info = parent_node_dict["database"][-1]
self.db_name = self.database_info["db_name"]
self.schema_info = parent_node_dict["schema"][-1]
self.schema_name = self.schema_info["schema_name"]
self.schema_id = self.schema_info["schema_id"]
self.domain_info = domain_utils.create_domain(self.server,
self.db_name,
self.schema_name,
self.schema_id,
self.domain_name,
self.domain_sql)
def runTest(self):
""" This function will add domain and verify the
reverse engineered sql. """
db_id = self.database_info["db_id"]
server_id = self.database_info["server_id"]
db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
server_id, db_id)
if not db_con['data']["connected"]:
raise Exception("Could not connect to database to get the domain.")
db_name = self.database_info["db_name"]
schema_response = schema_utils.verify_schemas(self.server,
db_name,
self.schema_name)
if not schema_response:
raise Exception("Could not find the schema to get the domain.")
domain_id = self.domain_info[0]
# Call GET API to fetch the domain sql
get_response = self.tester.get(
self.url + str(utils.SERVER_GROUP) + '/' +
str(server_id) + '/' +
str(db_id) + '/' +
str(self.schema_id) + '/' +
str(domain_id),
content_type='html/json')
self.assertEquals(get_response.status_code, 200)
orig_sql = json.loads(get_response.data.decode('utf-8'))
# Replace multiple spaces with one space and check the expected sql
sql = re.sub('\s+', ' ', orig_sql).strip()
expected_sql = '-- DOMAIN: {0}.{1} -- DROP DOMAIN {0}.{1}; ' \
'CREATE DOMAIN {0}.{1} {2} ' \
'ALTER DOMAIN {0}.{1} OWNER' \
' TO postgres;'.format(self.schema_name,
self.domain_name,
self.domain_sql)
self.assertEquals(sql, expected_sql)
domain_utils.delete_domain(self.server, db_name,
self.schema_name, self.domain_name)
# Verify the reverse engineered sql with creating domain with
# the sql we get from the server
domain_utils.create_domain_from_sql(self.server, db_name, orig_sql)
domain_utils.delete_domain(self.server, db_name,
self.schema_name, self.domain_name)
# Disconnect the database
database_utils.disconnect_database(self, server_id, db_id)
def tearDown(self):
pass

View File

@ -15,7 +15,8 @@ import traceback
from regression.python_test_utils import test_utils as utils
def create_domain(server, db_name, schema_name, schema_id, domain_name):
def create_domain(server, db_name, schema_name, schema_id, domain_name,
domain_sql=None):
"""
This function is used to add the domain to existing schema
:param server: server details
@ -37,8 +38,14 @@ def create_domain(server, db_name, schema_name, schema_id, domain_name):
server['host'],
server['port'])
pg_cursor = connection.cursor()
query = 'CREATE DOMAIN ' + schema_name + '.' + domain_name + \
' AS character(10) DEFAULT 1'
if domain_sql is None:
query = 'CREATE DOMAIN ' + schema_name + '.' + domain_name + \
' AS character(10) DEFAULT 1'
else:
query = 'CREATE DOMAIN ' + schema_name + '.' +\
domain_name + ' ' + domain_sql
pg_cursor.execute(query)
connection.commit()
# Get 'oid' from newly created domain
@ -77,3 +84,51 @@ def verify_domain(server, db_name, schema_id, domain_name):
domains = pg_cursor.fetchone()
connection.close()
return domains
def delete_domain(server, db_name, schema_name, domain_name):
"""
This function deletes the domain.
:param server:
:param db_name:
:param schema_name:
:param domain_name:
:return:
"""
try:
connection = utils.get_db_connection(db_name,
server['username'],
server['db_password'],
server['host'],
server['port'])
pg_cursor = connection.cursor()
pg_cursor.execute("DROP DOMAIN %s.%s" %
(schema_name, domain_name))
connection.commit()
connection.close()
except Exception:
traceback.print_exc(file=sys.stderr)
def create_domain_from_sql(server, db_name, sql):
"""
This function create domain from the reverse engineered sql
:param server:
:param db_name:
:param sql:
:return:
"""
try:
connection = utils.get_db_connection(db_name,
server['username'],
server['db_password'],
server['host'],
server['port'])
pg_cursor = connection.cursor()
pg_cursor.execute(sql)
connection.commit()
connection.close()
except Exception:
traceback.print_exc(file=sys.stderr)