mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-25 10:10:19 -06:00
Fixed following issue of schema diff tool:
1. Comparison result of 2 exact identical Trigger Functions is different 2. EPAS 12: Table comparison with the compound trigger shown as different, but all SQL panels are blank 3. Compound trigger properties panel is not opening 4. The DDL difference of the table containing the foreign key is not accurate 5. The DDL difference of the view which refers the table from schema is not accurate 6. DDL comparison fails if we have procedure with plpgsql in source and edbsql in target
This commit is contained in:
parent
210bbfdbe1
commit
3b1c8abd2f
@ -1146,13 +1146,13 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
data['pronamespace'] = self._get_schema(
|
||||
data['pronamespace']
|
||||
)
|
||||
if 'provolatile' in data:
|
||||
if 'provolatile' in data and data['provolatile']:
|
||||
data['provolatile'] = vol_dict[data['provolatile']]
|
||||
|
||||
if fnid is not None:
|
||||
# Edit Mode
|
||||
|
||||
if 'proparallel' in data:
|
||||
if 'proparallel' in data and data['proparallel']:
|
||||
data['proparallel'] = parallel_dict[data['proparallel']]
|
||||
|
||||
# Fetch Old Data from database.
|
||||
|
@ -31,7 +31,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}()
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if 'probin' in data or 'prosrc_c' in data %}
|
||||
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 }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
|
@ -30,7 +30,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}()
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if 'probin' in data or 'prosrc_c' in data %}
|
||||
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 }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
|
@ -31,7 +31,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}()
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if 'probin' in data or 'prosrc_c' in data %}
|
||||
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 }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
|
@ -29,7 +29,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}()
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if 'probin' in data or 'prosrc_c' in data %}
|
||||
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 }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
|
@ -30,7 +30,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}()
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if 'probin' in data or 'prosrc_c' in data %}
|
||||
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 }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
|
@ -31,7 +31,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}()
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if 'probin' in data or 'prosrc_c' in data %}
|
||||
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 }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
|
@ -29,7 +29,7 @@ CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}()
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if 'probin' in data or 'prosrc_c' in data %}
|
||||
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 }}{% else %}{{ o_data.probin|qtLiteral }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral }}{% else %}{{ o_data.prosrc_c|qtLiteral }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral }}, {{ o_data.prosrc_c|qtLiteral }}{% else %}
|
||||
|
@ -13,7 +13,7 @@ import simplejson as json
|
||||
from functools import wraps
|
||||
|
||||
import pgadmin.browser.server_groups.servers.databases as database
|
||||
from flask import render_template, request, jsonify
|
||||
from flask import render_template, request, jsonify, current_app
|
||||
from flask_babelex import gettext
|
||||
from pgadmin.browser.collection import CollectionNodeModule
|
||||
from pgadmin.browser.utils import PGChildNodeView
|
||||
@ -30,6 +30,7 @@ from pgadmin.utils.compile_template_name import compile_template_path
|
||||
from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry
|
||||
from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare
|
||||
|
||||
|
||||
# If we are in Python3
|
||||
if not IS_PY2:
|
||||
unicode = str
|
||||
@ -431,10 +432,14 @@ class CompoundTriggerView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
JSON of selected compound trigger node
|
||||
"""
|
||||
|
||||
data = self._fetch_properties(tid, trid)
|
||||
status, data = self._fetch_properties(tid, trid)
|
||||
|
||||
if not status:
|
||||
return data
|
||||
return internal_server_error(errormsg=data)
|
||||
|
||||
if 'rows' in data and len(data['rows']) == 0:
|
||||
return gone(gettext(
|
||||
"""Could not find the compound trigger in the table."""))
|
||||
|
||||
return ajax_response(
|
||||
response=data,
|
||||
@ -451,11 +456,10 @@ class CompoundTriggerView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
return status, res
|
||||
|
||||
if len(res['rows']) == 0:
|
||||
return gone(gettext(
|
||||
"""Could not find the compound trigger in the table."""))
|
||||
return True, res
|
||||
|
||||
# Making copy of output for future use
|
||||
data = dict(res['rows'][0])
|
||||
@ -876,7 +880,10 @@ class CompoundTriggerView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
def get_sql_from_diff(self, gid, sid, did, scid, tid, oid,
|
||||
data=None, diff_schema=None, drop_sql=False):
|
||||
if data:
|
||||
sql, name = self.get_sql(scid, tid, oid, data)
|
||||
sql, name = compound_trigger_utils.get_sql(self.conn,
|
||||
data,
|
||||
tid, oid,
|
||||
self.datlastsysoid)
|
||||
if not isinstance(sql, (str, unicode)):
|
||||
return sql
|
||||
sql = sql.strip('\n').strip(' ')
|
||||
@ -908,21 +915,16 @@ class CompoundTriggerView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
columns = ', '.join(data['tgattr'].split(' '))
|
||||
data['columns'] = self._column_details(tid, columns)
|
||||
|
||||
data = self._trigger_definition(data)
|
||||
data = trigger_definition(data)
|
||||
|
||||
if diff_schema:
|
||||
data['schema'] = diff_schema
|
||||
|
||||
SQL, name = self.get_sql(scid, tid, None, data)
|
||||
|
||||
sql_header = u"-- Compound Trigger: {0}\n\n-- ".format(
|
||||
data['name'])
|
||||
|
||||
sql_header += render_template("/".join([self.template_path,
|
||||
'delete.sql']),
|
||||
data=data, conn=self.conn)
|
||||
|
||||
SQL = sql_header + '\n\n' + SQL.strip('\n')
|
||||
SQL, name = compound_trigger_utils.get_sql(self.conn,
|
||||
data,
|
||||
tid,
|
||||
None,
|
||||
self.datlastsysoid)
|
||||
|
||||
# If compound trigger is disbaled then add sql
|
||||
# code for the same
|
||||
|
@ -275,8 +275,21 @@ def get_sql(conn, data, tid, fkid=None, template_path=None):
|
||||
# Get the parent schema and table.
|
||||
schema, table = get_parent(conn,
|
||||
data['columns'][0]['references'])
|
||||
data['remote_schema'] = schema
|
||||
data['remote_table'] = table
|
||||
|
||||
# Below handling will be used in Schema diff in case
|
||||
# of different database comparison
|
||||
|
||||
if schema and table:
|
||||
data['remote_schema'] = schema
|
||||
data['remote_table'] = table
|
||||
|
||||
if 'remote_schema' not in data:
|
||||
data['remote_schema'] = None
|
||||
elif 'schema' in data and (schema is None or schema == ''):
|
||||
data['remote_schema'] = data['schema']
|
||||
|
||||
if 'remote_table' not in data:
|
||||
data['remote_table'] = None
|
||||
|
||||
sql = render_template("/".join([template_path, 'create.sql']),
|
||||
data=data, conn=conn)
|
||||
|
@ -249,8 +249,7 @@ class TriggerView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
})
|
||||
|
||||
# Schema Diff: Keys to ignore while comparing
|
||||
keys_to_ignore = ['oid', 'xmin', 'nspname', 'tfunction',
|
||||
'tgrelid', 'tgfoid', 'prosrc']
|
||||
keys_to_ignore = ['oid', 'xmin', 'nspname', 'tgrelid', 'tgfoid', 'prosrc']
|
||||
|
||||
def check_precondition(f):
|
||||
"""
|
||||
|
@ -1145,6 +1145,9 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare):
|
||||
|
||||
result = res['rows'][0]
|
||||
if diff_schema:
|
||||
result['definition'] = result['definition'].replace(
|
||||
result['schema'],
|
||||
diff_schema)
|
||||
result['schema'] = diff_schema
|
||||
|
||||
# sending result to formtter
|
||||
@ -1753,6 +1756,9 @@ class MViewNode(ViewNode, VacuumSettings):
|
||||
result = res['rows'][0]
|
||||
|
||||
if diff_schema:
|
||||
result['definition'] = result['definition'].replace(
|
||||
result['schema'],
|
||||
diff_schema)
|
||||
result['schema'] = diff_schema
|
||||
|
||||
# sending result to formtter
|
||||
|
@ -230,8 +230,9 @@ export default class SchemaDiffUI {
|
||||
server_data['database'] = data.database;
|
||||
|
||||
if (_.isUndefined(generated_script)) {
|
||||
generated_script = gettext('-- The generated script does not include the dependency resolution currently, so it may fail in case of dependency. \n');
|
||||
generated_script += gettext('-- Please report an issue at https://redmine.postgresql.org/projects/pgadmin4/issues/new \n');
|
||||
generated_script = gettext('-- This script is generated by \'Schema Diff\' utility of pgAdmin 4. \n');
|
||||
generated_script += gettext('-- It does not include the dependency resolution logic, hence - it may not be able to resolve some dependent database object differences. \n');
|
||||
generated_script += gettext('-- Please report an issue for any failure with the reproduction steps. \n');
|
||||
|
||||
generated_script += 'BEGIN;' + '\n' + self.model.get('diff_ddl') + '\n' + 'END;';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user