From 7ce07f7dcfef52ba5a72bd146ce4f05ca67a2ecc Mon Sep 17 00:00:00 2001 From: Yogesh Mahajan Date: Fri, 6 Oct 2023 12:28:40 +0530 Subject: [PATCH] Fixed issues reported while testing foreign table node. #640 --- .../schemas/foreign_tables/__init__.py | 178 +++++++++++++- ...amp_with_default_value_using_function.msql | 2 +- .../pg/default/alter_column_numeric.msql | 2 +- ...amp_with_default_value_using_function.msql | 2 +- .../ppas/default/alter_column_numeric.msql | 2 +- .../static/js/foreign_table.ui.js | 231 +++++++++--------- .../sql/default/update.sql | 13 +- .../foreign_tables/sql/default/create.sql | 2 +- .../sql/default/foreign_table_schema_diff.sql | 2 +- .../sql/default/get_columns.sql | 6 +- .../foreign_tables/sql/default/update.sql | 74 ------ .../tests/foreign_tables_test_data.json | 6 +- .../tests/pg/default/alter_add_cons_opts.sql | 4 +- .../tests/pg/default/alter_add_priv.sql | 4 +- .../tests/pg/default/alter_col_opts.sql | 2 +- .../tests/pg/default/alter_col_opts_msql.sql | 9 +- .../pg/default/alter_comment_add_columns.sql | 4 +- .../alter_comment_add_columns_msql.sql | 10 +- .../default/alter_remove_opts_priv_cons.sql | 2 +- .../create_foreign_table_with_all_options.sql | 4 +- ...te_foreign_table_with_all_options_msql.sql | 4 +- .../tests/pg/default/test_foreign_table.json | 23 +- .../ppas/default/alter_add_cons_opts.sql | 4 +- .../tests/ppas/default/alter_add_priv.sql | 4 +- .../tests/ppas/default/alter_col_opts.sql | 2 +- .../ppas/default/alter_col_opts_msql.sql | 9 +- .../default/alter_comment_add_columns.sql | 4 +- .../alter_comment_add_columns_msql.sql | 10 +- .../default/alter_remove_opts_priv_cons.sql | 2 +- .../create_foreign_table_with_all_options.sql | 4 +- ...te_foreign_table_with_all_options_msql.sql | 4 +- .../ppas/default/test_foreign_table.json | 8 +- .../tables/columns/static/js/column.ui.js | 9 +- .../databases/schemas/tables/columns/utils.py | 21 +- .../columns/sql/14_plus/properties.sql | 18 ++ 35 files changed, 414 insertions(+), 271 deletions(-) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/__init__.py index 61d95e29196..1bff4b2e29c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/__init__.py @@ -10,6 +10,7 @@ """Implements the Foreign Table Module.""" import sys +import re from functools import wraps import json @@ -28,11 +29,14 @@ from pgadmin.browser.utils import PGChildNodeView from pgadmin.utils.ajax import make_json_response, internal_server_error, \ make_response as ajax_response, gone +from pgadmin.utils.compile_template_name import compile_template_path 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 pgadmin.browser.server_groups.servers.databases.schemas.tables.\ columns import utils as column_utils +from pgadmin.browser.server_groups.servers.databases.schemas.tables.\ + triggers import utils as trigger_utils class ForeignTableModule(SchemaChildModule): @@ -188,6 +192,8 @@ class ForeignTableView(PGChildNodeView) node_type = blueprint.node_type node_label = "Foreign Table" BASE_TEMPLATE_PATH = 'foreign_tables/sql/#{0}#' + double_newline = '\n\n' + pattern = '\n{2,}' parent_ids = [ {'type': 'int', 'id': 'gid'}, @@ -403,6 +409,17 @@ def wrap(*args, **kwargs): self.template_path = \ self.BASE_TEMPLATE_PATH.format(self.manager.version) + self.foreign_table_column_template_path = compile_template_path( + 'foreign_table_columns/sql', self.manager.version) + + self.column_template_path = compile_template_path( + 'columns/sql', self.manager.version) + + # Template for trigger node + self.trigger_template_path = \ + 'triggers/sql/{0}/#{1}#'.format(self.manager.server_type, + self.manager.version) + return f(*args, **kwargs) return wrap @@ -918,6 +935,11 @@ def sql(self, gid, sid, did, scid, foid=None, **kwargs): SQL = sql_header + SQL + trigger_sql = self._get_resql_for_triggers( + foid, data['basensp'], data['name']) + + SQL = SQL + trigger_sql + return ajax_response(response=SQL.strip('\n')) @check_precondition @@ -1012,9 +1034,9 @@ def _parse_column_options(data): :return: """ for c in data['columns']['changed']: - old_col_options = c['attfdwoptions'] = [] - if 'attfdwoptions' in c and c['attfdwoptions']: - old_col_options = c['attfdwoptions'] + old_col_options = [] + if 'coloptions' in c and c['coloptions']: + old_col_options = c['coloptions'] old_col_frmt_options = {} @@ -1089,7 +1111,13 @@ def get_sql(self, **kwargs): data['is_schema_diff'] = True old_data['columns_for_schema_diff'] = old_data['columns'] - self._format_columns_data(data, old_data) + # If name is not present in request data + if 'name' not in data: + data['name'] = old_data['name'] + + # If name if not present + if 'schema' not in data: + data['schema'] = old_data['basensp'] # Parse Privileges ForeignTableView._parse_privileges(data) @@ -1109,6 +1137,37 @@ def get_sql(self, **kwargs): "/".join([self.template_path, self._UPDATE_SQL]), data=data, o_data=old_data, conn=self.conn ) + + # Removes trailing new lines + if sql: + sql = sql.strip('\n') + self.double_newline + + # Parse/Format columns & create sql + if 'columns' in data: + # Parse the data coming from client + data = column_utils.parse_format_columns(data, mode='edit') + + columns = data['columns'] + column_sql = '\n' + + # If column(s) is/are deleted + column_sql = self._check_for_column_delete(columns, data, + column_sql) + + # If column(s) is/are changed + column_sql = self._check_for_column_update(columns, data, + column_sql, foid) + + # If column(s) is/are added + column_sql = self._check_for_column_add(columns, data, + column_sql) + + # Combine all the SQL together + sql += column_sql.strip('\n') + + sql = re.sub(self.pattern, self.double_newline, sql) + sql = sql.strip('\n') + return sql, data['name'] if 'name' in data else old_data['name'] else: data['columns'] = self._format_columns(data['columns']) @@ -1123,6 +1182,83 @@ def get_sql(self, **kwargs): conn=self.conn) return sql, data['name'] + def _check_for_column_delete(self, columns, data, column_sql): + # If column(s) is/are deleted + if 'deleted' in columns: + for c in columns['deleted']: + c['schema'] = data['schema'] + c['table'] = data['name'] + # Sql for drop column + if 'inheritedfrom' not in c: + column_sql += render_template("/".join( + [self.foreign_table_column_template_path, + self._DELETE_SQL]), + data=c, conn=self.conn).strip('\n') + \ + self.double_newline + return column_sql + + def _check_for_column_update(self, columns, data, column_sql, tid): + # Here we will be needing previous properties of column + # so that we can compare & update it + if 'changed' in columns: + for c in columns['changed']: + c['schema'] = data['schema'] + c['table'] = data['name'] + + properties_sql = render_template( + "/".join([self.column_template_path, + self._PROPERTIES_SQL]), + tid=tid, + clid=c['attnum'] if 'attnum' in c else None, + show_sys_objects=self.blueprint.show_system_objects + ) + + status, res = self.conn.execute_dict(properties_sql) + if not status: + return internal_server_error(errormsg=res) + old_col_data = res['rows'][0] + + old_col_data['cltype'], \ + old_col_data['hasSqrBracket'] = \ + column_utils.type_formatter(old_col_data['cltype']) + old_col_data = \ + column_utils.convert_length_precision_to_string( + old_col_data) + old_col_data = column_utils.fetch_length_precision( + old_col_data) + + old_col_data['cltype'] = \ + DataTypeReader.parse_type_name( + old_col_data['cltype']) + + # Sql for alter column + if 'inheritedfrom' not in c and \ + 'inheritedfromtable' not in c: + column_sql += render_template("/".join( + [self.foreign_table_column_template_path, + self._UPDATE_SQL]), + data=c, o_data=old_col_data, conn=self.conn + ).strip('\n') + self.double_newline + return column_sql + + def _check_for_column_add(self, columns, data, column_sql): + # If column(s) is/are added + if 'added' in columns: + for c in columns['added']: + c['schema'] = data['schema'] + c['table'] = data['name'] + + c = column_utils.convert_length_precision_to_string(c) + + if 'inheritedfrom' not in c and \ + 'inheritedfromtable' not in c: + column_sql += render_template("/".join( + [self.foreign_table_column_template_path, + self._CREATE_SQL]), + data=c, conn=self.conn).strip('\n') + \ + self.double_newline + return column_sql + @check_precondition def dependents(self, gid, sid, did, scid, foid): """ @@ -1248,6 +1384,14 @@ def _fetch_properties(self, gid, sid, did, scid, foid, inherits=False, ): for col in cols['rows']: column_utils.fetch_length_precision(col) + if 'attoptions' in col and col['attoptions'] != '': + col['attoptions'] = column_utils.parse_column_variables( + col['attoptions']) + + if 'attfdwoptions' in col and col['attfdwoptions'] != '': + col['coloptions'] = column_utils.parse_options_for_column( + col['attfdwoptions']) + self._get_edit_types(cols['rows']) if cols and 'rows' in cols: @@ -1768,6 +1912,32 @@ def enable_disable_triggers(self, gid, sid, did, scid, foid): except Exception as e: return internal_server_error(errormsg=str(e)) + def _get_resql_for_triggers(self, tid, schema, + table): + """ + ######################################## + # Reverse engineered sql for TRIGGERS + ######################################## + """ + sql = render_template("/".join([self.trigger_template_path, + self._NODES_SQL]), tid=tid) + status, rset = self.conn.execute_2darray(sql) + if not status: + return internal_server_error(errormsg=rset) + + trigger_sql = '' + for row in rset['rows']: + trigger_sql = trigger_utils.get_reverse_engineered_sql( + self.conn, schema=schema, table=table, tid=tid, + trid=row['oid'], datlastsysoid=self._DATABASE_LAST_SYSTEM_OID, + show_system_objects=self.blueprint.show_system_objects, + template_path=None) + trigger_sql = "\n" + trigger_sql + + trigger_sql = re.sub(self.pattern, self.double_newline, + trigger_sql) + return trigger_sql + SchemaDiffRegistry(blueprint.node_type, ForeignTableView) ForeignTableView.register_node_view(blueprint) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/pg/12_plus/alter_column_timestamp_with_default_value_using_function.msql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/pg/12_plus/alter_column_timestamp_with_default_value_using_function.msql index 0f55e375c9b..68ac2bb8129 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/pg/12_plus/alter_column_timestamp_with_default_value_using_function.msql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/pg/12_plus/alter_column_timestamp_with_default_value_using_function.msql @@ -1,4 +1,4 @@ -ALTER FOREIGN TABLE public."foreign_table_2_$%{}[]()&*^!@""'`\/#" +ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" ALTER COLUMN "col_3_$%{}[]()&*^!@""'`\/#" TYPE time(10) with time zone ; ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/pg/default/alter_column_numeric.msql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/pg/default/alter_column_numeric.msql index f00921076e9..646dfb29bd2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/pg/default/alter_column_numeric.msql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/pg/default/alter_column_numeric.msql @@ -3,7 +3,7 @@ ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" ALTER COLUMN "new_col_1_$%{}[]()&*^!@""'`\/#" OPTIONS (ADD column_name 'test'); -ALTER FOREIGN TABLE public."foreign_table_2_$%{}[]()&*^!@""'`\/#" +ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" ALTER COLUMN "new_col_1_$%{}[]()&*^!@""'`\/#" TYPE real; COMMENT ON COLUMN public."foreign_table_2_$%{}[]()&*^!@""'`\/#"."new_col_1_$%{}[]()&*^!@""'`\/#" diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/ppas/12_plus/alter_column_timestamp_with_default_value_using_function.msql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/ppas/12_plus/alter_column_timestamp_with_default_value_using_function.msql index 0f55e375c9b..68ac2bb8129 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/ppas/12_plus/alter_column_timestamp_with_default_value_using_function.msql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/ppas/12_plus/alter_column_timestamp_with_default_value_using_function.msql @@ -1,4 +1,4 @@ -ALTER FOREIGN TABLE public."foreign_table_2_$%{}[]()&*^!@""'`\/#" +ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" ALTER COLUMN "col_3_$%{}[]()&*^!@""'`\/#" TYPE time(10) with time zone ; ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/ppas/default/alter_column_numeric.msql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/ppas/default/alter_column_numeric.msql index f00921076e9..646dfb29bd2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/ppas/default/alter_column_numeric.msql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/foreign_table_columns/tests/ppas/default/alter_column_numeric.msql @@ -3,7 +3,7 @@ ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" ALTER COLUMN "new_col_1_$%{}[]()&*^!@""'`\/#" OPTIONS (ADD column_name 'test'); -ALTER FOREIGN TABLE public."foreign_table_2_$%{}[]()&*^!@""'`\/#" +ALTER FOREIGN TABLE IF EXISTS public."foreign_table_2_$%{}[]()&*^!@""'`\/#" ALTER COLUMN "new_col_1_$%{}[]()&*^!@""'`\/#" TYPE real; COMMENT ON COLUMN public."foreign_table_2_$%{}[]()&*^!@""'`\/#"."new_col_1_$%{}[]()&*^!@""'`\/#" diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.ui.js index 9d342eac2da..37f901147d6 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/static/js/foreign_table.ui.js @@ -62,6 +62,25 @@ export default class ForeignTableSchema extends BaseUISchema { return isEmptyString(colstate.inheritedfrom); } + inSchemaWithColumnCheck(state) { + if(this.nodeInfo && ('schema' in this.nodeInfo)) { + if(this.isNew(state)) { + return false; + } + + // We will disable control if it's system columns + // inheritedfrom check is useful when we use this schema in table node + // inheritedfrom has value then we should disable it + if (!isEmptyString(state.inheritedfrom)){ + return true; + } + + // ie: it's position is less than 1 + return !(!_.isUndefined(state.attnum) && state.attnum > 0); + } + return false; + } + getTableOid(tabId) { // Here we will fetch the table oid from table name // iterate over list to find table oid @@ -265,7 +284,7 @@ export class ColumnSchema extends BaseUISchema { attlen: undefined, attprecision: undefined, defval: undefined, - attnotnull: undefined, + attnotnull: false, collspcname: undefined, attstattarget:undefined, attnum: undefined, @@ -279,6 +298,8 @@ export class ColumnSchema extends BaseUISchema { this.nodeInfo = nodeInfo; this.cltypeOptions = datatypeOptions; this.collspcnameOptions = collspcnameOptions; + + this.datatypes = []; } get idAttribute() { @@ -295,6 +316,28 @@ export class ColumnSchema extends BaseUISchema { return (!_.isUndefined(colconstype) && !_.isNull(colconstype) && colconstype == 'g'); } + attlenRange(state) { + for(let o of this.datatypes) { + if ( state.cltype == o.value ) { + if(o.length) return {min: o.min_val || 0, max: o.max_val}; + } + } + return null; + } + + attprecisionRange(state) { + for(let o of this.datatypes) { + if ( state.cltype == o.value ) { + if(o.precision) return {min: o.min_val || 0, max: o.max_val}; + } + } + return null; + } + + attCell(state) { + return { cell: this.attlenRange(state) ? 'int' : '' }; + } + get baseFields() { let obj = this; @@ -323,7 +366,7 @@ export class ColumnSchema extends BaseUISchema { }, options: obj.cltypeOptions, optionsLoaded: (options)=>{ - obj.type_options = options; + obj.datatypes = options; }, cell: (row)=>{ return { @@ -364,124 +407,91 @@ export class ColumnSchema extends BaseUISchema { } }, { - id: 'inheritedfrom', label: gettext('Inherited From'), cell: 'label', - type: 'label', readonly: true, editable: false, mode: ['create','properties', 'edit'], + id: 'inheritedfrom', label: gettext('Inherited from'), cell: 'label', type: 'text', + readonly: true, editable: false, mode: ['create','properties', 'edit'], }, { id: 'attnum', label: gettext('Position'), cell: 'text', type: 'text', disabled: obj.inCatalog(), mode: ['properties'], }, { - id: 'attlen', label: gettext('Length'), cell: 'int', - deps: ['cltype'], type: 'int', group: gettext('Definition'), minWidth: 60, - disabled: (state) => { - let val = state.attlen; - // We will store type from selected from combobox - if(!(_.isUndefined(state.inheritedid) - || _.isNull(state.inheritedid) - || _.isUndefined(state.inheritedfrom) - || _.isNull(state.inheritedfrom))) { - - if (!_.isUndefined(val)) { - state.attlen = undefined; - } - return true; - } - - let of_type = state.cltype, - has_length = false; - if(obj.type_options) { - state.is_tlength = false; - - // iterating over all the types - _.each(obj.type_options, function(o) { - // if type from selected from combobox matches in options - if ( of_type == o.value ) { - // if length is allowed for selected type - if(o.length) - { - // set the values in model - has_length = true; - state.is_tlength = true; - state.min_val = o.min_val; - state.max_val = o.max_val; - } - } - }); - - if (!has_length && !_.isUndefined(val)) { - state.attlen = undefined; - } - - return !(state.is_tlength); + id: 'attlen', + label: gettext('Length'), + group: gettext('Definition'), + deps: ['cltype'], + type: 'int', + minWidth: 60, + cell: (state)=>{ + return obj.attCell(state); + }, + depChange: (state)=>{ + let range = this.attlenRange(state); + if(range) { + return { + ...state, min_val_attlen: range.min, max_val_attlen: range.max, + }; + } else { + return { + ...state, attlen: null, + }; } - if (!has_length && !_.isUndefined(val)) { - state.attlen = undefined; + }, + disabled: function(state) { + return !obj.attlenRange(state); + }, + editable: function(state) { + // inheritedfrom has value then we should disable it + if (!isEmptyString(state.inheritedfrom)) { + return false; } - return true; + return Boolean(obj.attlenRange(state)); }, - }, - { - id: 'attprecision', label: gettext('Scale'), cell: 'int', minWidth: 60, - deps: ['cltype'], type: 'int', group: gettext('Definition'), - disabled: (state) => { - let val = state.attprecision; - if(!(_.isUndefined(state.inheritedid) - || _.isNull(state.inheritedid) - || _.isUndefined(state.inheritedfrom) - || _.isNull(state.inheritedfrom))) { - if (!_.isUndefined(val)) { - state.attprecision = undefined; - } - return true; - } - let of_type = state.cltype, - has_precision = false; - - if(obj.type_options) { - state.is_precision = false; - // iterating over all the types - _.each(obj.type_options, function(o) { - // if type from selected from combobox matches in options - if ( of_type == o.value ) { - // if precession is allowed for selected type - if(o.precision) - { - has_precision = true; - // set the values in model - state.is_precision = true; - state.min_val = o.min_val; - state.max_val = o.max_val; - } - } - }); - if (!has_precision && !_.isUndefined(val)) { - state.attprecision = undefined; - } - return !(state.is_precision); + },{ + id: 'min_val_attlen', skipChange: true, visible: false, type: '', + },{ + id: 'max_val_attlen', skipChange: true, visible: false, type: '', + },{ + id: 'attprecision', label: gettext('Scale'), width: 60, disableResizing: true, + deps: ['cltype'], type: 'int', group: gettext('Definition'), + cell: (state)=>{ + return obj.attCell(state); + }, + depChange: (state)=>{ + let range = this.attprecisionRange(state); + if(range) { + return { + ...state, min_val_attprecision: range.min, max_val_attprecision: range.max, + }; + } else { + return { + ...state, attprecision: null, + }; } - if (!has_precision && !_.isUndefined(val)) { - state.attprecision = undefined; + }, + disabled: function(state) { + return !this.attprecisionRange(state); + }, + editable: function(state) { + // inheritedfrom has value then we should disable it + if (!isEmptyString(state.inheritedfrom)) { + return false; } - return true; + return Boolean(this.attprecisionRange(state)); }, + },{ + id: 'min_val_attprecision', skipChange: true, visible: false, type: '', + },{ + id: 'max_val_attprecision', skipChange: true, visible: false, type: '', }, { - id: 'attstattarget', label: gettext('Statistics'), cell: 'text', - type: 'text', disabled: (state) => { - if (obj.isNew()) { - return false; - } - - if (obj.nodeInfo.server.version < 90200) { - return false; - } - - return (_.isUndefined(state.inheritedid) || _.isNull(state.inheritedid) || - _.isUndefined(state.inheritedfrom) || _.isNull(state.inheritedfrom)) ? true : false; - }, mode: ['properties', 'edit'], + id: 'attstattarget', + label: gettext('Statistics'), + cell: 'text', + type: 'text', + readonly: obj.inSchemaWithColumnCheck, + mode: ['properties', 'edit'], group: gettext('Definition'), }, { @@ -529,10 +539,9 @@ export class ColumnSchema extends BaseUISchema { group: gettext('Constraints'), type: (state)=>{ let options = [ - { - 'label': gettext('NONE'), - 'value': 'n'}, - ]; // You can't change the existing column to Generated column. + { 'label': gettext('NONE'), 'value': 'n'}, + ]; + // You can't change the existing column to Generated column. if (this.isNew(state)) { options.push({ 'label': gettext('GENERATED'), @@ -585,8 +594,10 @@ export class ColumnSchema extends BaseUISchema { disabled: (state)=>{ if (!(_.isUndefined(obj.isNew)) && !obj.isNew(state)) { return false; } - return (_.isUndefined(state.inheritedid) || _.isNull(state.inheritedid) || - _.isUndefined(state.inheritedfrom) || _.isNull(state.inheritedfrom)) ? true : false; + return (_.isUndefined(state.inheritedid) + || _.isNull(state.inheritedid) || + _.isUndefined(state.inheritedfrom) || + _.isNull(state.inheritedfrom)); } }, { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_table_columns/sql/default/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_table_columns/sql/default/update.sql index d33199c7a92..38413c3996e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_table_columns/sql/default/update.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_table_columns/sql/default/update.sql @@ -10,18 +10,21 @@ ALTER FOREIGN TABLE IF EXISTS {{conn|qtIdent(data.schema, data.table)}} {% if 'coloptions' in data and data.coloptions != None and data.coloptions|length > 0 %} {% set coloptions = data.coloptions %} {% if data.name %} +{% set colname = data.name %} +{% else %} +{% set colname = o_data.name %} +{% endif %} {% if 'added' in coloptions and coloptions.added|length > 0 %} ALTER FOREIGN TABLE IF EXISTS {{conn|qtIdent(data.schema, data.table)}} - ALTER COLUMN {{conn|qtIdent(data.name)}} OPTIONS (ADD {% for opt in coloptions.added %}{% if loop.index != 1 %}, {% endif %}{{ conn|qtIdent(opt.option) }} {{ opt.value|qtLiteral(conn) }}{% endfor %}); + ALTER COLUMN {{conn|qtIdent(colname)}} OPTIONS (ADD {% for opt in coloptions.added %}{% if loop.index != 1 %}, {% endif %}{{ conn|qtIdent(opt.option) }} {{ opt.value|qtLiteral(conn) }}{% endfor %}); {% endif %} {% if 'changed' in coloptions and coloptions.changed|length > 0 %} ALTER FOREIGN TABLE IF EXISTS {{conn|qtIdent(data.schema, data.table)}} - ALTER COLUMN {{conn|qtIdent(data.name)}} OPTIONS (SET {% for opt in coloptions.changed %}{% if loop.index != 1 %}, {% endif %}{{ conn|qtIdent(opt.option) }} {{ opt.value|qtLiteral(conn) }}{% endfor %}); + ALTER COLUMN {{conn|qtIdent(colname)}} OPTIONS (SET {% for opt in coloptions.changed %}{% if loop.index != 1 %}, {% endif %}{{ conn|qtIdent(opt.option) }} {{ opt.value|qtLiteral(conn) }}{% endfor %}); {% endif %} {% if 'deleted' in coloptions and coloptions.deleted|length > 0 %} ALTER FOREIGN TABLE IF EXISTS {{conn|qtIdent(data.schema, data.table)}} - ALTER COLUMN {{conn|qtIdent(data.name)}} OPTIONS (DROP {% for opt in coloptions.deleted %}{% if loop.index != 1 %}, {% endif %}{{ conn|qtIdent(opt.option) }}{% endfor %}); -{% endif %} + ALTER COLUMN {{conn|qtIdent(colname)}} OPTIONS (DROP {% for opt in coloptions.deleted %}{% if loop.index != 1 %}, {% endif %}{{ conn|qtIdent(opt.option) }}{% endfor %}); {% endif %} {% endif %} {### Alter column type and collation ###} @@ -31,7 +34,7 @@ ALTER FOREIGN TABLE IF EXISTS {{conn|qtIdent(data.schema, data.table)}} -- The SQL statement below would normally be used to alter the cltype for the {{o_data.name}} column, however, -- the current datatype cannot be cast to the target cltype so this conversion cannot be made automatically. {% endif %} -{% if data.col_type_conversion is defined and data.col_type_conversion == False %} -- {% endif %}ALTER FOREIGN TABLE {{conn|qtIdent(data.schema, data.table)}} +{% if data.col_type_conversion is defined and data.col_type_conversion == False %} -- {% endif %}ALTER FOREIGN TABLE IF EXISTS {{conn|qtIdent(data.schema, data.table)}} {% if data.col_type_conversion is defined and data.col_type_conversion == False %} -- {% endif %} ALTER COLUMN {% if data.name %}{{conn|qtTypeIdent(data.name)}}{% else %}{{conn|qtTypeIdent(o_data.name)}}{% endif %} TYPE {{ GET_TYPE.UPDATE_TYPE_SQL(conn, data, o_data) }}{% if data.collspcname and data.collspcname != o_data.collspcname %} COLLATE {{data.collspcname}}{% elif o_data.collspcname %} COLLATE {{o_data.collspcname}}{% endif %}; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/create.sql index 5d5271c2ee6..fae839f595c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/create.sql @@ -11,7 +11,7 @@ CREATE FOREIGN TABLE{% if add_not_exists_clause %} IF NOT EXISTS{% endif %} {{ c {% for o in c.coloptions %}{% if o.option is defined and o.value is defined %} {% if loop.first %} OPTIONS ({% endif %}{% if not loop.first %}, {% endif %}{{o.option}} {{o.value|qtLiteral(conn)}}{% if loop.last %}){% endif %}{% endif %} {% endfor %}{% endif %} -{% if c.attnotnull %} NOT NULL{% else %} NULL{% endif %} +{% if c.attnotnull %} NOT NULL{% endif %} {% if c.defval is defined and c.defval is not none %} DEFAULT {{c.defval}}{% endif %} {% if c.collname %} COLLATE {{c.collname}}{% endif %} {% if not loop.last %}, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/foreign_table_schema_diff.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/foreign_table_schema_diff.sql index fa6353cc8b0..83acb8fb8f9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/foreign_table_schema_diff.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/foreign_table_schema_diff.sql @@ -20,7 +20,7 @@ CREATE FOREIGN TABLE {{ conn|qtIdent(o_data.basensp, o_data.name) }}( {% for o in c.coloptions %}{% if o.option is defined and o.value is defined %} {% if loop.first %} OPTIONS ({% endif %}{% if not loop.first %}, {% endif %}{{o.option}} {{o.value|qtLiteral(conn)}}{% if loop.last %}){% endif %}{% endif %} {% endfor %}{% endif %} -{% if c.attnotnull %} NOT NULL{% else %} NULL{% endif %} +{% if c.attnotnull %} NOT NULL{% endif %} {% if c.typdefault is defined and c.typdefault is not none %} DEFAULT {{c.typdefault}}{% endif %} {% if c.collname %} COLLATE {{c.collname}}{% endif %} {% if not loop.last %}, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/get_columns.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/get_columns.sql index 4eaf2217e4c..960c5bfdefb 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/get_columns.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/get_columns.sql @@ -15,14 +15,16 @@ WITH INH_TABLES AS ) SELECT INH.inheritedfrom, INH.inheritedid, att.attoptions, att.atttypid, attfdwoptions, att.attname as name, att.attndims, att.atttypmod, pg_catalog.format_type(t.oid,NULL) AS cltype, - att.attnotnull, att.attstattarget, att.attnum, pg_catalog.format_type(t.oid, att.atttypmod) AS fulltype, + att.attnotnull, att.attstorage, att.attstattarget, att.attnum, pg_catalog.format_type(t.oid, att.atttypmod) AS fulltype, CASE WHEN t.typelem > 0 THEN t.typelem ELSE t.oid END as elemoid, + (CASE WHEN (att.attidentity in ('a', 'd')) THEN 'i' WHEN (att.attgenerated in ('s')) THEN 'g' ELSE 'n' END) AS colconstype, + (CASE WHEN (att.attgenerated in ('s')) THEN pg_catalog.pg_get_expr(def.adbin, def.adrelid) END) AS genexpr, (SELECT nspname FROM pg_catalog.pg_namespace WHERE oid = t.typnamespace) as typnspname, pg_catalog.format_type(t.oid,NULL) AS typname, CASE WHEN length(cn.nspname::text) > 0 AND length(cl.collname::text) > 0 THEN pg_catalog.concat(cn.nspname, '."', cl.collname,'"') ELSE '' END AS collname, - pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS typdefault, + pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS defval, (SELECT COUNT(1) from pg_catalog.pg_type t2 WHERE t2.typname=t.typname) > 1 AS isdup, des.description FROM diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/update.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/update.sql index 0ebb4ed4d95..e6f9d1ae02c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/update.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/templates/foreign_tables/sql/default/update.sql @@ -12,80 +12,6 @@ ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, o_data.name) }} ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} OWNER TO {{ conn|qtIdent(data.owner) }}; -{% endif %} -{% if data.columns %} -{% for c in data.columns.deleted %} -{% if (not c.inheritedfrom or c.inheritedfrom =='' or c.inheritedfrom == None or c.inheritedfrom == 'None' ) %} -ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} - DROP COLUMN {{conn|qtIdent(c.name)}}; - -{% endif %} -{% endfor -%} -{% for c in data.columns.added %} -{% if (not c.inheritedfrom or c.inheritedfrom =='' or c.inheritedfrom == None or c.inheritedfrom == 'None' ) %} -ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} - ADD COLUMN {{conn|qtIdent(c.name)}} {{ c.cltype }}{% if c.attlen %}({{c.attlen}}{% if c.attprecision %}, {{c.attprecision}}{% endif %}){% endif %}{% if c.isArrayType %}[]{% endif %} -{% if c.coloptions %} -{% for o in c.coloptions %}{% if o.option is defined and o.value is defined %} -{% if loop.first %} OPTIONS ({% endif %}{% if not loop.first %}, {% endif %}{{o.option}} {{o.value|qtLiteral(conn)}}{% if loop.last %}){% endif %}{% endif %} -{% endfor %}{% endif %} -{% if c.attnotnull %} NOT NULL{% else %} NULL{% endif %} -{% if c.defval is defined and c.defval is not none %} DEFAULT {{c.defval}}{% endif %} -{% if c.collname %} COLLATE {{c.collname}}{% endif %}; - -{% endif %} -{% endfor -%} -{% for c in data.columns.changed %} -{% set col_name = o_data['columns'][c.attnum]['name'] %} -{% if c.name %}{% if c.name != o_data['columns'][c.attnum]['name'] %} -{% set col_name = c.name %} -ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} - RENAME COLUMN {{conn|qtIdent(o_data['columns'][c.attnum]['name'])}} TO {{conn|qtIdent(c.name)}}; - -{% endif %} -{% endif %} -{% if c.attnotnull != o_data['columns'][c.attnum]['attnotnull'] %} -ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} - ALTER COLUMN {{conn|qtIdent(col_name)}}{% if c.attnotnull %} SET{% else %} DROP{% endif %} NOT NULL; - -{% endif %} -{% if c.cltype != o_data['columns'][c.attnum]['cltype'] or c.attlen != o_data['columns'][c.attnum]['attlen'] or -c.attprecision != o_data['columns'][c.attnum]['attprecision'] %} -ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} - ALTER COLUMN {{conn|qtIdent(col_name)}} TYPE {{ c.cltype }}{% if c.attlen %}({{c.attlen}}{% if c.attprecision %}, {{c.attprecision}}{% endif %}){% endif %}{% if c.isArrayType %}[]{% endif %}; - -{% endif %} -{% if c.typdefault is defined and c.typdefault != o_data['columns'][c.attnum]['typdefault'] %} -ALTER FOREIGN TABLE {{ conn|qtIdent(o_data.basensp, name) }} - ALTER COLUMN {{conn|qtIdent(col_name)}}{% if c.typdefault is defined and c.typdefault != '' %} SET DEFAULT {{c.typdefault}}{% else %} DROP DEFAULT{% endif %}; - -{% endif %} -{% if c.attstattarget != o_data['columns'][c.attnum]['attstattarget'] %} -ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} - ALTER COLUMN {{conn|qtIdent(col_name)}} SET STATISTICS {% if c.attstattarget %}{{c.attstattarget}}{% else %}-1{% endif %}; - -{% endif %} -{% if c.coloptions_updated %} -{% for o in c.coloptions_updated.deleted %} -{% if o.option %} -{% if loop.first %}ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} - ALTER COLUMN {{conn|qtIdent(col_name)}} OPTIONS (DROP {% endif %}{% if not loop.first %}, {% endif %}{{o.option}}{% if loop.last %}){% endif %}; -{% endif %} -{% endfor %} -{% for o in c.coloptions_updated.added %} -{% if o.option is defined and o.value is defined %} -{% if loop.first %}ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} - ALTER COLUMN {{conn|qtIdent(col_name)}} OPTIONS (ADD {% endif %}{% if not loop.first %}, {% endif %}{{o.option}} {{o.value|qtLiteral(conn)}}{% if loop.last %});{% endif %} -{% endif %} -{% endfor %} -{% for o in c.coloptions_updated.changed %} -{% if o.option is defined and o.value is defined %} -{% if loop.first %}ALTER FOREIGN TABLE IF EXISTS {{ conn|qtIdent(o_data.basensp, name) }} - ALTER COLUMN {{conn|qtIdent(col_name)}} OPTIONS (SET {% endif %}{% if not loop.first %}, {% endif %}{{o.option}} {{o.value|qtLiteral(conn)}}{% if loop.last %});{% endif %} -{% endif %} -{% endfor %} -{% endif %} -{% endfor %} {% endif %} {% if data.inherits and data.inherits|length > 0%} {% if o_data.inherits == None or o_data.inherits == 'None' %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/foreign_tables_test_data.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/foreign_tables_test_data.json index 727a5de608e..01756c70253 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/foreign_tables_test_data.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/foreign_tables_test_data.json @@ -233,7 +233,7 @@ "name": "Update Foreign Table: With existing foreign table.", "is_positive_test": true, "inventory_data": { - "query": "\"CREATE FOREIGN TABLE %s.%s (col1 character varying(10) OPTIONS (columnoptionkey 'columnOptionVal') NULL ) SERVER %s;\" %(schema_name, foreign_table_name, fsrv_name)" + "query": "\"CREATE FOREIGN TABLE %s.%s (col1 character varying(10) OPTIONS (column_name 'columnOptionVal') NULL ) SERVER %s;\" %(schema_name, foreign_table_name, fsrv_name)" }, "test_data": { "description": "This is foreign table update comment", @@ -264,7 +264,7 @@ { "coloptions": [ { - "option": "OptionKey", + "option": "column_name", "value": "OptionValue" } ], @@ -279,7 +279,7 @@ "attstattarget": -1, "attoptions": null, "attfdwoptions": [ - "ColOptionKey=ColOptionValue" + "column_name=ColOptionValue" ], "attndims": 0, "atttypmod": -1, diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_add_cons_opts.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_add_cons_opts.sql index fffce8a0c94..2ae6f3cb0b6 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_add_cons_opts.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_add_cons_opts.sql @@ -3,8 +3,8 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL COLLATE pg_catalog."default" + col1 bigint NOT NULL, + col2 text COLLATE pg_catalog."default" ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_add_priv.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_add_priv.sql index 204fe13bbee..4e207f71a20 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_add_priv.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_add_priv.sql @@ -3,8 +3,8 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL COLLATE pg_catalog."default" + col1 bigint NOT NULL, + col2 text COLLATE pg_catalog."default" ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_col_opts.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_col_opts.sql index b20c1ca3fb0..0b6df464a22 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_col_opts.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_col_opts.sql @@ -3,7 +3,7 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 integer NULL + col1 integer ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'test_public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_col_opts_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_col_opts_msql.sql index 095712f7302..fe4c3113ae6 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_col_opts_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_col_opts_msql.sql @@ -1,14 +1,13 @@ ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - DROP COLUMN col2; + OPTIONS (SET schema_name 'test_public'); -ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - ALTER COLUMN col1 DROP NOT NULL; +ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" DROP COLUMN IF EXISTS col2; ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" ALTER COLUMN col1 TYPE integer; ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - ALTER COLUMN col1 SET STATISTICS -1; + ALTER COLUMN col1 DROP NOT NULL; ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - OPTIONS (SET schema_name 'test_public'); + ALTER COLUMN col1 SET STATISTICS 10; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_comment_add_columns.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_comment_add_columns.sql index 42d6f8dca6d..a7aaee89f00 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_comment_add_columns.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_comment_add_columns.sql @@ -3,8 +3,8 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL COLLATE pg_catalog."default" + col1 bigint NOT NULL, + col2 text COLLATE pg_catalog."default" ) SERVER test_fs_for_foreign_table; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_comment_add_columns_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_comment_add_columns_msql.sql index 50879691365..85e262c72ec 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_comment_add_columns_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_comment_add_columns_msql.sql @@ -1,8 +1,8 @@ -ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - ADD COLUMN col1 bigint NULL; +COMMENT ON FOREIGN TABLE public."FT1_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - ADD COLUMN col2 text NULL; + ADD COLUMN col1 bigint NOT NULL; -COMMENT ON FOREIGN TABLE public."FT1_$%{}[]()&*^!@""'`\/#" - IS 'Test Comment'; +ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" + ADD COLUMN col2 text; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_remove_opts_priv_cons.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_remove_opts_priv_cons.sql index b451db49ff4..f0e932f3fb6 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_remove_opts_priv_cons.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/alter_remove_opts_priv_cons.sql @@ -3,7 +3,7 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 integer NULL + col1 integer ) SERVER test_fs_for_foreign_table OPTIONS (table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/create_foreign_table_with_all_options.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/create_foreign_table_with_all_options.sql index 7d06685541c..e50fc1e7a07 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/create_foreign_table_with_all_options.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/create_foreign_table_with_all_options.sql @@ -3,8 +3,8 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL COLLATE pg_catalog."default" + col1 bigint, + col2 text COLLATE pg_catalog."default" ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/create_foreign_table_with_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/create_foreign_table_with_all_options_msql.sql index 13494a7936f..89a2842cc50 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/create_foreign_table_with_all_options_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/create_foreign_table_with_all_options_msql.sql @@ -1,6 +1,6 @@ CREATE FOREIGN TABLE public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL + col1 bigint, + col2 text ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/test_foreign_table.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/test_foreign_table.json index 43883e68148..92d79c7ef58 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/test_foreign_table.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/pg/default/test_foreign_table.json @@ -99,7 +99,8 @@ "ftsrvname": "test_fs_for_foreign_table", "columns": [] } - }, { + }, + { "type": "alter", "name": "Alter Foreign Table comment and add columns", "endpoint": "NODE-foreign_table.obj_id", @@ -111,7 +112,8 @@ "added": [{ "name":"col1", "cltype":"bigint", - "coloptions":[] + "coloptions":[], + "attnotnull": true },{ "name":"col2", "cltype":"text", @@ -121,7 +123,8 @@ }, "expected_sql_file": "alter_comment_add_columns.sql", "expected_msql_file": "alter_comment_add_columns_msql.sql" - },{ + }, + { "type": "alter", "name": "Alter Foreign Table add constraints and options", "endpoint": "NODE-foreign_table.obj_id", @@ -148,7 +151,8 @@ }, "expected_sql_file": "alter_add_cons_opts.sql", "expected_msql_file": "alter_add_cons_opts_msql.sql" - }, { + }, + { "type": "alter", "name": "Alter Foreign Table add privileges", "endpoint": "NODE-foreign_table.obj_id", @@ -169,7 +173,8 @@ }, "expected_sql_file": "alter_add_priv.sql", "expected_msql_file": "alter_add_priv_msql.sql" - }, { + }, + { "type": "alter", "name": "Alter Foreign Table change option and column", "endpoint": "NODE-foreign_table.obj_id", @@ -187,10 +192,11 @@ "name": "col1", "attnum": 1, "attoptions": null, + "attnotnull":false, + "attstattarget": 10, "collname": "", "coloptions": [], - "cltype": "integer", - "fulltype": "bigint" + "cltype": "integer" }], "deleted": [{ "name":"col2", @@ -200,7 +206,8 @@ }, "expected_sql_file": "alter_col_opts.sql", "expected_msql_file": "alter_col_opts_msql.sql" - }, { + }, + { "type": "alter", "name": "Alter Foreign Table remove option, constraint, privileges", "endpoint": "NODE-foreign_table.obj_id", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_add_cons_opts.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_add_cons_opts.sql index 40e0c4d37a4..5aa99086171 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_add_cons_opts.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_add_cons_opts.sql @@ -3,8 +3,8 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL COLLATE pg_catalog."default" + col1 bigint NOT NULL, + col2 text COLLATE pg_catalog."default" ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_add_priv.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_add_priv.sql index ad87901747c..b1bba941c3c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_add_priv.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_add_priv.sql @@ -3,8 +3,8 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL COLLATE pg_catalog."default" + col1 bigint NOT NULL, + col2 text COLLATE pg_catalog."default" ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_col_opts.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_col_opts.sql index 600619b0b25..7368467e571 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_col_opts.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_col_opts.sql @@ -3,7 +3,7 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 integer NULL + col1 integer ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'test_public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_col_opts_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_col_opts_msql.sql index 095712f7302..fe4c3113ae6 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_col_opts_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_col_opts_msql.sql @@ -1,14 +1,13 @@ ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - DROP COLUMN col2; + OPTIONS (SET schema_name 'test_public'); -ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - ALTER COLUMN col1 DROP NOT NULL; +ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" DROP COLUMN IF EXISTS col2; ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" ALTER COLUMN col1 TYPE integer; ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - ALTER COLUMN col1 SET STATISTICS -1; + ALTER COLUMN col1 DROP NOT NULL; ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - OPTIONS (SET schema_name 'test_public'); + ALTER COLUMN col1 SET STATISTICS 10; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_comment_add_columns.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_comment_add_columns.sql index df174955391..00fea0dce10 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_comment_add_columns.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_comment_add_columns.sql @@ -3,8 +3,8 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL COLLATE pg_catalog."default" + col1 bigint NOT NULL, + col2 text COLLATE pg_catalog."default" ) SERVER test_fs_for_foreign_table; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_comment_add_columns_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_comment_add_columns_msql.sql index 50879691365..85e262c72ec 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_comment_add_columns_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_comment_add_columns_msql.sql @@ -1,8 +1,8 @@ -ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - ADD COLUMN col1 bigint NULL; +COMMENT ON FOREIGN TABLE public."FT1_$%{}[]()&*^!@""'`\/#" + IS 'Test Comment'; ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" - ADD COLUMN col2 text NULL; + ADD COLUMN col1 bigint NOT NULL; -COMMENT ON FOREIGN TABLE public."FT1_$%{}[]()&*^!@""'`\/#" - IS 'Test Comment'; +ALTER FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#" + ADD COLUMN col2 text; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_remove_opts_priv_cons.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_remove_opts_priv_cons.sql index 879afd8fbec..69f3ff66944 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_remove_opts_priv_cons.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/alter_remove_opts_priv_cons.sql @@ -3,7 +3,7 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 integer NULL + col1 integer ) SERVER test_fs_for_foreign_table OPTIONS (table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/create_foreign_table_with_all_options.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/create_foreign_table_with_all_options.sql index a1ac8be3dfa..6706b378939 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/create_foreign_table_with_all_options.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/create_foreign_table_with_all_options.sql @@ -3,8 +3,8 @@ -- DROP FOREIGN TABLE IF EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"; CREATE FOREIGN TABLE IF NOT EXISTS public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL COLLATE pg_catalog."default" + col1 bigint, + col2 text COLLATE pg_catalog."default" ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/create_foreign_table_with_all_options_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/create_foreign_table_with_all_options_msql.sql index dd1f25434d3..8a5b5dcdc61 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/create_foreign_table_with_all_options_msql.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/create_foreign_table_with_all_options_msql.sql @@ -1,6 +1,6 @@ CREATE FOREIGN TABLE public."FT1_$%{}[]()&*^!@""'`\/#"( - col1 bigint NULL, - col2 text NULL + col1 bigint, + col2 text ) SERVER test_fs_for_foreign_table OPTIONS (schema_name 'public', table_name 'test_table'); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/test_foreign_table.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/test_foreign_table.json index addec340af0..77efbd33f59 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/test_foreign_table.json +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/foreign_tables/tests/ppas/default/test_foreign_table.json @@ -109,7 +109,8 @@ "added": [{ "name":"col1", "cltype":"bigint", - "coloptions":[] + "coloptions":[], + "attnotnull": true },{ "name":"col2", "cltype":"text", @@ -185,10 +186,11 @@ "name": "col1", "attnum": 1, "attoptions": null, + "attnotnull":false, + "attstattarget": 10, "collname": "", "coloptions": [], - "cltype": "integer", - "fulltype": "bigint" + "cltype": "integer" }], "deleted": [{ "name":"col2", diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.ui.js index 0f607232ab5..472f69a611e 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.ui.js @@ -82,16 +82,17 @@ export default class ColumnSchema extends BaseUISchema { } if(this.nodeInfo && ('schema' in this.nodeInfo)) { + if(this.isNew(state)) { + return false; + } + // We will disable control if it's system columns // inheritedfrom check is useful when we use this schema in table node // inheritedfrom has value then we should disable it - if(!_.isUndefined(state.inheritedfrom)) { + if (!isEmptyString(state.inheritedfrom)){ return true; } - if(this.isNew(state)) { - return false; - } // ie: it's position is less than 1 return !(!_.isUndefined(state.attnum) && state.attnum > 0); } 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 0aa68862a3a..d563820c5d3 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 @@ -139,12 +139,7 @@ def column_formatter(conn, tid, clid, data, edit_types_list=None, # We need to format variables according to client js collection if 'attoptions' in data and data['attoptions'] is not None: - spcoptions = [] - for spcoption in data['attoptions']: - k, v = spcoption.split('=') - spcoptions.append({'name': k, 'value': v}) - - data['attoptions'] = spcoptions + data['attoptions'] = parse_column_variables(data['attoptions']) # Need to format security labels according to client js collection if 'seclabels' in data and data['seclabels'] is not None: @@ -157,7 +152,7 @@ def column_formatter(conn, tid, clid, data, edit_types_list=None, # Get formatted Column Options if 'attfdwoptions' in data and data['attfdwoptions'] != '': - data['coloptions'] = _parse_options_for_column(data['attfdwoptions']) + data['coloptions'] = parse_options_for_column(data['attfdwoptions']) # We need to parse & convert ACL coming from database to json format SQL = render_template("/".join([template_path, 'acl.sql']), @@ -194,7 +189,7 @@ def column_formatter(conn, tid, clid, data, edit_types_list=None, return data -def _parse_options_for_column(db_variables): +def parse_options_for_column(db_variables): """ Function to format the output for variables. @@ -446,3 +441,13 @@ def fetch_length_precision(data): data['attprecision'] = None return data + + +def parse_column_variables(col_variables): + # We need to format variables according to client js collection + spcoptions = [] + if col_variables is not None: + for spcoption in col_variables: + k, v = spcoption.split('=') + spcoptions.append({'name': k, 'value': v}) + return spcoptions diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/columns/sql/14_plus/properties.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/columns/sql/14_plus/properties.sql index a980338e823..fe6d0376392 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/columns/sql/14_plus/properties.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/columns/sql/14_plus/properties.sql @@ -1,3 +1,18 @@ +WITH INH_TABLES AS + (SELECT + at.attname AS name, ph.inhparent AS inheritedid, ph.inhseqno, + pg_catalog.concat(nmsp_parent.nspname, '.',parent.relname ) AS inheritedfrom + FROM + pg_catalog.pg_attribute at + JOIN + pg_catalog.pg_inherits ph ON ph.inhparent = at.attrelid AND ph.inhrelid = 33896::oid + JOIN + pg_catalog.pg_class parent ON ph.inhparent = parent.oid + JOIN + pg_catalog.pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace + GROUP BY at.attname, ph.inhparent, ph.inhseqno, inheritedfrom + ORDER BY at.attname, ph.inhparent, ph.inhseqno, inheritedfrom + ) SELECT DISTINCT ON (att.attnum) att.attname as name, att.atttypid, att.attlen, att.attnum, att.attndims, att.atttypmod, att.attacl, att.attnotnull, att.attoptions, att.attfdwoptions, att.attstattarget, att.attstorage, att.attidentity, @@ -5,6 +20,8 @@ SELECT DISTINCT ON (att.attnum) att.attname as name, att.atttypid, att.attlen, a pg_catalog.format_type(ty.oid,NULL) AS typname, pg_catalog.format_type(ty.oid,att.atttypmod) AS displaytypname, pg_catalog.format_type(ty.oid,att.atttypmod) AS cltype, + inh.inheritedfrom, + inh.inheritedid, CASE WHEN ty.typelem > 0 THEN ty.typelem ELSE ty.oid END as elemoid, (SELECT nspname FROM pg_catalog.pg_namespace WHERE oid = ty.typnamespace) as typnspname, ty.typstorage AS defaultstorage, @@ -31,6 +48,7 @@ FROM pg_catalog.pg_attribute att LEFT OUTER JOIN pg_catalog.pg_namespace nspc ON coll.collnamespace=nspc.oid LEFT OUTER JOIN pg_catalog.pg_sequence seq ON cs.oid=seq.seqrelid LEFT OUTER JOIN pg_catalog.pg_class tab on tab.oid = att.attrelid + LEFT OUTER join INH_TABLES as INH ON att.attname = INH.name WHERE att.attrelid = {{tid}}::oid {% if clid %} AND att.attnum = {{clid}}::int