diff --git a/docs/en_US/dbms_job_scheduler.rst b/docs/en_US/dbms_job_scheduler.rst index b5022fb7c74..edd8c4310c3 100644 --- a/docs/en_US/dbms_job_scheduler.rst +++ b/docs/en_US/dbms_job_scheduler.rst @@ -15,9 +15,9 @@ as a background process for the DBMS_SCHEDULER and DBMS_JOB packages. The EDB Job Scheduler has a scheduler process that starts when the database cluster starts. To start the scheduler process, load the EDB Job Scheduler extension using the **shared_preload_libraries** -parameter. After you load the extension, create the extension using the CREATE EXTENSION command. -The database in which you're creating the extension must be listed in the **edb_job_scheduler.database_list** -parameter. +parameter. After you load the extension, create the extension **'edb_job_scheduler'** and **'dbms_scheduler'** using +the CREATE EXTENSION command. The database in which you're creating the extension must be listed in the +**edb_job_scheduler.database_list** parameter. Instructions for configuring the EDB Job Scheduler can be found in the `Configuring EDB Job Scheduler `_. diff --git a/docs/en_US/release_notes_8_5.rst b/docs/en_US/release_notes_8_5.rst index 93ba775a26a..210c57e102a 100644 --- a/docs/en_US/release_notes_8_5.rst +++ b/docs/en_US/release_notes_8_5.rst @@ -20,8 +20,8 @@ Bundled PostgreSQL Utilities New features ************ + | `Issue #5611 `_ - Added support for provider, deterministic, version and RULES parameter while creating collation. | `Issue #7098 `_ - Added support for EDB Job Scheduler. - | `Issue #7163 `_ - Added support to exclude multiple tables while taking backup. | `Issue #7221 `_ - Added support for UNIX socket in entrypoint.sh for Docker implementation. Housekeeping @@ -31,12 +31,16 @@ Housekeeping Bug fixes ********* + | `Issue #4413 `_ - Fixed an issue in Schema Diff where Columns with sequences get altered unnecessarily. | `Issue #7116 `_ - Bug fixes and improvements in pgAdmin CLI. | `Issue #7165 `_ - Fixed schema diff wrong query generation for table, foreign table and sequence. | `Issue #7229 `_ - Fix an issue in table dialog where changing column name was not syncing table constraints appropriately. + | `Issue #7255 `_ - Fixed an issue where taking backup of a shared server was using server owner's user name. | `Issue #7262 `_ - Fix an issue in editor where replace option in query tool edit menu is not working on non-Mac OS. | `Issue #7268 `_ - Fix an issue in editor where Format SQL shortcut and multiline selection are not working. | `Issue #7269 `_ - Fix an issue in editor where "Use Spaces?" Preference of Editor is not working. + | `Issue #7271 `_ - Fixed an issue where Triggers, Rules, Indexes were absent from the Schema Diff when comparing views. | `Issue #7277 `_ - Fix an issue in query tool where toggle case of selected text loses selection. | `Issue #7299 `_ - Fix query tool autocomplete results when cursor is in between the SQL query. | `Issue #7305 `_ - Fix an issue in query tool where custom keyboard shortcuts are not working for some. + | `Issue #7308 `_ - Fixed issue related to email authentication of Two-factor authentication. diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py index 64fc9e23195..302fe1a2a42 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py @@ -24,7 +24,7 @@ from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry from pgadmin.browser.server_groups.servers.databases.schemas.tables.\ constraints.foreign_key import utils as fkey_utils -from .schema_diff_utils import SchemaDiffTableCompare +from .schema_diff_table_utils import SchemaDiffTableCompare from pgadmin.browser.server_groups.servers.databases.schemas.tables.\ columns import utils as column_utils from pgadmin.browser.server_groups.servers.databases.schemas.tables.\ diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/schema_diff_utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/schema_diff_table_utils.py similarity index 99% rename from web/pgadmin/browser/server_groups/servers/databases/schemas/tables/schema_diff_utils.py rename to web/pgadmin/browser/server_groups/servers/databases/schemas/tables/schema_diff_table_utils.py index da6fbf2cf57..d0eded3e81a 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/schema_diff_utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/schema_diff_table_utils.py @@ -25,7 +25,7 @@ class SchemaDiffTableCompare(SchemaDiffObjectCompare): 'relacl_str', 'setting'] column_keys_to_ignore = ['atttypid', 'edit_types', 'elemoid', 'seqrelid', - 'indkey'] + 'indkey', 'seqtypid', 'defval'] constraint_keys_to_ignore = ['relname', 'nspname', 'parent_tbl', 'attrelid', 'adrelid', 'fknsp', 'confrelid', diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/rules/sql/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/rules/sql/nodes.sql index 9fc9323d439..7e8e47e14a0 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/rules/sql/nodes.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/rules/sql/nodes.sql @@ -14,6 +14,7 @@ WHERE rw.oid = {{ rid }} {% endif %} {% if schema_diff %} + AND rw.rulename != '_RETURN' AND CASE WHEN (SELECT COUNT(*) FROM pg_catalog.pg_depend WHERE objid = rw.oid AND deptype = 'e') > 0 THEN FALSE ELSE TRUE END {% endif %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py index 3f040ea60f9..05e981a215d 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py @@ -546,7 +546,6 @@ def fetch_tables(self, sid, did, scid, tid=None, with_serial_cols=False): BaseTableView._get_sub_module_data_for_compare( self, sid, did, scid, data, row) res[row['name']] = data - res[row['name']] = data return True, res diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/__init__.py index 93784545a82..4a6e2ff8e51 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/__init__.py @@ -28,7 +28,7 @@ make_response as ajax_response, gone from pgadmin.utils.driver import get_driver from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry -from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare +from .schema_diff_view_utils import SchemaDiffViewCompare from pgadmin.utils import html, does_utility_exist, get_server from pgadmin.model import Server from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc @@ -260,6 +260,24 @@ def wrap(*args, **kwargs): self.column_template_path = 'columns/sql/#{0}#'.format( self.manager.version) + # Template for trigger node + self.trigger_template_path = 'triggers/sql/{0}/#{1}#'.format( + self.manager.server_type, self.manager.version) + + # Template for compound trigger node + self.compound_trigger_template_path = ( + 'compound_triggers/sql/{0}/#{1}#'.format( + self.manager.server_type, self.manager.version)) + + # Template for rules node + self.rules_template_path = 'rules/sql' + + # Submodule list for schema diff + self.view_sub_modules = ['rule', 'trigger'] + if (self.manager.server_type == 'ppas' and + self.manager.version >= 120000): + self.view_sub_modules.append('compound_trigger') + try: self.allowed_acls = render_template( "/".join([self.template_path, self._ALLOWED_PRIVS_JSON]) @@ -273,7 +291,7 @@ def wrap(*args, **kwargs): return wrap -class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare): +class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffViewCompare): """ This class is responsible for generating routes for view node. @@ -374,8 +392,6 @@ class ViewNode(PGChildNodeView, VacuumSettings, SchemaDiffObjectCompare): {'get': 'get_toast_table_vacuum'}] }) - keys_to_ignore = ['oid', 'schema', 'xmin', 'oid-2', 'setting'] - def __init__(self, *args, **kwargs): """ Initialize the variables used by methods of ViewNode. @@ -510,7 +526,7 @@ def _fetch_properties(self, scid, vid): # sending result to formtter frmtd_reslt = self.formatter(result) - # merging formated result with main result again + # merging formatted result with main result again result.update(frmtd_reslt) return True, result @@ -1140,7 +1156,8 @@ def _generate_and_return_trigger_sql(self, vid, data, display_comments, [self.ct_trigger_temp_path, 'sql/{0}/#{1}#/create.sql'.format( self.manager.server_type, self.manager.version)]), - data=res_rows, display_comments=display_comments) + data=res_rows, display_comments=display_comments, + conn=self.conn) sql_data += '\n' sql_data += SQL @@ -1264,7 +1281,8 @@ def get_trigger_sql(self, vid, display_comments=True): [self.trigger_temp_path, 'sql/{0}/#{1}#/create.sql'.format( self.manager.server_type, self.manager.version)]), - data=res_rows, display_comments=display_comments) + data=res_rows, display_comments=display_comments, + conn=self.conn) sql_data += '\n' sql_data += SQL @@ -1310,7 +1328,8 @@ def get_index_sql(self, did, vid, display_comments=True): SQL = render_template("/".join( [self.index_temp_path, 'sql/#{0}#/create.sql'.format(self.manager.version)]), - data=data, display_comments=display_comments) + data=data, display_comments=display_comments, + conn=self.conn) sql_data += '\n' sql_data += SQL return sql_data @@ -1680,6 +1699,19 @@ def insert_sql(self, gid, sid, did, scid, vid): return ajax_response(response=sql) + def _get_sub_module_data_for_compare(self, sid, did, scid, data, vid): + # Get sub module data of a specified view for object + # comparison + for module in self.view_sub_modules: + module_view = SchemaDiffRegistry.get_node_view(module) + if module_view.blueprint.server_type is None or \ + self.manager.server_type in \ + module_view.blueprint.server_type: + sub_data = module_view.fetch_objects_to_compare( + sid=sid, did=did, scid=scid, tid=vid, + oid=None) + data[module] = sub_data + @check_precondition def fetch_objects_to_compare(self, sid, did, scid, oid=None): """ @@ -1707,6 +1739,9 @@ def fetch_objects_to_compare(self, sid, did, scid, oid=None): for row in views['rows']: status, data = self._fetch_properties(scid, row['oid']) if status: + # Fetch the data of sub module + self._get_sub_module_data_for_compare( + sid, did, scid, data, row['oid']) res[row['name']] = data else: status, data = self._fetch_properties(scid, oid) @@ -1717,7 +1752,7 @@ def fetch_objects_to_compare(self, sid, did, scid, oid=None): return res - def get_sql_from_diff(self, **kwargs): + def get_sql_from_view_diff(self, **kwargs): """ This function is used to get the DDL/DML statements. :param kwargs @@ -1727,15 +1762,15 @@ def get_sql_from_diff(self, **kwargs): sid = kwargs.get('sid') did = kwargs.get('did') scid = kwargs.get('scid') - oid = kwargs.get('oid') - data = kwargs.get('data', None) + oid = kwargs.get('tid') + diff_data = kwargs.get('diff_data', None) drop_sql = kwargs.get('drop_sql', False) target_schema = kwargs.get('target_schema', None) - if data: + if diff_data: if target_schema: - data['schema'] = target_schema - sql, _ = self.getSQL(gid, sid, did, data, oid) + diff_data['schema'] = target_schema + sql, _ = self.getSQL(gid, sid, did, diff_data, oid) if sql.find('DROP VIEW') != -1: sql = gettext(""" -- Changing the columns in a view requires dropping and re-creating the view. @@ -1755,6 +1790,60 @@ def get_sql_from_diff(self, **kwargs): json_resp=False) return sql + def get_submodule_template_path(self, module_name): + """ + This function is used to get the template path based on module name. + :param module_name: + :return: + """ + template_path = None + if module_name == 'trigger': + template_path = self.trigger_template_path + elif module_name == 'rule': + template_path = self.rules_template_path + elif module_name == 'compound_trigger': + template_path = self.compound_trigger_template_path + + return template_path + + def get_view_submodules_dependencies(self, **kwargs): + """ + This function is used to get the dependencies of view and it's + submodules. + :param kwargs: + :return: + """ + vid = kwargs['tid'] + view_dependencies = [] + view_deps = self.get_dependencies(self.conn, vid) + if len(view_deps) > 0: + view_dependencies.extend(view_deps) + + # Iterate all the submodules of the table and fetch the dependencies. + for module in self.view_sub_modules: + module_view = SchemaDiffRegistry.get_node_view(module) + template_path = self.get_submodule_template_path(module) + + SQL = render_template("/".join([template_path, + 'nodes.sql']), tid=vid) + status, rset = self.conn.execute_2darray(SQL) + if not status: + return internal_server_error(errormsg=rset) + + for row in rset['rows']: + result = module_view.get_dependencies( + self.conn, row['oid'], where=None, + show_system_objects=None, is_schema_diff=True) + if len(result) > 0: + view_dependencies.extend(result) + + # Remove the same table from the dependency list + for item in view_dependencies: + if 'oid' in item and item['oid'] == vid: + view_dependencies.remove(item) + + return view_dependencies + # Override the operations for materialized view mview_operations = { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/schema_diff_view_utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/schema_diff_view_utils.py new file mode 100644 index 00000000000..8d938ec355c --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/schema_diff_view_utils.py @@ -0,0 +1,238 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2024, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +""" Implements Utility class for View.""" + +import copy + +from pgadmin.utils.ajax import internal_server_error +from pgadmin.tools.schema_diff.directory_compare import compare_dictionaries,\ + are_dictionaries_identical +from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare +from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry + + +class SchemaDiffViewCompare(SchemaDiffObjectCompare): + view_keys_to_ignore = ['oid', 'schema', 'xmin', 'oid-2', 'setting'] + + trigger_keys_to_ignore = ['xmin', 'tgrelid', 'tgfoid', 'tfunction', + 'tgqual', 'tgconstraint', 'nspname'] + + keys_to_ignore = view_keys_to_ignore + trigger_keys_to_ignore + + def compare(self, **kwargs): + """ + This function is used to compare all the table objects + from two different schemas. + + :param kwargs: + :return: + """ + source_params = {'sid': kwargs.get('source_sid'), + 'did': kwargs.get('source_did'), + 'scid': kwargs.get('source_scid')} + target_params = {'sid': kwargs.get('target_sid'), + 'did': kwargs.get('target_did'), + '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) + source_views = {} + target_views = {} + + status, target_schema = self.get_schema(**target_params) + if not status: + return internal_server_error(errormsg=target_schema) + + if 'scid' in source_params and source_params['scid'] is not None: + source_views = self.fetch_objects_to_compare(**source_params) + + if 'scid' in target_params and target_params['scid'] is not None: + target_views = self.fetch_objects_to_compare(**target_params) + + # If both the dict have no items then return None. + if not (source_views or target_views) or ( + len(source_views) <= 0 and len(target_views) <= 0): + return None + + return compare_dictionaries(view_object=self, + source_params=source_params, + target_params=target_params, + target_schema=target_schema, + source_dict=source_views, + target_dict=target_views, + node=self.node_type, + node_label=self.blueprint.collection_label, + group_name=group_name, + ignore_keys=self.keys_to_ignore, + source_schema_name=source_schema_name, + ignore_owner=ignore_owner, + ignore_whitespaces=ignore_whitespaces, + ignore_tablespace=ignore_tablespace, + ignore_grants=ignore_grants) + + def ddl_compare(self, **kwargs): + """ + This function will compare properties of 2 views and + return the source DDL, target DDL and Difference of them. + + :param kwargs: + :return: + """ + source_params = {'sid': kwargs.get('source_sid'), + 'did': kwargs.get('source_did'), + 'scid': kwargs.get('source_scid'), + 'tid': kwargs.get('source_oid') + } + + target_params = {'sid': kwargs.get('target_sid'), + 'did': kwargs.get('target_did'), + 'scid': kwargs.get('target_scid'), + 'tid': kwargs.get('target_oid') + } + + source = self.get_sql_from_view_diff(**source_params) + target = self.get_sql_from_view_diff(**target_params) + + return {'source_ddl': source, + 'target_ddl': target, + 'diff_ddl': '' + } + + def get_sql_from_submodule_diff(self, **kwargs): + """ + This function returns the DDL/DML statements of the + submodules of table based on the comparison status. + + :param kwargs: + :return: + """ + source_params = kwargs.get('source_params') + target_params = kwargs.get('target_params') + target_schema = kwargs.get('target_schema') + source = kwargs.get('source') + target = kwargs.get('target') + diff_dict = kwargs.get('diff_dict') + ignore_whitespaces = kwargs.get('ignore_whitespaces') + diff = '' + + # Get the difference DDL/DML statements for table + if isinstance(diff_dict, dict) and len(diff_dict) > 0: + target_params['diff_data'] = diff_dict + diff = self.get_sql_from_view_diff(**target_params) + + ignore_sub_modules = ['column', 'index'] + if self.manager.server_type == 'pg' or self.manager.version < 120000: + ignore_sub_modules.append('compound_trigger') + + # Iterate through all the sub modules of the table + for module in self.blueprint.submodules: + if module.node_type not in ignore_sub_modules: + module_view = \ + SchemaDiffRegistry.get_node_view(module.node_type) + + dict1 = copy.deepcopy(source[module.node_type]) + dict2 = copy.deepcopy(target[module.node_type]) + + # Find the duplicate keys in both the dictionaries + dict1_keys = set(dict1.keys()) + dict2_keys = set(dict2.keys()) + intersect_keys = dict1_keys.intersection(dict2_keys) + + # Keys that are available in source and missing in target. + added = dict1_keys - dict2_keys + diff = SchemaDiffViewCompare._compare_source_only( + added, module_view, source_params, target_params, + dict1, diff, target_schema) + + # Keys that are available in target and missing in source. + removed = dict2_keys - dict1_keys + diff = SchemaDiffViewCompare._compare_target_only( + removed, module_view, source_params, target_params, + dict2, diff, target_schema) + + # Keys that are available in both source and target. + other_param = { + "dict1": dict1, + "dict2": dict2, + "source": source, + "target": target, + "target_schema": target_schema, + "ignore_whitespaces": ignore_whitespaces + } + diff = self._compare_source_and_target( + intersect_keys, module_view, source_params, + target_params, diff, **other_param) + + return diff + + @staticmethod + def _compare_source_only(added, module_view, source_params, target_params, + dict1, diff, target_schema): + for item in added: + source_ddl = module_view.ddl_compare( + source_params=source_params, + target_params=target_params, + target_schema=target_schema, + source=dict1[item], + target=None, + comp_status='source_only' + ) + + diff += '\n' + source_ddl + return diff + + @staticmethod + def _compare_target_only(removed, module_view, source_params, + target_params, dict2, diff, target_schema): + for item in removed: + target_ddl = module_view.ddl_compare( + source_params=source_params, + target_params=target_params, + target_schema=target_schema, + source=None, + target=dict2[item], + comp_status='target_only' + ) + + diff += '\n' + target_ddl + return diff + + def _compare_source_and_target(self, intersect_keys, module_view, + source_params, target_params, diff, + **kwargs): + dict1 = kwargs['dict1'] + dict2 = kwargs['dict2'] + source = kwargs['source'] + target = kwargs['target'] + target_schema = kwargs['target_schema'] + ignore_whitespaces = kwargs.get('ignore_whitespaces') + + for key in intersect_keys: + # Recursively Compare the two dictionary + if not are_dictionaries_identical( + dict1[key], dict2[key], self.keys_to_ignore, + ignore_whitespaces): + diff_ddl = module_view.ddl_compare( + source_params=source_params, + target_params=target_params, + target_schema=target_schema, + source=dict1[key], + target=dict2[key], + comp_status='different', + parent_source_data=source, + parent_target_data=target + ) + + diff += '\n' + diff_ddl + return diff diff --git a/web/pgadmin/tools/schema_diff/directory_compare.py b/web/pgadmin/tools/schema_diff/directory_compare.py index 8408e139681..1fe42b90556 100644 --- a/web/pgadmin/tools/schema_diff/directory_compare.py +++ b/web/pgadmin/tools/schema_diff/directory_compare.py @@ -58,18 +58,29 @@ def _get_source_list(**kwargs): if 'oid' in source_dict[item]: source_object_id = source_dict[item]['oid'] - if node == 'table': + if node == 'table' or node == 'view': temp_src_params = copy.deepcopy(source_params) temp_src_params['tid'] = source_object_id temp_src_params['json_resp'] = False temp_src_params['add_not_exists_clause'] = True - source_ddl = \ - view_object.get_sql_from_table_diff(**temp_src_params) - temp_src_params.update({'target_schema': target_schema}) - diff_ddl = view_object.get_sql_from_table_diff(**temp_src_params) - source_dependencies = \ - view_object.get_table_submodules_dependencies( - **temp_src_params) + if node == 'table': + source_ddl = \ + view_object.get_sql_from_table_diff(**temp_src_params) + temp_src_params.update({'target_schema': target_schema}) + diff_ddl = ( + view_object.get_sql_from_table_diff(**temp_src_params)) + source_dependencies = \ + view_object.get_table_submodules_dependencies( + **temp_src_params) + elif node == 'view': + source_ddl = \ + view_object.get_sql_from_view_diff(**temp_src_params) + temp_src_params.update({'target_schema': target_schema}) + diff_ddl = ( + view_object.get_sql_from_view_diff(**temp_src_params)) + source_dependencies = \ + view_object.get_view_submodules_dependencies( + **temp_src_params) else: temp_src_params = copy.deepcopy(source_params) temp_src_params['oid'] = source_object_id @@ -145,14 +156,23 @@ def _get_target_list(removed, target_dict, node, target_params, view_object, if 'oid' in target_dict[item]: target_object_id = target_dict[item]['oid'] - if node == 'table': + if node == 'table' or node == 'view': temp_tgt_params = copy.deepcopy(target_params) temp_tgt_params['tid'] = target_object_id temp_tgt_params['json_resp'] = False temp_tgt_params['add_not_exists_clause'] = True - target_ddl = view_object.get_sql_from_table_diff(**temp_tgt_params) - _delete_keys(temp_tgt_params) - diff_ddl = view_object.get_drop_sql(**temp_tgt_params) + if node == 'table': + target_ddl = ( + view_object.get_sql_from_table_diff(**temp_tgt_params)) + _delete_keys(temp_tgt_params) + diff_ddl = view_object.get_drop_sql(**temp_tgt_params) + elif node == 'view': + target_ddl = ( + view_object.get_sql_from_view_diff(**temp_tgt_params)) + temp_tgt_params.update( + {'drop_sql': True}) + diff_ddl = ( + view_object.get_sql_from_view_diff(**temp_tgt_params)) else: temp_tgt_params = copy.deepcopy(target_params) temp_tgt_params['oid'] = target_object_id @@ -288,7 +308,7 @@ def _get_identical_and_different_list(intersect_keys, source_dict, target_dict, if 'scid' in target_params else 0, }) else: - if node == 'table': + if node == 'table' or node == 'view': temp_src_params = copy.deepcopy(source_params) temp_tgt_params = copy.deepcopy(target_params) # Add submodules into the ignore keys so that directory @@ -308,16 +328,27 @@ def _get_identical_and_different_list(intersect_keys, source_dict, target_dict, temp_src_params['tid'] = source_object_id temp_tgt_params['tid'] = target_object_id - temp_src_params['json_resp'] = \ - temp_tgt_params['json_resp'] = False - source_ddl = \ - view_object.get_sql_from_table_diff(**temp_src_params) - diff_dependencies = \ - view_object.get_table_submodules_dependencies( - **temp_src_params) - target_ddl = \ - view_object.get_sql_from_table_diff(**temp_tgt_params) + if node == 'table': + temp_src_params['json_resp'] = \ + temp_tgt_params['json_resp'] = False + + source_ddl = \ + view_object.get_sql_from_table_diff(**temp_src_params) + diff_dependencies = \ + view_object.get_table_submodules_dependencies( + **temp_src_params) + target_ddl = \ + view_object.get_sql_from_table_diff(**temp_tgt_params) + elif node == 'view': + source_ddl = \ + view_object.get_sql_from_view_diff(**temp_src_params) + diff_dependencies = \ + view_object.get_view_submodules_dependencies( + **temp_src_params) + target_ddl = \ + view_object.get_sql_from_view_diff(**temp_tgt_params) + diff_ddl = view_object.get_sql_from_submodule_diff( source_params=temp_src_params, target_params=temp_tgt_params, diff --git a/web/pgadmin/tools/schema_diff/static/js/components/InputComponent.jsx b/web/pgadmin/tools/schema_diff/static/js/components/InputComponent.jsx index dd9b1ca09ec..b8af0c8f1e4 100644 --- a/web/pgadmin/tools/schema_diff/static/js/components/InputComponent.jsx +++ b/web/pgadmin/tools/schema_diff/static/js/components/InputComponent.jsx @@ -98,7 +98,7 @@ export function InputComponent({ label, serverList, databaseList, schemaList, di c.value), ',') : null} onChange={changeDatabase} value={selectedDatabase} controlProps={ @@ -114,7 +114,7 @@ export function InputComponent({ label, serverList, databaseList, schemaList, di c.value), ',') : null} onChange={changeSchema} value={selectedSchema} controlProps={