Fix drop/drop cascade for partitioned tables. Fixes #2550
parent
7aa7ea0fe2
commit
f06c3578f6
|
@ -1009,12 +1009,6 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
|||
scid: Schema ID
|
||||
tid: Table ID
|
||||
"""
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
cascade = True
|
||||
else:
|
||||
cascade = False
|
||||
|
||||
try:
|
||||
SQL = render_template(
|
||||
|
@ -1037,25 +1031,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings):
|
|||
)
|
||||
)
|
||||
|
||||
data = res['rows'][0]
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.table_template_path, 'delete.sql']),
|
||||
data=data, cascade=cascade,
|
||||
conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Table dropped"),
|
||||
data={
|
||||
'id': tid,
|
||||
'scid': scid
|
||||
}
|
||||
)
|
||||
return super(TableView, self).delete(gid, sid, did, scid, tid, res)
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
|
|
@ -179,6 +179,7 @@ class PartitionsView(BaseTableView, DataTypeReader, VacuumSettings):
|
|||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}],
|
||||
'nodes': [{'get': 'nodes'}, {'get': 'nodes'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
|
@ -579,5 +580,45 @@ class PartitionsView(BaseTableView, DataTypeReader, VacuumSettings):
|
|||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@BaseTableView.check_precondition
|
||||
def delete(self, gid, sid, did, scid, tid, ptid):
|
||||
"""
|
||||
This function will delete the table object
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
tid: Table ID
|
||||
"""
|
||||
|
||||
try:
|
||||
SQL = render_template(
|
||||
"/".join([self.partition_template_path, 'properties.sql']),
|
||||
did=did, scid=scid, tid=tid,ptid=ptid,
|
||||
datlastsysoid=self.datlastsysoid
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if not res['rows']:
|
||||
return make_json_response(
|
||||
success=0,
|
||||
errormsg=gettext(
|
||||
'Error: Object not found.'
|
||||
),
|
||||
info=gettext(
|
||||
'The specified partition could not be found.\n'
|
||||
)
|
||||
)
|
||||
|
||||
return super(PartitionsView, self).delete(
|
||||
gid, sid, did, scid, tid, res)
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
|
||||
PartitionsView.register_node_view(blueprint)
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
define([
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'underscore.string', 'pgadmin', 'pgadmin.browser', 'backform', 'alertify',
|
||||
'sources/alerts/alertify_wrapper',
|
||||
'pgadmin.browser.collection', 'pgadmin.browser.table.partition.utils'
|
||||
],
|
||||
function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
||||
function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify, AlertifyWrapper) {
|
||||
|
||||
if (!pgBrowser.Nodes['coll-partition']) {
|
||||
var databases = pgAdmin.Browser.Nodes['coll-partition'] =
|
||||
|
@ -163,7 +164,8 @@ function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||
dataType: "json",
|
||||
success: function(res) {
|
||||
if (res.success == 1) {
|
||||
alertify.success(res.info);
|
||||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.success(res.info);
|
||||
t.unload(i);
|
||||
t.setInode(i);
|
||||
t.deselect(i);
|
||||
|
@ -176,7 +178,8 @@ function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||
try {
|
||||
var err = $.parseJSON(xhr.responseText);
|
||||
if (err.success == 0) {
|
||||
alertify.error(err.errormsg);
|
||||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.error(err.errormsg);
|
||||
}
|
||||
} catch (e) {}
|
||||
t.unload(i);
|
||||
|
@ -216,9 +219,10 @@ function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||
dataType: "json",
|
||||
success: function(res) {
|
||||
if (res.success == 1) {
|
||||
alertify.success(res.info);
|
||||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.success(res.info);
|
||||
t.removeIcon(i);
|
||||
data.icon = 'icon-table';
|
||||
data.icon = 'icon-partition';
|
||||
t.addIcon(i, {icon: data.icon});
|
||||
t.unload(i);
|
||||
t.setInode(i);
|
||||
|
@ -233,7 +237,8 @@ function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||
try {
|
||||
var err = $.parseJSON(xhr.responseText);
|
||||
if (err.success == 0) {
|
||||
alertify.error(err.errormsg);
|
||||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.error(err.errormsg);
|
||||
}
|
||||
} catch (e) {}
|
||||
t.unload(i);
|
||||
|
@ -264,9 +269,10 @@ function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||
type:'DELETE',
|
||||
success: function(res) {
|
||||
if (res.success == 1) {
|
||||
alertify.success(res.info);
|
||||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.success(res.info);
|
||||
t.removeIcon(i);
|
||||
data.icon = 'icon-table';
|
||||
data.icon = 'icon-partition';
|
||||
t.addIcon(i, {icon: data.icon});
|
||||
t.unload(i);
|
||||
t.setInode(i);
|
||||
|
@ -281,7 +287,8 @@ function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||
try {
|
||||
var err = $.parseJSON(xhr.responseText);
|
||||
if (err.success == 0) {
|
||||
alertify.error(err.errormsg);
|
||||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.error(err.errormsg);
|
||||
}
|
||||
} catch (e) {}
|
||||
t.unload(i);
|
||||
|
@ -313,7 +320,8 @@ function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||
type:'PUT',
|
||||
success: function(res) {
|
||||
if (res.success == 1) {
|
||||
alertify.success(res.info);
|
||||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.success(res.info);
|
||||
var n = t.next(i);
|
||||
if (!n || !n.length) {
|
||||
n = t.prev(i);
|
||||
|
@ -332,7 +340,8 @@ function(gettext, url_for, $, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||
try {
|
||||
var err = $.parseJSON(xhr.responseText);
|
||||
if (err.success == 0) {
|
||||
alertify.error(err.errormsg);
|
||||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.error(err.errormsg);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
|
|
@ -172,6 +172,7 @@ define('pgadmin.node.table', [
|
|||
return false;
|
||||
|
||||
alertify.confirm(
|
||||
gettext('Truncate Table'),
|
||||
S(gettext('Are you sure you want to truncate table %s?')).sprintf(d.label).value(),
|
||||
function (e) {
|
||||
if (e) {
|
||||
|
@ -186,7 +187,7 @@ define('pgadmin.node.table', [
|
|||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.success(res.info);
|
||||
t.removeIcon(i);
|
||||
data.icon = 'icon-table';
|
||||
data.icon = data.is_partitioned ? 'icon-partition': 'icon-table';
|
||||
t.addIcon(i, {icon: data.icon});
|
||||
t.unload(i);
|
||||
t.setInode(i);
|
||||
|
@ -209,7 +210,8 @@ define('pgadmin.node.table', [
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, function() {}
|
||||
);
|
||||
},
|
||||
reset_table_stats: function(args) {
|
||||
var input = args || {},
|
||||
|
@ -235,7 +237,7 @@ define('pgadmin.node.table', [
|
|||
var alertifyWrapper = new AlertifyWrapper();
|
||||
alertifyWrapper.success(res.info);
|
||||
t.removeIcon(i);
|
||||
data.icon = 'icon-table';
|
||||
data.icon = data.is_partitioned ? 'icon-partition': 'icon-table';
|
||||
t.addIcon(i, {icon: data.icon});
|
||||
t.unload(i);
|
||||
t.setInode(i);
|
||||
|
|
|
@ -52,7 +52,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r
|
|||
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,
|
||||
(select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) AS typname,
|
||||
CASE WHEN typ.typname IS NOT NULL THEN (select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) ELSE typ.typname END 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,
|
||||
|
|
|
@ -51,7 +51,7 @@ SELECT rel.oid, rel.relname AS name, rel.reltablespace AS spcoid,rel.relacl AS r
|
|||
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,
|
||||
(select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) AS typname,
|
||||
CASE WHEN typ.typname IS NOT NULL THEN (select quote_ident(nspname) FROM pg_namespace WHERE oid = {{scid}}::oid )||'.'||quote_ident(typ.typname) ELSE typ.typname END 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,
|
||||
|
|
|
@ -2084,6 +2084,45 @@ class BaseTableView(PGChildNodeView):
|
|||
}
|
||||
)
|
||||
|
||||
def delete(self, gid, sid, did, scid, tid, res):
|
||||
"""
|
||||
This function will delete the table object
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
tid: Table ID
|
||||
"""
|
||||
|
||||
# Below will decide if it's simple drop or drop with cascade call
|
||||
if self.cmd == 'delete':
|
||||
# This is a cascade operation
|
||||
cascade = True
|
||||
else:
|
||||
cascade = False
|
||||
|
||||
data = res['rows'][0]
|
||||
|
||||
SQL = render_template(
|
||||
"/".join([self.table_template_path, 'delete.sql']),
|
||||
data=data, cascade=cascade,
|
||||
conn=self.conn
|
||||
)
|
||||
status, res = self.conn.execute_scalar(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
return make_json_response(
|
||||
success=1,
|
||||
info=gettext("Table dropped"),
|
||||
data={
|
||||
'id': tid,
|
||||
'scid': scid
|
||||
}
|
||||
)
|
||||
|
||||
def get_schema_and_table_name(self, tid):
|
||||
"""
|
||||
This function will fetch the schema qualified name of the
|
||||
|
|
Loading…
Reference in New Issue