1) Added 'Ignore Grants' option in the schema diff tool. #5759

2) Added 'Ignore Tablespace' option in the schema diff tool. #6004
3) Ensure that Schema Diff comparison results should be displayed in the sorted order. #6595
4) Fixed an issue where the SET directive is excluded from the function header in the schema diff tool. #6651
This commit is contained in:
Akshay Joshi
2023-08-11 17:38:44 +05:30
committed by GitHub
parent e80d55e968
commit 3c43aa12af
38 changed files with 390 additions and 5088 deletions

View File

@@ -224,8 +224,7 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
'compare': [{'get': 'compare'}, {'get': 'compare'}]
})
keys_to_ignore = ['oid', 'basensp', 'oid-2', 'attnum', 'strftoptions',
'relacl']
keys_to_ignore = ['oid', 'basensp', 'oid-2', 'attnum', 'strftoptions']
def validate_request(f):
"""
@@ -889,9 +888,9 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
data['basensp'] = target_schema
# Parse Privileges
if 'acl' in data:
data['acl'] = parse_priv_to_db(data['acl'],
["a", "r", "w", "x"])
if 'relacl' in data:
data['relacl'] = parse_priv_to_db(data['relacl'],
["a", "r", "w", "x"])
SQL = render_template("/".join([self.template_path,
self._CREATE_SQL]),
@@ -932,9 +931,22 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
Returns:
SQL statements to create/update the Foreign Table.
"""
data = {}
for k, v in self.request.items():
try:
# comments should be taken as is because if user enters a
# json comment it is parsed by loads which should not happen
if k in ('description',):
data[k] = v
else:
data[k] = json.loads(v)
except ValueError:
data[k] = v
except TypeError:
data[k] = v
try:
SQL, name = self.get_sql(gid=gid, sid=sid, did=did, scid=scid,
data=self.request, foid=foid)
data=data, foid=foid)
# Most probably this is due to error
if not isinstance(SQL, str):
return SQL
@@ -956,15 +968,15 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
:param data: Data.
:return:
"""
if 'acl' in data and 'added' in data['acl']:
data['acl']['added'] = parse_priv_to_db(data['acl']['added'],
["a", "r", "w", "x"])
if 'acl' in data and 'changed' in data['acl']:
data['acl']['changed'] = parse_priv_to_db(
data['acl']['changed'], ["a", "r", "w", "x"])
if 'acl' in data and 'deleted' in data['acl']:
data['acl']['deleted'] = parse_priv_to_db(
data['acl']['deleted'], ["a", "r", "w", "x"])
if 'relacl' in data and 'added' in data['relacl']:
data['relacl']['added'] = parse_priv_to_db(
data['relacl']['added'], ["a", "r", "w", "x"])
if 'relacl' in data and 'changed' in data['relacl']:
data['relacl']['changed'] = parse_priv_to_db(
data['relacl']['changed'], ["a", "r", "w", "x"])
if 'relacl' in data and 'deleted' in data['relacl']:
data['relacl']['deleted'] = parse_priv_to_db(
data['relacl']['deleted'], ["a", "r", "w", "x"])
@staticmethod
def _check_old_col_ops(old_col_frmt_options, option, col):
@@ -1095,9 +1107,9 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
data['columns'] = self._format_columns(data['columns'])
# Parse Privileges
if 'acl' in data:
data['acl'] = parse_priv_to_db(data['acl'],
["a", "r", "w", "x"])
if 'relacl' in data:
data['relacl'] = parse_priv_to_db(data['relacl'],
["a", "r", "w", "x"])
sql = render_template("/".join([self.template_path,
self._CREATE_SQL]), data=data,
@@ -1320,7 +1332,7 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
priv = parse_priv_from_db(row)
privileges.append(priv)
return {"acl": privileges}
return {"relacl": privileges}
def _parse_variables_from_db(self, db_variables):
"""

View File

