Handle partitioned tables created "OF TYPE". Fixes #2545

This commit is contained in:
Akshay Joshi 2017-07-10 14:16:30 +01:00 committed by Dave Page
parent 6d3d2cd458
commit ed3cb7df41
6 changed files with 56 additions and 21 deletions

View File

@ -661,9 +661,18 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
if not status:
return internal_server_error(errormsg=res)
for row in rset['rows']:
# Get columns for all 'OF TYPES'.
SQL = render_template("/".join([self.table_template_path,
'get_columns_for_table.sql']),
tid=row['oid'])
status, type_cols = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=type_cols)
res.append(
{'label': row['typname'], 'value': row['typname'],
'tid': row['oid']
'tid': row['oid'], 'oftype_columns': type_cols['rows']
}
)
return make_json_response(

View File

@ -116,7 +116,9 @@ function(gettext, $, _, pgBrowser, Backform, Backgrid) {
custom_options: function() {
// We will add all the columns entered by user in table model
var columns = this.model.top.get('columns'),
added_columns_from_tables = [];
typename = this.model.top.get('typname'),
of_types_tables = this.model.top.of_types_tables,
added_columns_from_tables = [];
if (columns.length > 0) {
_.each(columns.models, function(m) {
@ -127,7 +129,21 @@ function(gettext, $, _, pgBrowser, Backform, Backgrid) {
);
}
});
} else if (!_.isUndefined(typename) && !_.isNull(typename)
&& !_.isUndefined(of_types_tables) && of_types_tables.length > 0) {
// Iterate through all the of_type tables
_.each(of_types_tables, function(type) {
if (type.label == typename) {
// Iterate all the columns of selected "OF TYPE".
_.each(type.oftype_columns, function(col) {
added_columns_from_tables.push(
{label: col.name, value: col.name, image:'icon-column'}
);
});
}
});
}
// Set the values in to options so that user can select
this.column.set('options', added_columns_from_tables);
},

View File

@ -708,7 +708,7 @@ define('pgadmin.node.table', [
id: 'typname', label: gettext('Of type'), type: 'text',
control: 'node-ajax-options', mode: ['properties', 'create', 'edit'],
disabled: 'checkOfType', url: 'get_oftype', group: gettext('Advanced'),
deps: ['coll_inherits', 'is_partitioned'], transform: function(data, cell) {
deps: ['coll_inherits'], transform: function(data, cell) {
var control = cell || this,
m = control.model;
m.of_types_tables = data;
@ -854,7 +854,7 @@ define('pgadmin.node.table', [
subnode: Backform.PartitionKeyModel,
editable: true, type: 'collection',
group: 'partition', mode: ['create'],
deps: ['is_partitioned', 'partition_type'],
deps: ['is_partitioned', 'partition_type', 'typname'],
canEdit: false, canDelete: true,
control: 'sub-node-collection',
canAdd: function(m) {
@ -863,16 +863,33 @@ define('pgadmin.node.table', [
return false;
},
canAddRow: function(m) {
var columns = m.get('columns');
var max_row_count = 1000;
var columns = m.get('columns'),
typename = m.get('typname'),
columns_exist= false;
var max_row_count = 1000;
if (m.get('partition_type') && m.get('partition_type') == 'list')
max_row_count = 1;
/* If columns are not specified by the user then it may be
* possible that he/she selected 'OF TYPE', so we should check
* for that as well.
*/
if (columns.length <= 0 && !_.isUndefined(typename)
&& !_.isNull(typename) && m.of_types_tables.length > 0){
_.each(m.of_types_tables, function(data) {
if (data.label == typename && data.oftype_columns.length > 0){
columns_exist = true;
}
});
} else if (columns.length > 0) {
columns_exist = _.some(columns.pluck('name'));
}
return (m.get('partition_keys') &&
m.get('partition_keys').length < max_row_count &&
_.some(columns.pluck('name'))
m.get('partition_keys').length < max_row_count && columns_exist
);
},
visible: function(m) {
if(!_.isUndefined(m.node_info) && !_.isUndefined(m.node_info.server)
@ -938,7 +955,7 @@ define('pgadmin.node.table', [
subnode: Backform.PartitionsModel,
editable: true, type: 'collection',
group: 'partition', mode: ['edit', 'create'],
deps: ['is_partitioned', 'partition_type'],
deps: ['is_partitioned', 'partition_type', 'typname'],
canEdit: false, canDelete: true,
customDeleteTitle: gettext('Detach Partition'),
customDeleteMsg: gettext('Are you sure you wish to detach this partition?'),
@ -1181,14 +1198,6 @@ define('pgadmin.node.table', [
},
// We will disable it if Inheritance is defined
checkOfType: function(m) {
// Disabled if it is partitioned table
if (m.get('is_partitioned')) {
setTimeout( function() {
m.set('typname', undefined);
}, 10);
return true;
}
//coll_inherits || typname
if(!m.inSchemaWithModelCheck.apply(this, [m]) &&
(_.isUndefined(m.get('coll_inherits')) ||

View File

@ -51,7 +51,8 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age,
array_to_string(rel.reloptions, ',') AS table_vacuum_settings_str,
array_to_string(tst.reloptions, ',') AS toast_table_vacuum_settings_str,
rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, rel.reloftype, typ.typname,
rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, rel.reloftype,
(select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) AS typname,
(CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable,
-- Added for pgAdmin4
(CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)'))::boolean THEN true ELSE false END) AS autovacuum_custom,

View File

@ -50,7 +50,8 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r
substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age,
array_to_string(rel.reloptions, ',') AS table_vacuum_settings_str,
array_to_string(tst.reloptions, ',') AS toast_table_vacuum_settings_str,
rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, rel.reloftype, typ.typname,
rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions, rel.reloftype,
(select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) AS typname,
(CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable,
-- Added for pgAdmin4
(CASE WHEN (substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)'))::boolean THEN true ELSE false END) AS autovacuum_custom,

View File

@ -57,9 +57,8 @@ CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE {{conn|qtIdent(data
{{CONSTRAINTS.EXCLUDE(conn, data.exclude_constraint)}}{% endif %}
{% if data.like_relation or data.coll_inherits or data.columns|length > 0 or data.primary_key|length > 0 or data.unique_constraint|length > 0 or data.foreign_key|length > 0 or data.check_constraint|length > 0 or data.exclude_constraint|length > 0 %}
){% if data.relkind is defined and data.relkind == 'p' %} PARTITION BY {{ data.partition_scheme }} {% endif %}
){% endif %}{% if data.relkind is defined and data.relkind == 'p' %} PARTITION BY {{ data.partition_scheme }} {% endif %}
{% endif %}
{### If we are inheriting it from another table(s) ###}
{% if data.coll_inherits %}
INHERITS ({% for val in data.coll_inherits %}{% if loop.index != 1 %}, {% endif %}{{val}}{% endfor %})