mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Add support for primary key, foreign key, unique key, indexes and triggers on partitioned tables for PG/EPAS 11. Fixes #3412
This commit is contained in:
committed by
Akshay Joshi
parent
0138dee989
commit
0cb25bde63
BIN
docs/en_US/images/table_partition.png
Normal file
BIN
docs/en_US/images/table_partition.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 321 KiB |
@@ -13,6 +13,7 @@ Features
|
||||
| `Feature #2214 <https://redmine.postgresql.org/issues/2214>`_ - Add support for SCRAM password changes (requires psycopg2 >= 2.8).
|
||||
| `Feature #3074 <https://redmine.postgresql.org/issues/3074>`_ - Add support for reset saved password.
|
||||
| `Feature #3397 <https://redmine.postgresql.org/issues/3397>`_ - Add support for Trigger and JIT stats in the graphical query plan viewer.
|
||||
| `Feature #3412 <https://redmine.postgresql.org/issues/3412>`_ - Add support for primary key, foreign key, unique key, indexes and triggers on partitioned tables for PG/EPAS 11.
|
||||
| `Feature #3506 <https://redmine.postgresql.org/issues/3506>`_ - Allow the user to specify a fixed port number in the runtime to aid cookie whitelisting etc.
|
||||
| `Feature #3510 <https://redmine.postgresql.org/issues/3510>`_ - Add a menu option to the runtime to copy the appserver URL to the clipboard.
|
||||
|
||||
|
||||
@@ -256,6 +256,31 @@ Use the fields in the **Like** box to specify which attributes of an existing ta
|
||||
* Move the *With storage?* switch to the *Yes* position to copy storage settings.
|
||||
* Move the *With comments?* switch to the *Yes* position to copy comments.
|
||||
|
||||
With PostgreSQL 10 forward, the *Partition* tab will be visible.
|
||||
|
||||
Click the *Partition* tab to continue.
|
||||
|
||||
.. image:: images/table_partition.png
|
||||
:alt: Table dialog partition tab
|
||||
|
||||
Use the fields in the *partition* tab to create the partitions for the table:
|
||||
|
||||
* Select a partition type from the *Partition Type* selection box. There are 3 options available; Range, List and Hash. Hash option will only enable for PostgreSQL version >= 11.
|
||||
|
||||
Use the *Partition Keys* panel to define the partition keys. Click the *Add* icon (+) to add each partition keys selection:
|
||||
|
||||
* Select a partition key type in the *Keytype* field.
|
||||
* Select a partition column in the *Column* field if Column option selected for *Keytype* field .
|
||||
* Specify the expression in the *Expression* field if Expression option selected for the *Keytype* field.
|
||||
|
||||
Use the *Partitions* panel to define the partitions of a table. Click the *Add* icon (+) to add each partition:
|
||||
|
||||
* Move the *Operation* switch to *attach* to attach the partition, by default it is *create*.
|
||||
* Use the *Name* field to add the name of the partition.
|
||||
* If partition type is Range then *From* and *To* fields will be enabled.
|
||||
* If partition type is List then *In* field will be enabled.
|
||||
* If partition type is Hash then *Modulus* and *Remainder* fields will be enabled.
|
||||
|
||||
Click the *Parameter* tab to continue.
|
||||
|
||||
.. image:: images/table_parameter.png
|
||||
|
||||
@@ -205,7 +205,8 @@ define('pgadmin.node.column', [
|
||||
m.top.get('primary_key').length > 0 &&
|
||||
!_.isUndefined(m.top.get('primary_key').first().get('oid'))
|
||||
) || (
|
||||
m.top.has('is_partitioned') && m.top.get('is_partitioned')
|
||||
m.top.has('is_partitioned') && m.top.get('is_partitioned') &&
|
||||
m.top.node_info.server && m.top.node_info.server.version < 11000
|
||||
))
|
||||
) {
|
||||
return true;
|
||||
@@ -235,7 +236,8 @@ define('pgadmin.node.column', [
|
||||
|
||||
// If table is partitioned table then disable
|
||||
if (m.top && !_.isUndefined(m.top.get('is_partitioned')) &&
|
||||
m.top.get('is_partitioned'))
|
||||
m.top.get('is_partitioned') && m.top.node_info.server &&
|
||||
m.top.node_info.server.version < 11000)
|
||||
{
|
||||
setTimeout(function () {
|
||||
m.set('is_primary_key', false);
|
||||
|
||||
@@ -1061,13 +1061,15 @@ define('pgadmin.node.foreign_key', [
|
||||
|
||||
var t = pgBrowser.tree, i = item, d = itemData, parents = [],
|
||||
immediate_parent_table_found = false,
|
||||
is_immediate_parent_table_partitioned = false;
|
||||
is_immediate_parent_table_partitioned = false,
|
||||
s_version = this.getTreeNodeHierarchy(i).server.version;
|
||||
|
||||
// To iterate over tree to check parent node
|
||||
while (i) {
|
||||
// If table is partitioned table then return false
|
||||
if (!immediate_parent_table_found && (d._type == 'table' || d._type == 'partition')) {
|
||||
immediate_parent_table_found = true;
|
||||
if ('is_partitioned' in d && d.is_partitioned) {
|
||||
if ('is_partitioned' in d && d.is_partitioned && s_version < 110000) {
|
||||
is_immediate_parent_table_partitioned = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,14 +44,15 @@ define('pgadmin.node.primary_key', [
|
||||
|
||||
var t = pgBrowser.tree, i = item, d = itemData, parents = [],
|
||||
immediate_parent_table_found = false,
|
||||
is_immediate_parent_table_partitioned = false;
|
||||
is_immediate_parent_table_partitioned = false,
|
||||
s_version = this.getTreeNodeHierarchy(i).server.version;
|
||||
|
||||
// To iterate over tree to check parent node
|
||||
while (i) {
|
||||
// If table is partitioned table then return false
|
||||
if (!immediate_parent_table_found && (d._type == 'table' || d._type == 'partition')) {
|
||||
immediate_parent_table_found = true;
|
||||
if ('is_partitioned' in d && d.is_partitioned) {
|
||||
if ('is_partitioned' in d && d.is_partitioned && s_version < 110000) {
|
||||
is_immediate_parent_table_partitioned = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,14 +44,15 @@ define('pgadmin.node.unique_constraint', [
|
||||
|
||||
var t = pgBrowser.tree, i = item, d = itemData, parents = [],
|
||||
immediate_parent_table_found = false,
|
||||
is_immediate_parent_table_partitioned = false;
|
||||
is_immediate_parent_table_partitioned = false,
|
||||
s_version = this.getTreeNodeHierarchy(i).server.version;
|
||||
|
||||
// To iterate over tree to check parent node
|
||||
while (i) {
|
||||
// If table is partitioned table then return false
|
||||
if (!immediate_parent_table_found && (d._type == 'table' || d._type == 'partition')) {
|
||||
immediate_parent_table_found = true;
|
||||
if ('is_partitioned' in d && d.is_partitioned) {
|
||||
if ('is_partitioned' in d && d.is_partitioned && s_version < 110000) {
|
||||
is_immediate_parent_table_partitioned = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +75,9 @@ class IndexesModule(CollectionNodeModule):
|
||||
if super(IndexesModule, self).BackendSupported(manager, **kwargs):
|
||||
conn = manager.connection(did=kwargs['did'])
|
||||
|
||||
# In case of partitioned table return false.
|
||||
if 'tid' in kwargs and manager.version >= 100000:
|
||||
# If PG version > 100000 and < 110000 then index is
|
||||
# not supported for partitioned table.
|
||||
if 'tid' in kwargs and 100000 <= manager.version < 110000:
|
||||
return not backend_supported(self, manager, **kwargs)
|
||||
|
||||
if 'vid' not in kwargs:
|
||||
|
||||
@@ -560,14 +560,15 @@ define('pgadmin.node.index', [
|
||||
|
||||
var t = pgBrowser.tree, i = item, d = itemData, parents = [],
|
||||
immediate_parent_table_found = false,
|
||||
is_immediate_parent_table_partitioned = false;
|
||||
is_immediate_parent_table_partitioned = false,
|
||||
s_version = this.getTreeNodeHierarchy(i).server.version;
|
||||
// To iterate over tree to check parent node
|
||||
while (i) {
|
||||
// Do not allow creating index on partitioned tables.
|
||||
if (!immediate_parent_table_found &&
|
||||
_.indexOf(['table', 'partition'], d._type) > -1) {
|
||||
immediate_parent_table_found = true;
|
||||
if ('is_partitioned' in d && d.is_partitioned) {
|
||||
if ('is_partitioned' in d && d.is_partitioned && s_version < 110000) {
|
||||
is_immediate_parent_table_partitioned = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +237,8 @@ define('pgadmin.node.table_partition_utils', [
|
||||
values_from: undefined,
|
||||
values_to: undefined,
|
||||
values_in: undefined,
|
||||
values_modulus: undefined,
|
||||
values_remainder: undefined,
|
||||
},
|
||||
keys:['partition_name'],
|
||||
schema: [{
|
||||
@@ -252,7 +254,7 @@ define('pgadmin.node.table_partition_utils', [
|
||||
},
|
||||
},{
|
||||
id: 'partition_name', label: gettext('Name'), type: 'text', cell:'string',
|
||||
cellHeaderClasses: 'width_percent_25',
|
||||
cellHeaderClasses: 'width_percent_15',
|
||||
editable: function(m) {
|
||||
if (m instanceof Backbone.Model && m.isNew())
|
||||
return true;
|
||||
@@ -261,11 +263,11 @@ define('pgadmin.node.table_partition_utils', [
|
||||
},{
|
||||
id: 'values_from', label: gettext('From'), type:'text',
|
||||
cell:Backgrid.Extension.StringDepCell,
|
||||
cellHeaderClasses: 'width_percent_20',
|
||||
cellHeaderClasses: 'width_percent_15',
|
||||
editable: function(m) {
|
||||
if(m.handler && m.handler.top &&
|
||||
m.handler.top.attributes &&
|
||||
m.handler.top.attributes.partition_type == 'range' &&
|
||||
m.handler.top.attributes.partition_type === 'range' &&
|
||||
m instanceof Backbone.Model && m.isNew())
|
||||
return true;
|
||||
return false;
|
||||
@@ -273,11 +275,11 @@ define('pgadmin.node.table_partition_utils', [
|
||||
},{
|
||||
id: 'values_to', label: gettext('To'), type:'text',
|
||||
cell:Backgrid.Extension.StringDepCell,
|
||||
cellHeaderClasses: 'width_percent_20',
|
||||
cellHeaderClasses: 'width_percent_15',
|
||||
editable: function(m) {
|
||||
if(m.handler && m.handler.top &&
|
||||
m.handler.top.attributes &&
|
||||
m.handler.top.attributes.partition_type == 'range' &&
|
||||
m.handler.top.attributes.partition_type === 'range' &&
|
||||
m instanceof Backbone.Model && m.isNew())
|
||||
return true;
|
||||
return false;
|
||||
@@ -285,11 +287,35 @@ define('pgadmin.node.table_partition_utils', [
|
||||
},{
|
||||
id: 'values_in', label: gettext('In'), type:'text',
|
||||
cell:Backgrid.Extension.StringDepCell,
|
||||
cellHeaderClasses: 'width_percent_25',
|
||||
cellHeaderClasses: 'width_percent_15',
|
||||
editable: function(m) {
|
||||
if(m.handler && m.handler.top &&
|
||||
m.handler.top.attributes &&
|
||||
m.handler.top.attributes.partition_type == 'list' &&
|
||||
m.handler.top.attributes.partition_type === 'list' &&
|
||||
m instanceof Backbone.Model && m.isNew())
|
||||
return true;
|
||||
return false;
|
||||
},
|
||||
},{
|
||||
id: 'values_modulus', label: gettext('Modulus'), type:'int',
|
||||
cell:Backgrid.Extension.StringDepCell,
|
||||
cellHeaderClasses: 'width_percent_15',
|
||||
editable: function(m) {
|
||||
if(m.handler && m.handler.top &&
|
||||
m.handler.top.attributes &&
|
||||
m.handler.top.attributes.partition_type === 'hash' &&
|
||||
m instanceof Backbone.Model && m.isNew())
|
||||
return true;
|
||||
return false;
|
||||
},
|
||||
},{
|
||||
id: 'values_remainder', label: gettext('Remainder'), type:'int',
|
||||
cell:Backgrid.Extension.StringDepCell,
|
||||
cellHeaderClasses: 'width_percent_15 width_percent_20',
|
||||
editable: function(m) {
|
||||
if(m.handler && m.handler.top &&
|
||||
m.handler.top.attributes &&
|
||||
m.handler.top.attributes.partition_type === 'hash' &&
|
||||
m instanceof Backbone.Model && m.isNew())
|
||||
return true;
|
||||
return false;
|
||||
@@ -300,6 +326,8 @@ define('pgadmin.node.table_partition_utils', [
|
||||
values_from = this.get('values_from'),
|
||||
values_to = this.get('values_to'),
|
||||
values_in = this.get('values_in'),
|
||||
values_modulus = this.get('values_modulus'),
|
||||
values_remainder = this.get('values_remainder'),
|
||||
msg;
|
||||
|
||||
// Have to clear existing validation before initiating current state
|
||||
@@ -307,31 +335,43 @@ define('pgadmin.node.table_partition_utils', [
|
||||
this.errorModel.clear();
|
||||
|
||||
if (_.isUndefined(partition_name) || _.isNull(partition_name) ||
|
||||
String(partition_name).replace(/^\s+|\s+$/g, '') == '') {
|
||||
String(partition_name).replace(/^\s+|\s+$/g, '') === '') {
|
||||
msg = gettext('Partition name cannot be empty.');
|
||||
this.errorModel.set('partition_name', msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (this.top.get('partition_type') == 'range') {
|
||||
if (this.top.get('partition_type') === 'range') {
|
||||
if (_.isUndefined(values_from) || _.isNull(values_from) ||
|
||||
String(values_from).replace(/^\s+|\s+$/g, '') == '') {
|
||||
String(values_from).replace(/^\s+|\s+$/g, '') === '') {
|
||||
msg = gettext('For range partition From field cannot be empty.');
|
||||
this.errorModel.set('values_from', msg);
|
||||
return msg;
|
||||
} else if (_.isUndefined(values_to) || _.isNull(values_to) ||
|
||||
String(values_to).replace(/^\s+|\s+$/g, '') == '') {
|
||||
String(values_to).replace(/^\s+|\s+$/g, '') === '') {
|
||||
msg = gettext('For range partition To field cannot be empty.');
|
||||
this.errorModel.set('values_to', msg);
|
||||
return msg;
|
||||
}
|
||||
} else if (this.top.get('partition_type') == 'list') {
|
||||
} else if (this.top.get('partition_type') === 'list') {
|
||||
if (_.isUndefined(values_in) || _.isNull(values_in) ||
|
||||
String(values_in).replace(/^\s+|\s+$/g, '') == '') {
|
||||
String(values_in).replace(/^\s+|\s+$/g, '') === '') {
|
||||
msg = gettext('For list partition In field cannot be empty.');
|
||||
this.errorModel.set('values_in', msg);
|
||||
return msg;
|
||||
}
|
||||
} else if (this.top.get('partition_type') === 'hash') {
|
||||
if (_.isUndefined(values_modulus) || _.isNull(values_modulus) ||
|
||||
String(values_modulus).replace(/^\s+|\s+$/g, '') === '') {
|
||||
msg = gettext('For hash partition Modulus field cannot be empty.');
|
||||
this.errorModel.set('values_modulus', msg);
|
||||
return msg;
|
||||
} else if (_.isUndefined(values_remainder) || _.isNull(values_remainder) ||
|
||||
String(values_remainder).replace(/^\s+|\s+$/g, '') === '') {
|
||||
msg = gettext('For hash partition Remainder field cannot be empty.');
|
||||
this.errorModel.set('values_remainder', msg);
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -593,7 +593,9 @@ define('pgadmin.node.table', [
|
||||
control: 'unique-col-collection',
|
||||
columns : ['name', 'columns'],
|
||||
canAdd: function(m) {
|
||||
if (m.get('is_partitioned')) {
|
||||
if (m.get('is_partitioned') && !_.isUndefined(m.top.node_info) && !_.isUndefined(m.top.node_info.server)
|
||||
&& !_.isUndefined(m.top.node_info.server.version) &&
|
||||
m.top.node_info.server.version < 110000) {
|
||||
setTimeout(function() {
|
||||
var coll = m.get('primary_key');
|
||||
coll.remove(coll.filter(function() { return true; }));
|
||||
@@ -620,7 +622,9 @@ define('pgadmin.node.table', [
|
||||
canEdit: true, canDelete: true, deps:['is_partitioned'],
|
||||
control: 'unique-col-collection',
|
||||
canAdd: function(m) {
|
||||
if (m.get('is_partitioned')) {
|
||||
if (m.get('is_partitioned') && !_.isUndefined(m.top.node_info) && !_.isUndefined(m.top.node_info.server)
|
||||
&& !_.isUndefined(m.top.node_info.server.version) &&
|
||||
m.top.node_info.server.version < 110000) {
|
||||
setTimeout(function() {
|
||||
var coll = m.get('foreign_key');
|
||||
coll.remove(coll.filter(function() { return true; }));
|
||||
@@ -656,7 +660,8 @@ define('pgadmin.node.table', [
|
||||
control: 'unique-col-collection',
|
||||
columns : ['name', 'columns'],
|
||||
canAdd: function(m) {
|
||||
if (m.get('is_partitioned')) {
|
||||
if (m.get('is_partitioned') && !_.isUndefined(m.node_info) && !_.isUndefined(m.node_info.server)
|
||||
&& !_.isUndefined(m.node_info.server.version) && m.node_info.server.version < 110000) {
|
||||
setTimeout(function() {
|
||||
var coll = m.get('unique_constraint');
|
||||
coll.remove(coll.filter(function() { return true; }));
|
||||
@@ -834,11 +839,22 @@ define('pgadmin.node.table', [
|
||||
id: 'partition_type', label:gettext('Partition Type'),
|
||||
editable: false, type: 'select2', select2: {allowClear: false},
|
||||
group: 'partition', deps: ['is_partitioned'],
|
||||
options:[{
|
||||
label: gettext('Range'), value: 'range',
|
||||
},{
|
||||
label: gettext('List'), value: 'list',
|
||||
}],
|
||||
options: function() {
|
||||
var options = [{
|
||||
label: gettext('Range'), value: 'range',
|
||||
},{
|
||||
label: gettext('List'), value: 'list',
|
||||
}];
|
||||
|
||||
if(!_.isUndefined(this.node_info) && !_.isUndefined(this.node_info.server)
|
||||
&& !_.isUndefined(this.node_info.server.version) &&
|
||||
this.node_info.server.version >= 110000) {
|
||||
options.push({
|
||||
label: gettext('Hash'), value: 'hash',
|
||||
});
|
||||
}
|
||||
return options;
|
||||
},
|
||||
mode:['create'],
|
||||
visible: function(m) {
|
||||
if(!_.isUndefined(m.node_info) && !_.isUndefined(m.node_info.server)
|
||||
@@ -963,7 +979,7 @@ define('pgadmin.node.table', [
|
||||
canEdit: false, canDelete: true,
|
||||
customDeleteTitle: gettext('Detach Partition'),
|
||||
customDeleteMsg: gettext('Are you sure you wish to detach this partition?'),
|
||||
columns:['is_attach', 'partition_name', 'values_from', 'values_to', 'values_in'],
|
||||
columns:['is_attach', 'partition_name', 'values_from', 'values_to', 'values_in', 'values_modulus', 'values_remainder'],
|
||||
control: Backform.SubNodeCollectionControl.extend({
|
||||
row: Backgrid.PartitionRow,
|
||||
initialize: function() {
|
||||
@@ -1040,6 +1056,8 @@ define('pgadmin.node.table', [
|
||||
'</li><li> ',
|
||||
gettext('In: Enabled for list partition. Values must be comma(,) separated and quoted with single quote.'),
|
||||
'</li></ul></li></ul>',
|
||||
gettext('Modulus/Remainder: Enabled for hash partition.'),
|
||||
'</li></ul></li></ul>',
|
||||
].join(''),
|
||||
visible: function(m) {
|
||||
if(!_.isUndefined(m.node_info) && !_.isUndefined(m.node_info.server)
|
||||
|
||||
@@ -36,6 +36,12 @@ class TableAddTestCase(BaseTestGenerator):
|
||||
server_min_version=100000,
|
||||
partition_type='list'
|
||||
)
|
||||
),
|
||||
('Create Hash partitioned table with 2 partitions',
|
||||
dict(url='/browser/table/obj/',
|
||||
server_min_version=110000,
|
||||
partition_type='hash'
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
@@ -93,13 +99,14 @@ class TableAddTestCase(BaseTestGenerator):
|
||||
"attoptions": [],
|
||||
"seclabels": []
|
||||
},
|
||||
{"name": "DOJ",
|
||||
"cltype": "date",
|
||||
"attacl": [],
|
||||
"is_primary_key": False,
|
||||
"attoptions": [],
|
||||
"seclabels": []
|
||||
}
|
||||
{
|
||||
"name": "DOJ",
|
||||
"cltype": "date",
|
||||
"attacl": [],
|
||||
"is_primary_key": False,
|
||||
"attoptions": [],
|
||||
"seclabels": []
|
||||
}
|
||||
],
|
||||
"exclude_constraint": [],
|
||||
"fillfactor": "",
|
||||
@@ -208,7 +215,9 @@ class TableAddTestCase(BaseTestGenerator):
|
||||
'is_attach': False,
|
||||
'partition_name': 'emp_2011'
|
||||
}]
|
||||
else:
|
||||
data['partition_keys'] = \
|
||||
[{'key_type': 'column', 'pt_column': 'DOJ'}]
|
||||
elif self.partition_type == 'list':
|
||||
data['partitions'] = \
|
||||
[{'values_in': "'2012-01-01', '2012-12-31'",
|
||||
'is_attach': False,
|
||||
@@ -218,8 +227,22 @@ class TableAddTestCase(BaseTestGenerator):
|
||||
'is_attach': False,
|
||||
'partition_name': 'emp_2013'
|
||||
}]
|
||||
data['partition_keys'] = \
|
||||
[{'key_type': 'column', 'pt_column': 'DOJ'}]
|
||||
data['partition_keys'] = \
|
||||
[{'key_type': 'column', 'pt_column': 'DOJ'}]
|
||||
else:
|
||||
data['partitions'] = \
|
||||
[{'values_modulus': "24",
|
||||
'values_remainder': "3",
|
||||
'is_attach': False,
|
||||
'partition_name': 'emp_2016'
|
||||
},
|
||||
{'values_modulus': "8",
|
||||
'values_remainder': "2",
|
||||
'is_attach': False,
|
||||
'partition_name': 'emp_2017'
|
||||
}]
|
||||
data['partition_keys'] = \
|
||||
[{'key_type': 'column', 'pt_column': 'empno'}]
|
||||
|
||||
# Add table
|
||||
response = self.tester.post(
|
||||
|
||||
@@ -204,7 +204,9 @@ define('pgadmin.node.trigger', [
|
||||
disabled: function(m) {
|
||||
// Disabled if table is a partitioned table.
|
||||
if (_.has(m, 'node_info') && _.has(m.node_info, 'table') &&
|
||||
_.has(m.node_info.table, 'is_partitioned') && m.node_info.table.is_partitioned)
|
||||
_.has(m.node_info.table, 'is_partitioned') &&
|
||||
m.node_info.table.is_partitioned && m.node_info.server.version < 110000
|
||||
)
|
||||
{
|
||||
setTimeout(function(){
|
||||
m.set('is_row_trigger', false);
|
||||
|
||||
@@ -874,6 +874,7 @@ class BaseTableView(PGChildNodeView, BasePartitionTable):
|
||||
# Table & Schema declaration so that we can use them in child nodes
|
||||
schema = data['schema']
|
||||
table = data['name']
|
||||
is_partitioned = 'is_partitioned' in data and data['is_partitioned']
|
||||
|
||||
data = self._formatter(did, scid, tid, data)
|
||||
|
||||
@@ -1139,7 +1140,7 @@ class BaseTableView(PGChildNodeView, BasePartitionTable):
|
||||
# 5) Reverse engineered sql for PARTITIONS
|
||||
##########################################
|
||||
"""
|
||||
if 'is_partitioned' in data and data['is_partitioned']:
|
||||
if is_partitioned:
|
||||
SQL = render_template("/".join([self.partition_template_path,
|
||||
'nodes.sql']),
|
||||
scid=scid, tid=tid)
|
||||
@@ -1211,6 +1212,9 @@ class BaseTableView(PGChildNodeView, BasePartitionTable):
|
||||
elif 'partition_type' in data \
|
||||
and data['partition_type'] == 'list':
|
||||
partition_scheme = 'LIST ('
|
||||
elif 'partition_type' in data \
|
||||
and data['partition_type'] == 'hash':
|
||||
partition_scheme = 'HASH ('
|
||||
|
||||
for row in data['partition_keys']:
|
||||
if row['key_type'] == 'column':
|
||||
@@ -2205,7 +2209,7 @@ class BaseTableView(PGChildNodeView, BasePartitionTable):
|
||||
'values_from': range_from,
|
||||
'values_to': range_to
|
||||
})
|
||||
else:
|
||||
elif data['partition_type'] == 'list':
|
||||
range_part = \
|
||||
row['partition_value'].split('FOR VALUES IN (')[1]
|
||||
|
||||
@@ -2215,6 +2219,20 @@ class BaseTableView(PGChildNodeView, BasePartitionTable):
|
||||
'partition_name': partition_name,
|
||||
'values_in': range_in
|
||||
})
|
||||
else:
|
||||
range_part = row['partition_value'].split(
|
||||
'FOR VALUES WITH (')[1].split(",")
|
||||
range_modulus = range_part[0].strip().strip(
|
||||
"modulus").strip()
|
||||
range_remainder = range_part[1].strip().\
|
||||
strip(" remainder").strip(")").strip()
|
||||
|
||||
partitions.append({
|
||||
'oid': row['oid'],
|
||||
'partition_name': partition_name,
|
||||
'values_modulus': range_modulus,
|
||||
'values_remainder': range_remainder
|
||||
})
|
||||
|
||||
data['partitions'] = partitions
|
||||
|
||||
@@ -2256,10 +2274,26 @@ class BaseTableView(PGChildNodeView, BasePartitionTable):
|
||||
|
||||
part_data['partition_value'] = 'FOR VALUES FROM (' + from_str \
|
||||
+ ') TO (' + to_str + ')'
|
||||
else:
|
||||
|
||||
elif partitions['partition_type'] == 'list':
|
||||
range_in = row['values_in'].split(',')
|
||||
in_str = ', '.join("{0}".format(item) for item in range_in)
|
||||
part_data['partition_value'] = 'FOR VALUES IN (' + in_str + ')'
|
||||
part_data['partition_value'] = 'FOR VALUES IN (' + in_str\
|
||||
+ ')'
|
||||
|
||||
else:
|
||||
range_modulus = row['values_modulus'].split(',')
|
||||
range_remainder = row['values_remainder'].split(',')
|
||||
|
||||
modulus_str = ', '.join("{0}".format(item) for item in
|
||||
range_modulus)
|
||||
remainder_str = ', '.join("{0}".format(item) for item in
|
||||
range_remainder)
|
||||
|
||||
part_data['partition_value'] = 'FOR VALUES WITH (MODULUS '\
|
||||
+ modulus_str \
|
||||
+ ', REMAINDER ' +\
|
||||
remainder_str + ')'
|
||||
|
||||
if 'is_attach' in row and row['is_attach']:
|
||||
partition_sql = render_template(
|
||||
|
||||
Reference in New Issue
Block a user