Added support to create the Partitioned table should be created using COLLATE and opclass. Fixes #2546

pull/61/head
Pradip Parkale 2021-09-09 16:26:23 +05:30 committed by Akshay Joshi
parent 02ed2289e6
commit dbf78bf214
28 changed files with 1346 additions and 27 deletions

View File

@ -21,4 +21,5 @@ Housekeeping
Bug fixes
*********
| `Issue #2546 <https://redmine.postgresql.org/issues/2546>`_ - Added support to create the Partitioned table should be created using COLLATE and opclass.
| `Issue #6712 <https://redmine.postgresql.org/issues/6712>`_ - Fixed an issue where collapse and expand arrows mismatch in case of nested IF.

View File

@ -283,7 +283,8 @@ class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare):
'update_sql': [{'get': 'update_sql'}],
'delete_sql': [{'get': 'delete_sql'}],
'count_rows': [{'get': 'count_rows'}],
'compare': [{'get': 'compare'}, {'get': 'compare'}]
'compare': [{'get': 'compare'}, {'get': 'compare'}],
'get_op_class': [{'get': 'get_op_class'}, {'get': 'get_op_class'}],
})
@BaseTableView.check_precondition
@ -597,6 +598,38 @@ class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare):
gid, sid, did, scid, tid, res=res
)
@BaseTableView.check_precondition
def get_op_class(self, gid, sid, did, scid, tid=None):
"""
This function will return list of op_class method
for each access methods available via AJAX response
"""
res = dict()
try:
# for row in rset['rows']:
# # Fetching all the op_classes for each access method
SQL = render_template(
"/".join([self.table_template_path, 'get_op_class.sql'])
)
status, result = self.conn.execute_2darray(SQL)
if not status:
return internal_server_error(errormsg=res)
op_class_list = [{'label': '', 'value': ''}]
for r in result['rows']:
op_class_list.append({'label': r['opcname'],
'value': r['opcname']})
return make_json_response(
data=op_class_list,
status=200
)
except Exception as e:
return internal_server_error(errormsg=str(e))
@BaseTableView.check_precondition
def types(self, gid, sid, did, scid, tid=None, clid=None):
"""

View File

@ -4,18 +4,30 @@ import BaseUISchema from 'sources/SchemaView/base_schema.ui';
import { emptyValidator, isEmptyString } from '../../../../../../../../static/js/validators';
export class PartitionKeysSchema extends BaseUISchema {
constructor(columns=[]) {
constructor(columns=[], getOperatorClass, getCollations) {
super({
key_type: 'column',
});
this.columns = columns;
this.columnsReloadBasis = false;
this.getOperatorClass = getOperatorClass;
this.getCollations = getCollations;
this.op_class_types = [];
}
changeColumnOptions(columns) {
this.columns = columns;
}
setOpClassTypes(options) {
if(!options || (_.isArray(options) && options.length == 0))
return this.op_class_types;
if(this.op_class_types.length == 0)
this.op_class_types = options;
}
get baseFields() {
let obj = this;
return [{
@ -66,6 +78,30 @@ export class PartitionKeysSchema extends BaseUISchema {
}
return false;
},
},{
id: 'collationame', label: gettext('Collation'), cell: 'select',
type: 'select', group: gettext('partition'), deps:['key_type'],
options: obj._top.getCollations(), mode: ['create', 'properties', 'edit'],
editable: function(state) {
if(state.key_type == 'expression') {
return false;
}
return true;
},
disabled: ()=>{return !(obj.isNew()); },
},
{
id: 'op_class', label: gettext('Operator class'), cell: 'select',
type: 'select', group: gettext('partition'), deps:['key_type'],
editable: function(state) {
if(state.key_type == 'expression') {
return false;
}
return true;
},
disabled: ()=>{return !(obj.isNew()); },
options: obj._top.getOperatorClass(), mode: ['create', 'properties', 'edit'],
optionsLoaded: (options)=>{obj.setOpClassTypes(options);},
}];
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////
//
//234567890
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2021, The pgAdmin Development Team

View File

@ -57,6 +57,8 @@ export function getNodeTableSchema(treeNodeInfo, itemNodeData, pgBrowser) {
(params)=>{
return getNodeAjaxOptions('get_columns', tableNode, treeNodeInfo, itemNodeData, {urlParams: params, useCache:false});
},
()=>getNodeAjaxOptions('get_collations', pgBrowser.Nodes['collation'], treeNodeInfo, itemNodeData),
()=>getNodeAjaxOptions('get_op_class', pgBrowser.Nodes['table'], treeNodeInfo, itemNodeData),
{
relowner: pgBrowser.serverInfo[treeNodeInfo.server._id].user.name,
schema: treeNodeInfo.schema._label,
@ -255,7 +257,7 @@ export class LikeSchema extends BaseUISchema {
}
export default class TableSchema extends BaseUISchema {
constructor(fieldOptions={}, nodeInfo, schemas, getPrivilegeRoleSchema, getColumns, initValues) {
constructor(fieldOptions={}, nodeInfo, schemas, getPrivilegeRoleSchema, getColumns, getCollations, getOperatorClass, initValues) {
super({
name: undefined,
oid: undefined,
@ -298,6 +300,8 @@ export default class TableSchema extends BaseUISchema {
this.getPrivilegeRoleSchema = getPrivilegeRoleSchema;
this.nodeInfo = nodeInfo;
this.getColumns = getColumns;
this.getCollations = getCollations;
this.getOperatorClass = getOperatorClass;
this.partitionKeysObj = new PartitionKeysSchema();
this.partitionsObj = new PartitionsSchema(this.nodeInfo);

View File

@ -0,0 +1,7 @@
SELECT (PG_CATALOG.CONCAT(PG_CATALOG.QUOTE_IDENT(nspc.nspname),'.',PG_CATALOG.QUOTE_IDENT(PGCOL.COLLNAME))) AS collationame
FROM PG_PARTITIONED_TABLE PARTT
LEFT OUTER JOIN PG_CATALOG.PG_COLLATION PGCOL
ON PGCOL.OID = 950
LEFT OUTER JOIN PG_CATALOG.PG_NAMESPACE NSPC
ON PGCOL.COLLNAMESPACE = NSPC.OID
WHERE PARTRELID = 162140

View File

@ -0,0 +1,3 @@
SELECT opcname, opcmethod
FROM pg_catalog.pg_opclass
ORDER BY 1;

View File

@ -0,0 +1,24 @@
-- Table: public.partition_table_with_collate_$%{}[]()&*^!@"'`\/#
-- DROP TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#";
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text COLLATE pg_catalog."default",
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to postgres;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
-- Partitions SQL
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');
ALTER TABLE IF EXISTS public.cust_arr_small
OWNER to postgres;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text,
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to postgres;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');

View File

@ -1790,6 +1790,158 @@
"store_object_id": true,
"expected_sql_file": "create_table_with_range_partition.sql",
"expected_msql_file": "create_table_with_range_partition_msql.sql"
},
{
"type": "create",
"name": "Create Table with range partition with collate and opclass",
"endpoint": "NODE-table.obj",
"sql_endpoint": "NODE-table.sql_id",
"msql_endpoint": "NODE-table.msql",
"data": {
"name": "partition_table_with_collate_$%{}[]()&*^!@\"'`\\/#",
"relowner": "postgres",
"relacl": [],
"description": "partition table",
"coll_inherits": "[]",
"hastoasttable": true,
"toast_autovacuum_enabled": "x",
"autovacuum_enabled": "x",
"primary_key": [],
"partitions": [
{
"is_attach": false,
"partition_name": "cust_arr_small",
"values_from": "'20'",
"values_to": "'25'",
"is_sub_partitioned": false,
"sub_partition_type": "range",
"sub_partition_keys": []
}
],
"partition_type": "range",
"is_partitioned": true,
"schema": "public",
"columns": [
{
"name": "id",
"cltype": "integer",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "status",
"cltype": "text",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "arr",
"cltype": "numeric",
"attacl": [],
"min_val_attlen": 1,
"min_val_attprecision": 0,
"max_val_attlen": 1000,
"max_val_attprecision": 1000,
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
}
],
"foreign_key": [],
"check_constraint": [],
"unique_constraint": [],
"exclude_constraint": [],
"partition_keys": [
{
"key_type": "column",
"pt_column": "status",
"collationame": "\"C\"",
"op_class": "text_pattern_ops"
}
],
"vacuum_table": [
{
"name": "autovacuum_analyze_scale_factor"
},
{
"name": "autovacuum_analyze_threshold"
},
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"vacuum_toast": [
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"seclabels": [],
"forcerlspolicy": false,
"like_default_value": false,
"like_constraints": false,
"like_indexes": false,
"like_storage": false,
"like_comments": false,
"autovacuum_custom": false
},
"store_object_id": true,
"expected_sql_file": "create_partition_table_with_collate.sql",
"expected_msql_file": "create_partition_table_with_collate_msql.sql"
}
]
}

View File

@ -0,0 +1,24 @@
-- Table: public.partition_table_with_collate_$%{}[]()&*^!@"'`\/#
-- DROP TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#";
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text COLLATE pg_catalog."default",
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to postgres;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
-- Partitions SQL
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');
ALTER TABLE IF EXISTS public.cust_arr_small
OWNER to postgres;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text COLLATE pg_catalog."default",
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to postgres;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');

View File

@ -1940,6 +1940,158 @@
"store_object_id": true,
"expected_sql_file": "create_table_with_hash_partition.sql",
"expected_msql_file": "create_table_with_hash_partition_msql.sql"
},
{
"type": "create",
"name": "Create Table with range partition with collate and opclass",
"endpoint": "NODE-table.obj",
"sql_endpoint": "NODE-table.sql_id",
"msql_endpoint": "NODE-table.msql",
"data": {
"name": "partition_table_with_collate_$%{}[]()&*^!@\"'`\\/#",
"relowner": "postgres",
"relacl": [],
"description": "partition table",
"coll_inherits": "[]",
"hastoasttable": true,
"toast_autovacuum_enabled": "x",
"autovacuum_enabled": "x",
"primary_key": [],
"partitions": [
{
"is_attach": false,
"partition_name": "cust_arr_small",
"values_from": "'20'",
"values_to": "'25'",
"is_sub_partitioned": false,
"sub_partition_type": "range",
"sub_partition_keys": []
}
],
"partition_type": "range",
"is_partitioned": true,
"schema": "public",
"columns": [
{
"name": "id",
"cltype": "integer",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "status",
"cltype": "text",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "arr",
"cltype": "numeric",
"attacl": [],
"min_val_attlen": 1,
"min_val_attprecision": 0,
"max_val_attlen": 1000,
"max_val_attprecision": 1000,
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
}
],
"foreign_key": [],
"check_constraint": [],
"unique_constraint": [],
"exclude_constraint": [],
"partition_keys": [
{
"key_type": "column",
"pt_column": "status",
"collationame": "\"C\"",
"op_class": "text_pattern_ops"
}
],
"vacuum_table": [
{
"name": "autovacuum_analyze_scale_factor"
},
{
"name": "autovacuum_analyze_threshold"
},
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"vacuum_toast": [
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"seclabels": [],
"forcerlspolicy": false,
"like_default_value": false,
"like_constraints": false,
"like_indexes": false,
"like_storage": false,
"like_comments": false,
"autovacuum_custom": false
},
"store_object_id": true,
"expected_sql_file": "create_partition_table_with_collate.sql",
"expected_msql_file": "create_partition_table_with_collate_msql.sql"
}
]
}

View File

@ -0,0 +1,24 @@
-- Table: public.partition_table_with_collate_$%{}[]()&*^!@"'`\/#
-- DROP TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#";
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text COLLATE pg_catalog."default",
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to postgres;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
-- Partitions SQL
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');
ALTER TABLE IF EXISTS public.cust_arr_small
OWNER to postgres;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text,
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to postgres;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');

View File

@ -1940,6 +1940,158 @@
"store_object_id": true,
"expected_sql_file": "create_table_with_hash_partition.sql",
"expected_msql_file": "create_table_with_hash_partition_msql.sql"
},
{
"type": "create",
"name": "Create Table with range partition with collate and opclass",
"endpoint": "NODE-table.obj",
"sql_endpoint": "NODE-table.sql_id",
"msql_endpoint": "NODE-table.msql",
"data": {
"name": "partition_table_with_collate_$%{}[]()&*^!@\"'`\\/#",
"relowner": "enterprisedb",
"relacl": [],
"description": "partition table",
"coll_inherits": "[]",
"hastoasttable": true,
"toast_autovacuum_enabled": "x",
"autovacuum_enabled": "x",
"primary_key": [],
"partitions": [
{
"is_attach": false,
"partition_name": "cust_arr_small",
"values_from": "'20'",
"values_to": "'25'",
"is_sub_partitioned": false,
"sub_partition_type": "range",
"sub_partition_keys": []
}
],
"partition_type": "range",
"is_partitioned": true,
"schema": "public",
"columns": [
{
"name": "id",
"cltype": "integer",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "status",
"cltype": "text",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "arr",
"cltype": "numeric",
"attacl": [],
"min_val_attlen": 1,
"min_val_attprecision": 0,
"max_val_attlen": 1000,
"max_val_attprecision": 1000,
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
}
],
"foreign_key": [],
"check_constraint": [],
"unique_constraint": [],
"exclude_constraint": [],
"partition_keys": [
{
"key_type": "column",
"pt_column": "status",
"collationame": "\"C\"",
"op_class": "text_pattern_ops"
}
],
"vacuum_table": [
{
"name": "autovacuum_analyze_scale_factor"
},
{
"name": "autovacuum_analyze_threshold"
},
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"vacuum_toast": [
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"seclabels": [],
"forcerlspolicy": false,
"like_default_value": false,
"like_constraints": false,
"like_indexes": false,
"like_storage": false,
"like_comments": false,
"autovacuum_custom": false
},
"store_object_id": true,
"expected_sql_file": "create_partition_table_with_collate.sql",
"expected_msql_file": "create_partition_table_with_collate_msql.sql"
}
]
}

View File

@ -0,0 +1,24 @@
-- Table: public.partition_table_with_collate_$%{}[]()&*^!@"'`\/#
-- DROP TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#";
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text COLLATE pg_catalog."default",
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to enterprisedb;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
-- Partitions SQL
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');
ALTER TABLE IF EXISTS public.cust_arr_small
OWNER to enterprisedb;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text,
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to enterprisedb;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');

View File

@ -1790,6 +1790,158 @@
"store_object_id": true,
"expected_sql_file": "create_table_with_range_partition.sql",
"expected_msql_file": "create_table_with_range_partition_msql.sql"
},
{
"type": "create",
"name": "Create Table with range partition with collate and opclass",
"endpoint": "NODE-table.obj",
"sql_endpoint": "NODE-table.sql_id",
"msql_endpoint": "NODE-table.msql",
"data": {
"name": "partition_table_with_collate_$%{}[]()&*^!@\"'`\\/#",
"relowner": "enterprisedb",
"relacl": [],
"description": "partition table",
"coll_inherits": "[]",
"hastoasttable": true,
"toast_autovacuum_enabled": "x",
"autovacuum_enabled": "x",
"primary_key": [],
"partitions": [
{
"is_attach": false,
"partition_name": "cust_arr_small",
"values_from": "'20'",
"values_to": "'25'",
"is_sub_partitioned": false,
"sub_partition_type": "range",
"sub_partition_keys": []
}
],
"partition_type": "range",
"is_partitioned": true,
"schema": "public",
"columns": [
{
"name": "id",
"cltype": "integer",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "status",
"cltype": "text",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "arr",
"cltype": "numeric",
"attacl": [],
"min_val_attlen": 1,
"min_val_attprecision": 0,
"max_val_attlen": 1000,
"max_val_attprecision": 1000,
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
}
],
"foreign_key": [],
"check_constraint": [],
"unique_constraint": [],
"exclude_constraint": [],
"partition_keys": [
{
"key_type": "column",
"pt_column": "status",
"collationame": "\"C\"",
"op_class": "text_pattern_ops"
}
],
"vacuum_table": [
{
"name": "autovacuum_analyze_scale_factor"
},
{
"name": "autovacuum_analyze_threshold"
},
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"vacuum_toast": [
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"seclabels": [],
"forcerlspolicy": false,
"like_default_value": false,
"like_constraints": false,
"like_indexes": false,
"like_storage": false,
"like_comments": false,
"autovacuum_custom": false
},
"store_object_id": true,
"expected_sql_file": "create_partition_table_with_collate.sql",
"expected_msql_file": "create_partition_table_with_collate_msql.sql"
}
]
}

View File

@ -0,0 +1,24 @@
-- Table: public.partition_table_with_collate_$%{}[]()&*^!@"'`\/#
-- DROP TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#";
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text COLLATE pg_catalog."default",
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to enterprisedb;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
-- Partitions SQL
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');
ALTER TABLE IF EXISTS public.cust_arr_small
OWNER to enterprisedb;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text,
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to enterprisedb;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');

View File

@ -1940,6 +1940,158 @@
"store_object_id": true,
"expected_sql_file": "create_table_with_hash_partition.sql",
"expected_msql_file": "create_table_with_hash_partition_msql.sql"
},
{
"type": "create",
"name": "Create Table with range partition with collate and opclass",
"endpoint": "NODE-table.obj",
"sql_endpoint": "NODE-table.sql_id",
"msql_endpoint": "NODE-table.msql",
"data": {
"name": "partition_table_with_collate_$%{}[]()&*^!@\"'`\\/#",
"relowner": "enterprisedb",
"relacl": [],
"description": "partition table",
"coll_inherits": "[]",
"hastoasttable": true,
"toast_autovacuum_enabled": "x",
"autovacuum_enabled": "x",
"primary_key": [],
"partitions": [
{
"is_attach": false,
"partition_name": "cust_arr_small",
"values_from": "'20'",
"values_to": "'25'",
"is_sub_partitioned": false,
"sub_partition_type": "range",
"sub_partition_keys": []
}
],
"partition_type": "range",
"is_partitioned": true,
"schema": "public",
"columns": [
{
"name": "id",
"cltype": "integer",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "status",
"cltype": "text",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "arr",
"cltype": "numeric",
"attacl": [],
"min_val_attlen": 1,
"min_val_attprecision": 0,
"max_val_attlen": 1000,
"max_val_attprecision": 1000,
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
}
],
"foreign_key": [],
"check_constraint": [],
"unique_constraint": [],
"exclude_constraint": [],
"partition_keys": [
{
"key_type": "column",
"pt_column": "status",
"collationame": "\"C\"",
"op_class": "text_pattern_ops"
}
],
"vacuum_table": [
{
"name": "autovacuum_analyze_scale_factor"
},
{
"name": "autovacuum_analyze_threshold"
},
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"vacuum_toast": [
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"seclabels": [],
"forcerlspolicy": false,
"like_default_value": false,
"like_constraints": false,
"like_indexes": false,
"like_storage": false,
"like_comments": false,
"autovacuum_custom": false
},
"store_object_id": true,
"expected_sql_file": "create_partition_table_with_collate.sql",
"expected_msql_file": "create_partition_table_with_collate_msql.sql"
}
]
}

View File

@ -0,0 +1,24 @@
-- Table: public.partition_table_with_collate_$%{}[]()&*^!@"'`\/#
-- DROP TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#";
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text COLLATE pg_catalog."default",
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to enterprisedb;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
-- Partitions SQL
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');
ALTER TABLE IF EXISTS public.cust_arr_small
OWNER to enterprisedb;

View File

@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
(
id integer,
status text,
arr numeric
) PARTITION BY RANGE (status COLLATE "C" text_pattern_ops);
ALTER TABLE IF EXISTS public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
OWNER to enterprisedb;
COMMENT ON TABLE public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
IS 'partition table';
CREATE TABLE IF NOT EXISTS public.cust_arr_small PARTITION OF public."partition_table_with_collate_$%{}[]()&*^!@""'`\/#"
FOR VALUES FROM ('20') TO ('25');

View File

@ -1940,6 +1940,158 @@
"store_object_id": true,
"expected_sql_file": "create_table_with_hash_partition.sql",
"expected_msql_file": "create_table_with_hash_partition_msql.sql"
},
{
"type": "create",
"name": "Create Table with range partition with collate and opclass",
"endpoint": "NODE-table.obj",
"sql_endpoint": "NODE-table.sql_id",
"msql_endpoint": "NODE-table.msql",
"data": {
"name": "partition_table_with_collate_$%{}[]()&*^!@\"'`\\/#",
"relowner": "enterprisedb",
"relacl": [],
"description": "partition table",
"coll_inherits": "[]",
"hastoasttable": true,
"toast_autovacuum_enabled": "x",
"autovacuum_enabled": "x",
"primary_key": [],
"partitions": [
{
"is_attach": false,
"partition_name": "cust_arr_small",
"values_from": "'20'",
"values_to": "'25'",
"is_sub_partitioned": false,
"sub_partition_type": "range",
"sub_partition_keys": []
}
],
"partition_type": "range",
"is_partitioned": true,
"schema": "public",
"columns": [
{
"name": "id",
"cltype": "integer",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "status",
"cltype": "text",
"attacl": [],
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
},
{
"name": "arr",
"cltype": "numeric",
"attacl": [],
"min_val_attlen": 1,
"min_val_attprecision": 0,
"max_val_attlen": 1000,
"max_val_attprecision": 1000,
"is_primary_key": false,
"attnotnull": false,
"attlen": null,
"attprecision": null,
"attidentity": "a",
"colconstype": "n",
"attoptions": [],
"seclabels": []
}
],
"foreign_key": [],
"check_constraint": [],
"unique_constraint": [],
"exclude_constraint": [],
"partition_keys": [
{
"key_type": "column",
"pt_column": "status",
"collationame": "\"C\"",
"op_class": "text_pattern_ops"
}
],
"vacuum_table": [
{
"name": "autovacuum_analyze_scale_factor"
},
{
"name": "autovacuum_analyze_threshold"
},
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"vacuum_toast": [
{
"name": "autovacuum_freeze_max_age"
},
{
"name": "autovacuum_vacuum_cost_delay"
},
{
"name": "autovacuum_vacuum_cost_limit"
},
{
"name": "autovacuum_vacuum_scale_factor"
},
{
"name": "autovacuum_vacuum_threshold"
},
{
"name": "autovacuum_freeze_min_age"
},
{
"name": "autovacuum_freeze_table_age"
}
],
"seclabels": [],
"forcerlspolicy": false,
"like_default_value": false,
"like_constraints": false,
"like_indexes": false,
"like_storage": false,
"like_comments": false,
"autovacuum_custom": false
},
"store_object_id": true,
"expected_sql_file": "create_partition_table_with_collate.sql",
"expected_msql_file": "create_partition_table_with_collate_msql.sql"
}
]
}

View File

@ -378,6 +378,57 @@
"test_result_data": {}
}
},
{
"name": "Create: Add Range partitioned table with collate",
"is_positive_test": true,
"inventory_data": {
"server_min_version": 100000,
"skip_msg": "Partitioned table are not supported by PPAS/PG 10.0 and below."
},
"test_data": {
"is_partitioned": true,
"description": "partition table",
"partition_type": "range",
"multilevel_partition": true,
"partitions": [
{
"values_from": "'2010-01-01'",
"values_to": "'2010-12-31'",
"is_attach": false,
"partition_name": "emp_2010_multi_level",
"is_sub_partitioned": true,
"sub_partition_type": "range",
"sub_partition_keys": [
{
"key_type": "column",
"pt_column": "empno"
}
]
},
{
"values_from": "'20'",
"values_to": "'25'",
"is_attach": false,
"partition_name": "emp_2011_multi_level"
}
],
"partition_keys": [
{
"key_type": "column",
"pt_column": "part_col",
"collationame": "pg_catalog.\"C\"",
"op_class": "text_pattern_ops"
}
]
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200,
"error_msg": null,
"test_result_data": {}
}
},
{
"name": "Create: Add Table with name more than 64 chars.",
"is_positive_test": true,
@ -1329,7 +1380,7 @@
"is_positive_test": true,
"inventory_data": {},
"test_data": {
"toast_autovacuum":false
"toast_autovacuum": false
},
"mocking_required": false,
"mock_data": {},
@ -1348,25 +1399,40 @@
},
"test_data": {
"columns": {
"changed": [{
"attnum": 1,
"attacl": {
"added": [{
"privileges": [
{"privilege_type": "a", "privilege": true,
"with_grant": true},
{"privilege_type": "r", "privilege": true,
"with_grant": true},
{"privilege_type": "w", "privilege": true,
"with_grant": true},
{"privilege_type": "x", "privilege": true,
"with_grant": true
}
]
}]
}
}]
"changed": [
{
"attnum": 1,
"attacl": {
"added": [
{
"privileges": [
{
"privilege_type": "a",
"privilege": true,
"with_grant": true
},
{
"privilege_type": "r",
"privilege": true,
"with_grant": true
},
{
"privilege_type": "w",
"privilege": true,
"with_grant": true
},
{
"privilege_type": "x",
"privilege": true,
"with_grant": true
}
]
}
]
}
}
]
}
},
"mocking_required": false,
"mock_data": {},
@ -1817,7 +1883,7 @@
"inventory_data": {},
"url_encoded_data": true,
"test_data": {
"col_type":"integer"
"col_type": "integer"
},
"mocking_required": false,
"mock_data": {},
@ -1835,7 +1901,7 @@
"inventory_data": {},
"url_encoded_data": true,
"test_data": {
"indextype":"btree"
"indextype": "btree"
},
"mocking_required": false,
"mock_data": {},

View File

@ -395,7 +395,16 @@ def get_table_common_data():
"is_primary_key": False,
"attoptions": [],
"seclabels": []
}],
},
{
"name": "part_col",
"cltype": "text",
"attacl": [],
"is_primary_key": False,
"attoptions": [],
"seclabels": []
}
],
"exclude_constraint": [],
"fillfactor": "",
"hastoasttable": True,

View File

@ -1117,7 +1117,15 @@ class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings):
for row in data[part_keys]:
if row['key_type'] == 'column':
partition_scheme += self.qtIdent(
self.conn, row['pt_column']) + ', '
self.conn, row['pt_column'])
if 'collationame' in row:
partition_scheme += ' COLLATE %s' % row['collationame']
if 'op_class' in row:
partition_scheme += ' %s' % row['op_class']
partition_scheme += ', '
elif row['key_type'] == 'expression':
partition_scheme += row['expression'] + ', '