@@ -33,7 +33,6 @@ export default class ForeignTableSchema extends BaseUISchema {
columns: [],
ftoptions: [],
relacl: [],
stracl: [],
seclabels: [],
...initValues
});
@@ -198,12 +197,11 @@ export default class ForeignTableSchema extends BaseUISchema {
canAdd: true, canDelete: true, uniqueCol : ['option'],
},
{
id: 'relacl', label: gettext('Privileges'), cell: 'text',
type: 'text', group: gettext('Security'),
mode: ['properties'], min_version: 90200,
id: 'acl', label: gettext('Privileges'), type: 'text',
group: gettext('Security'), mode: ['properties'], min_version: 90200,
},
{
id: 'acl', label: gettext('Privileges'), type: 'collection',
id: 'relacl', label: gettext('Privileges'), type: 'collection',
schema: this.getPrivilegeRoleSchema(['a','r','w','x']),
uniqueCol : ['grantee', 'grantor'],
editable: false,

View File

@@ -56,9 +56,9 @@ COMMENT ON COLUMN {{conn|qtIdent(data.basensp, data.name, c.attname)}}
{% endif %}
{% endfor %}
{% endif %}
{% if data.acl %}
{% if data.relacl %}
{% for priv in data.acl %}
{% for priv in data.relacl %}
{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.basensp) }}
{% endfor -%}
{% endif -%}

View File

@@ -1,5 +1,6 @@
SELECT
c.oid, c.relname AS name, c.relacl, pg_catalog.pg_get_userbyid(relowner) AS owner,
c.oid, c.relname AS name, pg_catalog.pg_get_userbyid(relowner) AS owner,
pg_catalog.array_to_string(c.relacl::text[], ', ') as acl,
ftoptions, srvname AS ftsrvname, description, nspname AS basensp,
(SELECT
pg_catalog.array_agg(provider || '=' || label)

View File

@@ -187,23 +187,23 @@ COMMENT ON FOREIGN TABLE {{ conn|qtIdent(o_data.basensp, name) }}
IS {{ data.description|qtLiteral(conn) }};
{% endif -%}
{% if data.acl %}
{% if 'deleted' in data.acl %}
{% for priv in data.acl.deleted %}
{% if data.relacl %}
{% if 'deleted' in data.relacl %}
{% for priv in data.relacl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, name, o_data.basensp) }}
{% endfor %}
{% endif -%}
{% if 'changed' in data.acl %}
{% for priv in data.acl.changed %}
{% if 'changed' in data.relacl %}
{% for priv in data.relacl.changed %}
{{ PRIVILEGE.UNSETALL(conn, 'TABLE', priv.grantee, name, o_data.basensp) }}
{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.basensp) }}
{% endfor %}
{% endif -%}
{% if 'added' in data.acl %}
{% for priv in data.acl.added %}
{% if 'added' in data.relacl %}
{% for priv in data.relacl.added %}
{{ PRIVILEGE.SET(conn, 'TABLE', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.basensp) }}
{% endfor %}

View File

