diff --git a/docs/en_US/exclusion_constraint_dialog.rst b/docs/en_US/exclusion_constraint_dialog.rst index f54fd046a..024119880 100644 --- a/docs/en_US/exclusion_constraint_dialog.rst +++ b/docs/en_US/exclusion_constraint_dialog.rst @@ -58,13 +58,15 @@ Click the *Columns* tab to continue. :alt: Exclusion constraint dialog columns tab :align: center -Use the fields in the *Columns* tab to to specify the column(s) to which the -constraint applies. Use the drop-down listbox next to *Column* to select a -column and click the *Add* icon (+) to provide details of the action on the -column: +Use the fields in the *Columns* tab to specify the column(s) or expression(s) +to which the constraint applies. Use the *Is expression ?* switch to enable +expression text input. Use the drop-down listbox next to *Column* +to select a column. Once the *Column* is selected or the *Expression* is +entered then click the *Add* icon (+) to provide details of the action on the +column/expression: -* The *Column* field is populated with the selection made in the *Column* - drop-down listbox. +* The *Col/Exp* field is populated with the selection made in the *Column* + drop-down listbox or the *Expression* entered. * If applicable, use the drop-down listbox in the *Operator class* to specify the operator class that will be used by the index for the column. * Move the *DESC* switch to *DESC* to specify a descending sort order. The diff --git a/docs/en_US/images/exclusion_constraint_columns.png b/docs/en_US/images/exclusion_constraint_columns.png old mode 100755 new mode 100644 index 671f9412e..882433aa3 Binary files a/docs/en_US/images/exclusion_constraint_columns.png and b/docs/en_US/images/exclusion_constraint_columns.png differ diff --git a/docs/en_US/images/exclusion_constraint_sql.png b/docs/en_US/images/exclusion_constraint_sql.png old mode 100755 new mode 100644 index 8a14e722c..e992c0ff3 Binary files a/docs/en_US/images/exclusion_constraint_sql.png and b/docs/en_US/images/exclusion_constraint_sql.png differ diff --git a/docs/en_US/release_notes_4_30.rst b/docs/en_US/release_notes_4_30.rst index 0351a6296..3962099cd 100644 --- a/docs/en_US/release_notes_4_30.rst +++ b/docs/en_US/release_notes_4_30.rst @@ -19,6 +19,7 @@ Housekeeping Bug fixes ********* +| `Issue #5571 `_ - Added support for expression in exclusion constraints. | `Issue #5875 `_ - Ensure that the 'template1' database should not be visible after pg_upgrade. | `Issue #5965 `_ - Ensure that the macro query result should be download properly. | `Issue #5973 `_ - Added appropriate help message and a placeholder for letting users know about the account password expiry for Login/Group Role. 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 6da40f9f5..51323a273 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 @@ -560,17 +560,16 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings, Returns: """ - data = request.args if request.args else None + data = request.args try: - if data and 'col_type' in data: - result = exclusion_utils.get_operator( - self.conn, data['col_type'], - self.blueprint.show_system_objects) + result = exclusion_utils.get_operator( + self.conn, data.get('col_type', None), + self.blueprint.show_system_objects) - return make_json_response( - data=result, - status=200 - ) + return make_json_response( + data=result, + status=200 + ) except Exception as e: return internal_server_error(errormsg=str(e)) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py index 679782f4d..7615ad85e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/__init__.py @@ -778,58 +778,18 @@ class ExclusionConstraintView(PGChildNodeView): """ try: - SQL = render_template( - "/".join([self.template_path, self._PROPERTIES_SQL]), - did=did, tid=tid, conn=self.conn, cid=exid) - status, result = self.conn.execute_dict(SQL) + status, rows = exclusion_utils.get_exclusion_constraints( + self.conn, did, tid, exid, template_path=self.template_path + ) if not status: - return internal_server_error(errormsg=result) - if len(result['rows']) == 0: + return rows + if len(rows) == 0: return gone(_("Could not find the exclusion constraint.")) - data = result['rows'][0] + data = rows[0] data['schema'] = self.schema data['table'] = self.table - sql = render_template( - "/".join([self.template_path, 'get_constraint_cols.sql']), - cid=exid, - colcnt=data['col_count']) - status, res = self.conn.execute_dict(sql) - - if not status: - return internal_server_error(errormsg=res) - - columns = [] - for row in res['rows']: - nulls_order = True if (row['options'] & 2) else False - order = False if row['options'] & 1 else True - columns.append({"column": row['coldef'].strip('"'), - "oper_class": row['opcname'], - "order": order, - "nulls_order": nulls_order, - "operator": row['oprname'] - }) - - data['columns'] = columns - - # Add Include details of the index supported for PG-11+ - if self.manager.version >= 110000: - sql = render_template( - "/".join( - [self.template_path, 'get_constraint_include.sql'] - ), - cid=exid) - status, res = self.conn.execute_dict(sql) - - if not status: - return internal_server_error(errormsg=res) - - data['include'] = [col['colname'] for col in res['rows']] - - if data.get('amname', '') == "": - data['amname'] = 'btree' - SQL = render_template( "/".join([self.template_path, self._CREATE_SQL]), data=data) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.js index d8ef7b361..670734008 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/exclusion_constraint/static/js/exclusion_constraint.js @@ -19,6 +19,7 @@ define('pgadmin.node.exclusion_constraint', [ var ExclusionConstraintColumnModel = pgBrowser.Node.Model.extend({ defaults: { column: undefined, + is_exp: false, oper_class: undefined, order: false, nulls_order: false, @@ -32,8 +33,20 @@ define('pgadmin.node.exclusion_constraint', [ return d; }, schema: [{ - id: 'column', label: gettext('Column'), type:'text', editable: false, + id: 'column', label: gettext('Col/Exp'), type:'text', editable: false, cell:'string', + },{ + id: 'is_exp', label: '', type:'boolean', editable: false, + cell: Backgrid.StringCell.extend({ + formatter: { + fromRaw: function (rawValue) { + return rawValue ? 'E' : 'C'; + }, + toRaw: function (val) { + return val; + }, + }, + }), visible: false, },{ id: 'oper_class', label: gettext('Operator class'), type:'text', node: 'table', url: 'get_oper_class', first_empty: true, @@ -175,7 +188,7 @@ define('pgadmin.node.exclusion_constraint', [ self.column.set('options', []); - if (url && !_.isUndefined(col_type) && !_.isNull(col_type) && col_type != '') { + if (url) { var node = this.column.get('schema_node'), eventHandler = m.top || m, node_info = this.column.get('node_info'), @@ -210,9 +223,11 @@ define('pgadmin.node.exclusion_constraint', [ validate: function() { this.errorModel.clear(); var operator = this.get('operator'), - column_name = this.get('column'); + column_name = this.get('column'), + is_exp = this.get('is_exp'); if (_.isUndefined(operator) || _.isNull(operator)) { var msg = gettext('Please specify operator for column: ') + column_name; + if(is_exp) msg = gettext('Please specify operator for expression: ') + column_name; this.errorModel.set('operator', msg); return msg; } @@ -231,8 +246,15 @@ define('pgadmin.node.exclusion_constraint', [ var self = this, node = 'exclusion_constraint', headerSchema = [{ - id: 'column', label:'', type:'text', - node: 'column', control: Backform.NodeListByNameControl.extend({ + id: 'is_exp', label: gettext('Is expression ?'), type: 'switch', + control: 'switch', controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12', + controlsClassName: 'pgadmin-controls pg-el-sm-6 pg-el-12', + },{ + id: 'column', label: gettext('Column'), type:'text', + controlLabelClassName: 'control-label pg-el-sm-4 pg-el-12', + controlsClassName: 'pgadmin-controls pg-el-sm-6 pg-el-12', + node: 'column', deps: ['is_exp'], + control: Backform.NodeListByNameControl.extend({ initialize: function() { // Here we will decide if we need to call URL // Or fetch the data from parent columns collection @@ -310,7 +332,8 @@ define('pgadmin.node.exclusion_constraint', [ } }, template: _.template([ - '
', + '<%=label%>', + '
', ' <%=readonly ? "readonly aria-readonly=true" : ""%> <%=required ? "required" : ""%> />', ' <% if (helpMessage && helpMessage.length) { %>', ' <%=helpMessage%>',