Skip to content

Commit

Permalink
Added support for provider, deterministic, version and RULES paramete…
Browse files Browse the repository at this point in the history
…r while creating collation. pgadmin-org#5611
  • Loading branch information
JyotiEdb authored Mar 19, 2024
1 parent cee0945 commit 25074e4
Show file tree
Hide file tree
Showing 18 changed files with 201 additions and 13 deletions.
10 changes: 10 additions & 0 deletions docs/en_US/collation_dialog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ settings:
* Use the *LC_CTYPE* field to specify a locale with specified character
classification. The locale must be applicable to the current database encoding.
(See CREATE DATABASE for details.)
* Use the drop-down listbox next to *Locale Provider* to select a locale services associated
with the collation. Possible values are: icu, libc. libc is the default.
* Move the switch next to *Deterministic* to *YES* to specify whether the collation should use
deterministic comparisons. By default, this option is set to true. In a
deterministic comparison, strings that are not byte-wise equal are considered
unequal, even if they are considered logically equal in the comparison.
* Use the *Rules* field to specify a rules for customizing the behavior of the collation.
It includes considerations such as character ordering, case sensitivity, and accent
sensitivity.
* Use the *Version* field to specify version string to store with the collation object.


Click the *SQL* tab to continue.
Expand Down
Binary file modified docs/en_US/images/collation_definition.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/en_US/images/collation_sql.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export default class CollationSchema extends BaseUISchema {
readonly: function (state) { return !obj.isNew(state); },
deps: ['lc_collate', 'lc_type', 'copy_collation'],
disabled: function (state) {
// Enable localy only if lc_* & copy_collation is not provided
// Enable locale only if lc_* & copy_collation is not provided
if (state.lc_collate || state.lc_type)
return true;
return state.copy_collation;
Expand All @@ -109,6 +109,68 @@ export default class CollationSchema extends BaseUISchema {
disabled: obj.disableFields,
deps: ['locale', 'copy_collation'],
},
{
id: 'provider', label: gettext('Locale Provider'),
editable: false, type: 'select',mode: ['create', 'edit'], group: gettext('Definition'),
readonly: function (state) { return !obj.isNew(state); },
options: [{
label: gettext('icu'),
value: 'icu',
}, {
label: gettext('libc'),
value: 'libc',
}],
min_version: 120000,
deps: ['copy_collation'],
disabled: function (state) {
return state.copy_collation;
}
},
{
id: 'provider', label: gettext('Locale Provider'),
type: 'text',mode: ['properties'], group: gettext('Definition'),
readonly: true,
min_version: 120000,
},
{
id: 'is_deterministic', label: gettext('Deterministic'),
type: 'switch', group: gettext('Definition'),
default: false,
readonly: function (state) { return !obj.isNew(state); },
mode: ['properties', 'edit', 'create'],
min_version: 120000,
helpMessageMode: ['edit', 'create'],
deps: ['copy_collation'],
disabled: function (state) {
return state.copy_collation;
}
},
{
id: 'rules', label: gettext('Rules'),
editable: true, type: 'text', group: gettext('Definition'),
readonly: function (state) { return !obj.isNew(state); },
mode: ['properties', 'edit', 'create'],
deps: ['provider','is_deterministic','copy_collation'],
depChange: (state)=>{
if (state.provider !== 'icu')
return { rules: '' };
},
disabled: function(state) {
if (state.copy_collation)
return true;
return state.provider !== 'icu' || (state.provider == 'icu' && state.is_deterministic);
},
min_version: 160000,
},
{
id: 'version', label: gettext('Version'), type: 'text', group: gettext('Definition'),
readonly: function (state) { return !obj.isNew(state); },
mode: ['properties','create', 'edit'], min_version: 120000,
deps: ['copy_collation'],
disabled: function (state) {
return state.copy_collation;
}
},
{
id: 'is_sys_obj', label: gettext('System collation?'),
cell: 'boolean', type: 'switch', mode: ['properties'],
Expand Down Expand Up @@ -164,4 +226,3 @@ export default class CollationSchema extends BaseUISchema {
}

}

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
SELECT c.oid, c.collname AS name, COALESCE(c.collcollate, c.colliculocale) AS lc_collate,
COALESCE(c.collctype, c.colliculocale) AS lc_type,
COALESCE(c.collctype, c.colliculocale) AS lc_type, c.collisdeterministic AS is_deterministic, c.collversion AS version,
c.collprovider AS provider,
pg_catalog.pg_get_userbyid(c.collowner) AS owner, description, n.nspname AS schema
FROM pg_catalog.pg_collation c
JOIN pg_catalog.pg_namespace n ON n.oid=c.collnamespace
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
SELECT c.oid, c.collname AS name, COALESCE(c.collcollate, c.colliculocale) AS lc_collate,
COALESCE(c.collctype, c.colliculocale) AS lc_type, c.collisdeterministic AS is_deterministic, c.collversion AS version,
c.collprovider AS provider, c.collprovider AS rules,
pg_catalog.pg_get_userbyid(c.collowner) AS owner, description, n.nspname AS schema
FROM pg_catalog.pg_collation c
JOIN pg_catalog.pg_namespace n ON n.oid=c.collnamespace
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=c.oid AND des.classoid='pg_collation'::regclass)
WHERE c.collnamespace = {{scid}}::oid
{% if coid %} AND c.oid = {{coid}}::oid {% endif %}
ORDER BY c.collname;
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
{% if data %}
CREATE COLLATION{% if add_not_exists_clause %} IF NOT EXISTS{% endif %} {{ conn|qtIdent(data.schema, data.name) }}
{% if not data.copy_collation %}
{# if user has provided lc_collate & lc_type #}
{% if data.lc_collate and data.lc_type %}
(LC_COLLATE = {{ data.lc_collate|qtLiteral(conn) }}, LC_CTYPE = {{ data.lc_type|qtLiteral(conn) }});
{% if data.lc_collate and data.lc_type and data.provider and data.is_deterministic%}
{% if data.version %}
(LC_COLLATE = {{ data.lc_collate|qtLiteral(conn) }}, LC_CTYPE = {{ data.lc_type|qtLiteral(conn) }}, PROVIDER = {{ data.provider|qtLiteral(conn) }}, DETERMINISTIC = {{ data.is_deterministic|qtLiteral(conn) }}, VERSION = {{ data.version|qtLiteral(conn) }});
{% else %}
(LC_COLLATE = {{ data.lc_collate|qtLiteral(conn) }}, LC_CTYPE = {{ data.lc_type|qtLiteral(conn) }}, PROVIDER = {{ data.provider|qtLiteral(conn) }}, DETERMINISTIC = {{ data.is_deterministic|qtLiteral(conn) }});
{% endif %}
{% endif %}
{% if data.lc_collate and data.lc_type and data.provider and not data.is_deterministic and data.rules %}
{% if data.version %}
(LC_COLLATE = {{ data.lc_collate|qtLiteral(conn) }}, LC_CTYPE = {{ data.lc_type|qtLiteral(conn) }}, PROVIDER = {{ data.provider|qtLiteral(conn) }}, RULES = {{ data.rules|qtLiteral(conn) }}, VERSION = {{ data.version|qtLiteral(conn) }}, DETERMINISTIC = FALSE);
{% else %}
(LC_COLLATE = {{ data.lc_collate|qtLiteral(conn) }}, LC_CTYPE = {{ data.lc_type|qtLiteral(conn) }}, PROVIDER = {{ data.provider|qtLiteral(conn) }}, RULES = {{ data.rules|qtLiteral(conn) }}, DETERMINISTIC = FALSE);
{% endif %}
{% endif %}
{# if user has provided locale only #}
{% if data.locale %}
(LOCALE = {{ data.locale|qtLiteral(conn) }});
{% if data.locale and data.provider and data.is_deterministic%}
{% if data.version %}
(LOCALE = {{ data.locale|qtLiteral(conn) }}, PROVIDER = {{ data.provider|qtLiteral(conn) }}, DETERMINISTIC = {{ data.is_deterministic|qtLiteral(conn) }}, VERSION = {{ data.version|qtLiteral(conn) }});
{% else %}
(LOCALE = {{ data.locale|qtLiteral(conn) }}, PROVIDER = {{ data.provider|qtLiteral(conn) }}, DETERMINISTIC = {{ data.is_deterministic|qtLiteral(conn) }});
{% endif %}
{% endif %}
{% if data.locale and data.provider and data.version and not data.is_deterministic and data.rules %}
{% if data.version %}
(LOCALE = {{ data.locale|qtLiteral(conn) }}, PROVIDER = {{ data.provider|qtLiteral(conn) }}, RULES = {{ data.rules|qtLiteral(conn) }}, VERSION = {{ data.version|qtLiteral(conn) }}, DETERMINISTIC = FALSE);
{% else %}
(LOCALE = {{ data.locale|qtLiteral(conn) }}, PROVIDER = {{ data.provider|qtLiteral(conn) }}, RULES = {{ data.rules|qtLiteral(conn) }}, DETERMINISTIC = FALSE);
{% endif %}
{% endif %}
{% endif %}
{# if user has choosed to copy from existing collation #}
{% if data.copy_collation %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
SELECT c.oid, c.collname AS name, c.collcollate AS lc_collate, c.collctype AS lc_type,
pg_catalog.pg_get_userbyid(c.collowner) AS owner, description, n.nspname AS schema
pg_catalog.pg_get_userbyid(c.collowner) AS owner, c.collisdeterministic AS is_deterministic, c.collversion AS version,
c.collprovider AS provider, c.description, n.nspname AS schema

FROM pg_catalog.pg_collation c
JOIN pg_catalog.pg_namespace n ON n.oid=c.collnamespace
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=c.oid AND des.classoid='pg_collation'::regclass)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"mock_data": {},
"expected_data": {
"status_code": 200
},
"inventory_data": {
"server_min_version": 160000,
"skip_msg": "Create collation: With valid data are not supported by PG 16.0 and below."
}
},
{
Expand Down Expand Up @@ -98,6 +102,10 @@
"name": "Get Collation",
"url": "/browser/collation/obj/",
"is_positive_test": true,
"inventory_data": {
"server_min_version": 160000,
"skip_msg": "Get Collation are not supported by PG 16.0 and below."
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
Expand All @@ -109,6 +117,10 @@
"url": "/browser/collation/obj/",
"error_fetching_collation": true,
"is_positive_test": false,
"inventory_data": {
"server_min_version": 160000,
"skip_msg": "Error while fetching a Collation are not supported by PG 16.0 and below."
},
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg3.connection.Connection.execute_dict",
Expand All @@ -123,6 +135,10 @@
"url": "/browser/collation/obj/",
"wrong_collation_id": true,
"is_positive_test": false,
"inventory_data": {
"server_min_version": 160000,
"skip_msg": "Fetch collation using wrong collation id are not supported by PG 16.0 and below."
},
"mocking_required": false,
"mock_data": {
},
Expand All @@ -134,6 +150,10 @@
"name": "Get Collation list",
"url": "/browser/collation/obj/",
"is_positive_test": true,
"inventory_data": {
"server_min_version": 160000,
"skip_msg": "Get Collation list are not supported by PG 16.0 and below."
},
"collation_list": true,
"mocking_required": false,
"mock_data": {},
Expand Down Expand Up @@ -214,6 +234,10 @@
"name": "Update Collation",
"url": "/browser/collation/obj/",
"is_positive_test": true,
"inventory_data": {
"server_min_version": 160000,
"skip_msg": "Update Collation are not supported by PG 16.0 and below."
},
"mocking_required": false,
"test_data": {
"description": "This is collation update comment",
Expand Down Expand Up @@ -377,6 +401,10 @@
"name": "Get Collation SQL",
"url": "/browser/collation/sql/",
"is_positive_test": true,
"inventory_data": {
"server_min_version": 160000,
"skip_msg": "Get Collation SQL are not supported by PG 16.0 and below."
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
Expand All @@ -401,6 +429,10 @@
"name": "Get collation msql: With existing collation id.",
"url": "/browser/collation/msql/",
"is_positive_test": true,
"inventory_data": {
"server_min_version": 160000,
"skip_msg": "Get collation msql are not supported by PG 16.0 and below."
},
"msql": true,
"mocking_required": false,
"mock_data": {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
-- DROP COLLATION IF EXISTS testschema."Cl1_$%{}[]()&*^!@""'`\/#a";

CREATE COLLATION IF NOT EXISTS testschema."Cl1_$%{}[]()&*^!@""'`\/#a"
(LC_COLLATE = 'C', LC_CTYPE = 'C');
(LC_COLLATE = 'C', LC_CTYPE = 'C', PROVIDER = 'c', DETERMINISTIC = true);

ALTER COLLATION testschema."Cl1_$%{}[]()&*^!@""'`\/#a"
OWNER TO <OWNER>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
-- DROP COLLATION IF EXISTS testschema."Cl1_$%{}[]()&*^!@""'`\/#";

CREATE COLLATION IF NOT EXISTS testschema."Cl1_$%{}[]()&*^!@""'`\/#"
(LC_COLLATE = 'C', LC_CTYPE = 'C');
(LC_COLLATE = 'C', LC_CTYPE = 'C', PROVIDER = 'c', DETERMINISTIC = true);

ALTER COLLATION testschema."Cl1_$%{}[]()&*^!@""'`\/#"
OWNER TO <OWNER>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- Collation: Cl1_$%{}[]()&*^!@"'`\/#b;

-- DROP COLLATION IF EXISTS testschema."Cl1_$%{}[]()&*^!@""'`\/#b";

CREATE COLLATION IF NOT EXISTS testschema."Cl1_$%{}[]()&*^!@""'`\/#b"
(LC_COLLATE = 'locale', LC_CTYPE = 'locale', PROVIDER = 'i', DETERMINISTIC = true, VERSION = '1');

ALTER COLLATION testschema."Cl1_$%{}[]()&*^!@""'`\/#b"
OWNER TO <OWNER>;

COMMENT ON COLLATION testschema."Cl1_$%{}[]()&*^!@""'`\/#b"
IS 'Description for extra params';
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
"copy_collation": "pg_catalog.\"C\"",
"description": "Description"
},
"store_object_id": true,
"expected_sql_file": "create_collation.sql"
}, {
},
{
"type": "alter",
"name": "Alter Collation",
"endpoint": "NODE-collation.obj_id",
Expand All @@ -25,13 +27,32 @@
},
"expected_sql_file": "alter_collation.sql",
"expected_msql_file": "msql_collation.sql"
}, {
},
{
"type": "delete",
"name": "Drop Collation",
"endpoint": "NODE-collation.delete_id",
"data": {
"name": "Cl1_$%{}[]()&*^!@\"'`\\/#a"
"name": "Cl1_$%{}[]()&*^!@\"'`\\/#b"
}
},
{
"type": "create",
"name": "Create Collation with extra parameters",
"endpoint": "NODE-collation.obj",
"sql_endpoint": "NODE-collation.sql_id",
"data": {
"name": "Cl1_$%{}[]()&*^!@\"'`\\/#b",
"schema": "testschema",
"owner": "postgres",
"description": "Description for extra params",
"locale": "locale",
"provider": "icu",
"is_deterministic": true,
"version": "1"
},
"store_object_id": true,
"expected_sql_file": "create_collation_with_extra_params.sql"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ def runTest(self):
self.test_data['name'] = "collation_add_%s" % str(uuid.uuid4())[1:8]
self.test_data['owner'] = self.server["username"]
self.test_data['schema'] = self.schema_name
self.test_data['provider'] = "icu"
self.test_data['is_deterministic'] = True
self.test_data['version'] = "test"

if self.is_positive_test:
response = self.create_collation()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ class CollationGetTestCase(BaseTestGenerator):

def setUp(self):
super().setUp()
if hasattr(self, 'inventory_data') and \
self.server_information['server_version']\
< self.inventory_data['server_min_version']:
self.skipTest(self.inventory_data['skip_msg'])
self.schema_info = parent_node_dict["schema"][-1]
self.schema_name = self.schema_info["schema_name"]
self.schema_id = self.schema_info["schema_id"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class CollationPutTestCase(BaseTestGenerator):

def setUp(self):
super().setUp()
if hasattr(self, 'inventory_data') and \
self.server_information['server_version'] \
< self.inventory_data['server_min_version']:
self.skipTest(self.inventory_data['skip_msg'])
self.schema_info = parent_node_dict["schema"][-1]
self.schema_name = self.schema_info["schema_name"]
self.db_name = parent_node_dict["database"][-1]["db_name"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ class CollationSqlTestCase(BaseTestGenerator):

def setUp(self):
super().setUp()
if hasattr(self, 'inventory_data') and \
self.server_information['server_version'] \
< self.inventory_data['server_min_version']:
self.skipTest(self.inventory_data['skip_msg'])
self.schema_info = parent_node_dict["schema"][-1]
self.schema_name = self.schema_info["schema_name"]
self.schema_id = self.schema_info["schema_id"]
Expand Down

0 comments on commit 25074e4

Please sign in to comment.