@@ -55,7 +55,7 @@
"option":"table_name",
"value":"test_table"
}],
"acl":[{
"relacl":[{
"grantee":"PUBLIC",
"grantor":"postgres",
"privileges":[{
@@ -153,7 +153,7 @@
"sql_endpoint": "NODE-foreign_table.sql_id",
"msql_endpoint": "NODE-foreign_table.msql_id",
"data": {
"acl":{
"relacl":{
"added": [{
"grantee":"PUBLIC",
"grantor":"postgres",
@@ -205,7 +205,7 @@
"sql_endpoint": "NODE-foreign_table.sql_id",
"msql_endpoint": "NODE-foreign_table.msql_id",
"data": {
"acl":{
"relacl":{
"deleted": [{
"grantee":"PUBLIC",
"grantor":"postgres",

View File

@@ -55,7 +55,7 @@
"option":"table_name",
"value":"test_table"
}],
"acl":[{
"relacl":[{
"grantee":"PUBLIC",
"grantor":"enterprisedb",
"privileges":[{
@@ -153,7 +153,7 @@
"sql_endpoint": "NODE-foreign_table.sql_id",
"msql_endpoint": "NODE-foreign_table.msql_id",
"data": {
"acl":{
"relacl":{
"added": [{
"grantee":"PUBLIC",
"grantor":"enterprisedb",
@@ -205,7 +205,7 @@
"sql_endpoint": "NODE-foreign_table.sql_id",
"msql_endpoint": "NODE-foreign_table.msql_id",
"data": {
"acl":{
"relacl":{
"deleted": [{
"grantee":"PUBLIC",
"grantor":"enterprisedb",

View File

@@ -1,122 +0,0 @@
{% import 'macros/functions/security.macros' as SECLABEL %}
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% set exclude_quoting = ['search_path'] %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
o_data.proargtypenames }})
RENAME TO {{ conn|qtIdent(data.name) }};
{% set name = data.name %}
{% endif %}
{% endif -%}
{% if data.change_func %}
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ p.argtype }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
RETURNS {% if 'prorettypename' in data %}{{ data.prorettypename }}{% else %}{{ o_data.prorettypename }}{% endif %}
{% if 'lanname' in data %}
LANGUAGE {{ data.lanname|qtLiteral(conn) }} {% else %}
LANGUAGE {{ o_data.lanname|qtLiteral(conn) }}
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
{% if ('proleakproof' in data and data.proleakproof) or ('proleakproof' not in data and o_data.proleakproof) %} LEAKPROOF{% elif 'proleakproof' in data and not data.proleakproof %} NOT LEAKPROOF{% endif %}
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
{% if 'proparallel' in data and data.proparallel %}PARALLEL {{ data.proparallel }}{% elif 'proparallel' not in data and o_data.proparallel %}PARALLEL {{ o_data.proparallel }}{% endif %}
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows and data.prorows != '0'%}
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
{% endif %}
AS {% if (data.lanname == 'c' or o_data.lanname == 'c') and ('probin' in data or 'prosrc_c' in data) %}
{% if 'probin' in data %}{{ data.probin|qtLiteral(conn) }}{% else %}{{ o_data.probin|qtLiteral(conn) }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral(conn) }}{% else %}{{ o_data.prosrc_c|qtLiteral(conn) }}{% endif %}{% elif 'prosrc' in data %}
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
{{ o_data.probin|qtLiteral(conn) }}, {{ o_data.prosrc_c|qtLiteral(conn) }}{% else %}
$BODY${{ o_data.prosrc }}$BODY${% endif -%};
{% endif -%}
{% if data.funcowner %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
OWNER TO {{ conn|qtIdent(data.funcowner) }};
{% endif -%}
{# The SQL generated below will change priviledges #}
{% if data.acl %}
{% if 'deleted' in data.acl %}
{% for priv in data.acl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in data.acl %}
{% for priv in data.acl.changed %}
{% if priv.grantee != priv.old_grantee %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.old_grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% else %}
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
{% endif %}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in data.acl %}
{% for priv in data.acl.added %}
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}{% endif -%}
{% endif -%}
{% if data.change_func == False %}
{% if data.variables %}
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames) }}
{% endif -%}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames) }}
{% endif -%}
{% endif -%}
{% endif -%}
{% set seclabels = data.seclabels %}
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
{% for r in seclabels.deleted %}
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'added' in seclabels and seclabels.added|length > 0 %}
{% for r in seclabels.added %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
{% for r in seclabels.changed %}
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
{% endfor %}
{% endif -%}
{% if data.description is defined and data.description != o_data.description%}
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
IS {{ data.description|qtLiteral(conn) }};
{% endif -%}
{% if data.pronamespace %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
{% endif -%}
{% endif %}

View File

@@ -3,6 +3,12 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% set exclude_quoting = ['search_path'] %}
{% set set_variables = [] %}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{% set set_variables = data.merged_variables %}
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
{% set set_variables = o_data.variables %}
{% endif %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
@@ -36,7 +42,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if d
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif %}
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
{% endif %}

View File

@@ -3,6 +3,12 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% set exclude_quoting = ['search_path'] %}
{% set set_variables = [] %}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{% set set_variables = data.merged_variables %}
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
{% set set_variables = o_data.variables %}
{% endif %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
@@ -36,7 +42,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if d
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif %}
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
{% endif %}

View File

@@ -3,6 +3,12 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% set exclude_quoting = ['search_path'] %}
{% set set_variables = [] %}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{% set set_variables = data.merged_variables %}
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
{% set set_variables = o_data.variables %}
{% endif %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
@@ -34,7 +40,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if d
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows and data.prorows != '0' %}
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
{% endif %}

View File

@@ -3,6 +3,12 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% set exclude_quoting = ['search_path'] %}
{% set set_variables = [] %}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{% set set_variables = data.merged_variables %}
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
{% set set_variables = o_data.variables %}
{% endif %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
@@ -36,7 +42,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if d
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif %}
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
{% endif %}

View File

@@ -3,6 +3,12 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% set exclude_quoting = ['search_path'] %}
{% set set_variables = [] %}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{% set set_variables = data.merged_variables %}
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
{% set set_variables = o_data.variables %}
{% endif %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
@@ -36,7 +42,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if d
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif %}
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
{% endif %}

View File

@@ -3,6 +3,12 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
{% set name = o_data.name %}
{% set exclude_quoting = ['search_path'] %}
{% set set_variables = [] %}
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
{% set set_variables = data.merged_variables %}
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
{% set set_variables = o_data.variables %}
{% endif %}
{% if data.name %}
{% if data.name != o_data.name %}
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
@@ -34,7 +40,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if d
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows and data.prorows != '0' %}
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif -%}{% if data.merged_variables %}{% for v in data.merged_variables %}
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
{% endif %}

View File

@@ -57,6 +57,8 @@ class SchemaDiffTableCompare(SchemaDiffObjectCompare):
'scid': kwargs.get('target_scid')}
ignore_owner = kwargs.get('ignore_owner')
ignore_whitespaces = kwargs.get('ignore_whitespaces')
ignore_tablespace = kwargs.get('ignore_tablespace')
ignore_grants = kwargs.get('ignore_grants')
group_name = kwargs.get('group_name')
source_schema_name = kwargs.get('source_schema_name', None)
@@ -90,7 +92,9 @@ class SchemaDiffTableCompare(SchemaDiffObjectCompare):
ignore_keys=self.keys_to_ignore,
source_schema_name=source_schema_name,
ignore_owner=ignore_owner,
ignore_whitespaces=ignore_whitespaces)
ignore_whitespaces=ignore_whitespaces,
ignore_tablespace=ignore_tablespace,
ignore_grants=ignore_grants)
def ddl_compare(self, **kwargs):
"""

View File

@@ -0,0 +1,105 @@
{% import 'macros/schemas/security.macros' as SECLABEL %}
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %}
-- WARNING:
-- We have found the difference in either of Type or SubType or Collation,
-- so we need to drop the existing type first and re-create it.
DROP TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }} CASCADE;
{## If user selected shell type then just create type template ##}
{% if data and data.typtype == 'p' %}
CREATE TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }};
{% endif %}
{### Composite Type ###}
{% if data and data.typtype == 'c' %}
{% if data.composite %}{% set typinput = data.typinput %}{% elif o_data.typinput %}{% set typinput = o_data.typinput %}{% endif %}
CREATE TYPE {% if o_data.schema %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% else %}{{ conn|qtIdent(o_data.name) }}{% endif %} AS
({{"\n\t"}}{% if data.composite.added %}{% for d in data.composite.added %}{% if loop.index != 1 %},{{"\n\t"}}{% endif %}{{ conn|qtIdent(d.member_name) }} {% if is_sql %}{{ d.fulltype }}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, d.cltype, d.tlength, d.precision, d.hasSqrBracket) }}{% endif %}{% if d.collation %} COLLATE {{d.collation}}{% endif %}{% endfor %}{% endif %}{{"\n"}});
{% endif %}
{### Enum Type ###}
{% if data and data.typtype == 'e' %}
CREATE TYPE {% if o_data.schema %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% else %}{{ conn|qtIdent(o_data.name) }}{% endif %} AS ENUM
({% for e in data.enum.added %}{% if loop.index != 1 %}, {% endif %}{{ e.label|qtLiteral(conn) }}{% endfor %});
{% endif %}
{### Range Type ###}
{% if data and (data.typtype == 'r' or (data.typtype is not defined and o_data.typtype == 'r')) %}
{% if data.typname %}{% set typname = data.typname %}{% elif o_data.typname %}{% set typname = o_data.typname %}{% endif %}
CREATE TYPE {% if o_data.schema %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% else %}{{ conn|qtIdent(o_data.name) }}{% endif %} AS RANGE
(
{% if typname %}SUBTYPE={{ conn|qtTypeIdent(typname) }}{% endif %}{% if data.collname %},
COLLATION = {{ data.collname }}{% endif %}{% if data.opcname %},
SUBTYPE_OPCLASS = {{ data.opcname }}{% endif %}{% if data.rngcanonical %},
CANONICAL = {{ data.rngcanonical }}{% endif %}{% if data.rngsubdiff %},
SUBTYPE_DIFF = {{ data.rngsubdiff }}{% endif %}
);
{% endif %}
{### External Type ###}
{% if data and (data.typtype == 'b' or (data.typtype is not defined and o_data.typtype == 'b')) %}
{% if data.typinput %}{% set typinput = data.typinput %}{% elif o_data.typinput %}{% set typinput = o_data.typinput %}{% endif %}
{% if data.typoutput %}{% set typoutput = data.typoutput %}{% elif o_data.typoutput %}{% set typoutput = o_data.typoutput %}{% endif %}
CREATE TYPE {% if o_data.schema %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% else %}{{ conn|qtIdent(o_data.name) }}{% endif %}
(
{% if typinput %}INPUT = {{ typinput }}{% endif %}{% if typoutput %},
OUTPUT = {{ typoutput }}{% endif %}{% if data.typreceive %},
RECEIVE = {{data.typreceive}}{% endif %}{% if data.typsend %},
SEND = {{data.typsend}}{% endif %}{% if data.typmodin %},
TYPMOD_IN = {{data.typmodin}}{% endif %}{% if data.typmodout %},
TYPMOD_OUT = {{data.typmodout}}{% endif %}{% if data.typanalyze %},
ANALYZE = {{data.typanalyze}}{% endif %}{% if data.typlen %},
INTERNALLENGTH = {{data.typlen}}{% endif %}{% if data.typbyval %},
PASSEDBYVALUE{% endif %}{% if data.typalign %},
ALIGNMENT = {{data.typalign}}{% endif %}{% if data.typstorage %},
STORAGE = {{data.typstorage}}{% endif %}{% if data.typcategory %},
CATEGORY = {{data.typcategory|qtLiteral(conn)}}{% endif %}{% if data.typispreferred %},
PREFERRED = {{data.typispreferred}}{% endif %}{% if data.typdefault %},
DEFAULT = {{data.typdefault|qtLiteral(conn)}}{% endif %}{% if data.element %},
ELEMENT = {{data.element}}{% endif %}{% if data.typdelim %},
DELIMITER = {{data.typdelim|qtLiteral(conn)}}{% endif %}{% if data.is_collatable %},
COLLATABLE = {{data.is_collatable}}{% endif %}
);
{% endif %}
{### Type Owner ###}
{% if data and (data.typeowner or o_data.typeowner)%}
ALTER TYPE {% if o_data.schema %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% else %}{{ conn|qtIdent(o_data.name) }}{% endif %}
OWNER TO {% if data.typeowner %}{{ conn|qtIdent(data.typeowner) }}{% elif o_data.typeowner %}{{ conn|qtIdent(o_data.typeowner) }}{% endif %};
{% endif %}
{### Type Comments ###}
{% if data and data.description %}
COMMENT ON TYPE {% if o_data.schema %}{{ conn|qtIdent(o_data.schema, o_data.name) }}{% else %}{{ conn|qtIdent(o_data.name) }}{% endif %}
IS {{data.description|qtLiteral(conn)}};
{% endif %}
{### ACL ###}
{% if data.typacl and data.typacl|length > 0 %}
{% if 'deleted' in data.typacl %}
{% for priv in data.typacl.deleted %}
{{ PRIVILEGE.UNSETALL(conn, 'TYPE', priv.grantee, o_data.name, o_data.schema) }}
{% endfor %}
{% endif %}
{% if 'changed' in data.typacl %}
{% for priv in data.typacl.changed %}
{{ PRIVILEGE.UNSETALL(conn, 'TYPE', priv.grantee, o_data.name, o_data.schema) }}
{{ PRIVILEGE.SET(conn, 'TYPE', priv.grantee, o_data.name, priv.without_grant, priv.with_grant, o_data.schema) }}
{% endfor %}
{% endif %}
{% if 'added' in data.typacl %}
{% for priv in data.typacl.added %}
{{ PRIVILEGE.SET(conn, 'TYPE', priv.grantee, o_data.name, priv.without_grant, priv.with_grant, o_data.schema) }}
{% endfor %}
{% endif %}
{% endif %}
{### Security Lables ###}
{% if data.seclabels %}
{% for r in data.seclabels %}
{% if r.provider and r.label %}
{{ SECLABEL.SET(conn, 'TYPE', o_data.name, r.provider, r.label, o_data.schema) }}
{% endif %}
{% endfor %}
{% endif %}