diff --git a/docs/en_US/release_notes_4_17.rst b/docs/en_US/release_notes_4_17.rst index c4d97027a..4a0ae66a1 100644 --- a/docs/en_US/release_notes_4_17.rst +++ b/docs/en_US/release_notes_4_17.rst @@ -14,6 +14,7 @@ New features Housekeeping ************ +| `Issue #4988 `_ - Refactored SQL of Table's and it's child nodes. | `Issue #5017 `_ - Use cheroot as default production server for pgAdmin4. | `Issue #5023 `_ - Refactored SQL of Views and Materialized Views. @@ -23,4 +24,6 @@ Bug fixes | `Issue #4506 `_ - Fix an issue where clicking on an empty textbox like fill factor or comments, considers it as change and enabled the save button. | `Issue #4943 `_ - Added more information to the 'Database connected/disconnected' message. | `Issue #4999 `_ - Rename some internal environment variables that could conflict with Kubernetes. -| `Issue #5004 `_ - Fix vulnerability issues reported by 'yarn audit'. Replace the deprecated uglifyjs-webpack-plugin with a terser-webpack-plugin. \ No newline at end of file +| `Issue #5004 `_ - Fix vulnerability issues reported by 'yarn audit'. Replace the deprecated uglifyjs-webpack-plugin with a terser-webpack-plugin. +| `Issue #5008 `_ - Ensure that the error message should not be displayed if Tablespace is not selected while creating the index. +| `Issue #5009 `_ - Fix an issue where operator, access method and operator class is not visible for exclusion constraints. \ No newline at end of file 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 b6e0b5f20..3fef6e025 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 @@ -26,6 +26,8 @@ from pgadmin.browser.server_groups.servers.databases.schemas.tables.\ constraints.foreign_key import utils as fkey_utils from pgadmin.browser.server_groups.servers.databases.schemas.tables.\ columns import utils as column_utils +from pgadmin.browser.server_groups.servers.databases.schemas.tables.\ + constraints.exclusion_constraint import utils as exclusion_utils class TableModule(SchemaChildModule): @@ -500,20 +502,8 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings): Returns: """ - res = [{'label': '', 'value': ''}] - sql = render_template("/".join([ - self.exclusion_constraint_template_path, 'get_access_methods.sql' - ])) + res = exclusion_utils.get_access_methods(self.conn) - status, rest = self.conn.execute_2darray(sql) - - if not status: - return internal_server_error(errormsg=rest) - - for row in rest['rows']: - res.append( - {'label': row['amname'], 'value': row['amname']} - ) return make_json_response( data=res, status=200 @@ -537,21 +527,9 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings): data = request.args if request.args else None try: if data and 'indextype' in data: - SQL = render_template( - "/".join([ - self.exclusion_constraint_template_path, - 'get_oper_class.sql' - ]), - indextype=data['indextype'] - ) + result = exclusion_utils.get_oper_class( + self.conn, data['indextype']) - status, res = self.conn.execute_2darray(SQL) - - if not status: - return internal_server_error(errormsg=res) - result = [] - for row in res['rows']: - result.append([row['opcname'], row['opcname']]) return make_json_response( data=result, status=200 @@ -577,22 +555,10 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings): data = request.args if request.args else None try: if data and 'col_type' in data: - SQL = render_template( - "/".join([ - self.exclusion_constraint_template_path, - 'get_operator.sql' - ]), - type=data['col_type'], - show_sysobj=self.blueprint.show_system_objects - ) + result = exclusion_utils.get_operator( + self.conn, data['col_type'], + self.blueprint.show_system_objects) - status, res = self.conn.execute_2darray(SQL) - - if not status: - return internal_server_error(errormsg=res) - result = [] - for row in res['rows']: - result.append([row['oprname'], row['oprname']]) return make_json_response( data=result, status=200 diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/utils.py index eede2d30e..6593a7a0c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/utils.py @@ -65,7 +65,7 @@ def get_parent(conn, tid, template_path=None): @get_template_path def column_formatter(conn, tid, clid, data, edit_types_list=None, - template_path=None): + fetch_inherited_tables=True, template_path=None): """ This function will return formatted output of query result as per client model format for column node @@ -73,6 +73,8 @@ def column_formatter(conn, tid, clid, data, edit_types_list=None, :param tid: Table ID :param clid: Column ID :param data: Data + :param edit_types_list: + :param fetch_inherited_tables: :param template_path: Optional template path :return: """ @@ -97,15 +99,16 @@ def column_formatter(conn, tid, clid, data, edit_types_list=None, data = fetch_length_precision(data) # We need to fetch inherited tables for each table - SQL = render_template("/".join([template_path, - 'get_inherited_tables.sql']), tid=tid) - status, inh_res = conn.execute_dict(SQL) - if not status: - return internal_server_error(errormsg=inh_res) - for row in inh_res['rows']: - if row['attrname'] == data['name']: - data['is_inherited'] = True - data['tbls_inherited'] = row['inhrelname'] + if fetch_inherited_tables: + SQL = render_template("/".join( + [template_path, 'get_inherited_tables.sql']), tid=tid) + status, inh_res = conn.execute_dict(SQL) + if not status: + return internal_server_error(errormsg=inh_res) + for row in inh_res['rows']: + if row['attrname'] == data['name']: + data['is_inherited'] = True + data['tbls_inherited'] = row['inhrelname'] # We need to format variables according to client js collection if 'attoptions' in data and data['attoptions'] is not None: @@ -206,7 +209,7 @@ def get_formatted_columns(conn, tid, data, other_columns, for column in data['columns']: column_formatter(conn, tid, column['attnum'], column, - edit_types[column['atttypid']]) + edit_types[column['atttypid']], False) return data diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/utils.py index 358c65535..0f38889cc 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/utils.py @@ -213,3 +213,76 @@ def get_sql(conn, data, did, tid, exid=None, template_path=None): data=data, conn=conn) return sql, name + + +@get_template_path +def get_access_methods(conn, template_path=None): + """ + This function is used to get the access methods. + + :param conn: + :param template_path: + :return: + """ + res = [{'label': '', 'value': ''}] + sql = render_template("/".join([template_path, 'get_access_methods.sql'])) + + status, rest = conn.execute_2darray(sql) + if not status: + return internal_server_error(errormsg=rest) + + for row in rest['rows']: + res.append( + {'label': row['amname'], 'value': row['amname']} + ) + + return res + + +@get_template_path +def get_oper_class(conn, indextype, template_path=None): + """ + This function is used to get the operator class methods. + + :param conn: + :param indextype: + :param template_path: + :return: + """ + SQL = render_template("/".join([template_path, 'get_oper_class.sql']), + indextype=indextype) + + status, res = conn.execute_2darray(SQL) + if not status: + return internal_server_error(errormsg=res) + + result = [] + for row in res['rows']: + result.append([row['opcname'], row['opcname']]) + + return result + + +@get_template_path +def get_operator(conn, coltype, show_sysobj, template_path=None): + """ + This function is used to get the operator. + + :param conn: + :param coltype: + :param show_sysobj: + :param template_path: + :return: + """ + SQL = render_template("/".join([template_path, 'get_operator.sql']), + type=coltype, show_sysobj=show_sysobj) + + status, res = conn.execute_2darray(SQL) + if not status: + return internal_server_error(errormsg=res) + + result = [] + for row in res['rows']: + result.append([row['oprname'], row['oprname']]) + + return result diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js index 0220a9410..1f211b527 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js @@ -492,12 +492,6 @@ define('pgadmin.node.index', [ this.errorModel.set('name', msg); return msg; } - if (_.isUndefined(this.get('spcname')) - || String(this.get('spcname')).replace(/^\s+|\s+$/g, '') == '') { - msg = gettext('Tablespace cannot be empty.'); - this.errorModel.set('spcname', msg); - return msg; - } if (_.isUndefined(this.get('amname')) || String(this.get('amname')).replace(/^\s+|\s+$/g, '') == '') { msg = gettext('Access method cannot be empty.'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/11_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/11_plus/properties.sql index d2bdc82f2..3fb1a00d0 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/11_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/11_plus/properties.sql @@ -19,9 +19,7 @@ SELECT cls.oid, pg_get_expr(idx.indpred, idx.indrelid, true) AS indconstraint FROM pg_index idx JOIN pg_class cls ON cls.oid=indexrelid -JOIN pg_class tab ON tab.oid=indrelid LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace -JOIN pg_namespace n ON n.oid=tab.relnamespace JOIN pg_am am ON am.oid=cls.relam LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/default/properties.sql index 7feaeb7da..92e993d91 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/default/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/exclusion_constraint/sql/default/properties.sql @@ -19,9 +19,7 @@ SELECT cls.oid, pg_get_expr(idx.indpred, idx.indrelid, true) AS indconstraint FROM pg_index idx JOIN pg_class cls ON cls.oid=indexrelid -JOIN pg_class tab ON tab.oid=indrelid LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace -JOIN pg_namespace n ON n.oid=tab.relnamespace JOIN pg_am am ON am.oid=cls.relam LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/index_constraint/sql/11_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/index_constraint/sql/11_plus/properties.sql index 3dda5633a..18e25b593 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/index_constraint/sql/11_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/index_constraint/sql/11_plus/properties.sql @@ -17,10 +17,7 @@ SELECT cls.oid, substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor FROM pg_index idx JOIN pg_class cls ON cls.oid=indexrelid -JOIN pg_class tab ON tab.oid=indrelid LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace -JOIN pg_namespace n ON n.oid=tab.relnamespace -JOIN pg_am am ON am.oid=cls.relam LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) LEFT OUTER JOIN pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/index_constraint/sql/default/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/index_constraint/sql/default/properties.sql index 6ead04b47..622b005aa 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/index_constraint/sql/default/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/index_constraint/sql/default/properties.sql @@ -17,10 +17,7 @@ SELECT cls.oid, substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor FROM pg_index idx JOIN pg_class cls ON cls.oid=indexrelid -JOIN pg_class tab ON tab.oid=indrelid LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace -JOIN pg_namespace n ON n.oid=tab.relnamespace -JOIN pg_am am ON am.oid=cls.relam LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) LEFT OUTER JOIN pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)