Skip to content

Commit

Permalink
repo-sqale: MID-6967 support for assignment/subtype search, EQ only
Browse files Browse the repository at this point in the history
With one value assignment having subtype with that value is found.
With multiple values in the query, assignment with ANY of the values
is found (this is in line with semantics of multi-value EQ for in memory
filtering).
This is only added for new/future repository, old one would require
subtypes table.
Minor style/cosmetics adjustments around gin index clauses.
  • Loading branch information
virgo47 committed Jul 14, 2021
1 parent 7ae8ed9 commit 0018db7
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 31 deletions.
2 changes: 1 addition & 1 deletion repo/repo-sqale/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ For example:
[source,sql]
----
-- with this index
CREATE INDEX m_user_ext_idx ON m_user USING gin (ext);
CREATE INDEX m_user_ext_idx ON m_user USING gin(ext);
-- the following where does not use it
select * from m_user
Expand Down
58 changes: 31 additions & 27 deletions repo/repo-sqale/sql/pgnew-repo.sql
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,8 @@ CREATE TRIGGER m_user_oid_delete_tr AFTER DELETE ON m_user

CREATE INDEX m_user_nameOrig_idx ON m_user (nameOrig);
ALTER TABLE m_user ADD CONSTRAINT m_user_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_user_policySituation_idx ON m_user USING GIN(policysituations gin__int_ops);
CREATE INDEX m_user_ext_idx ON m_user USING gin (ext);
CREATE INDEX m_user_policySituation_idx ON m_user USING gin(policysituations gin__int_ops);
CREATE INDEX m_user_ext_idx ON m_user USING gin(ext);
CREATE INDEX m_user_fullNameOrig_idx ON m_user (fullNameOrig);
CREATE INDEX m_user_familyNameOrig_idx ON m_user (familyNameOrig);
CREATE INDEX m_user_givenNameOrig_idx ON m_user (givenNameOrig);
Expand Down Expand Up @@ -834,9 +834,9 @@ ALTER TABLE m_shadow ADD CONSTRAINT m_shadow_primIdVal_objCls_resRefOid_key
UNIQUE (primaryIdentifierValue, objectClassId, resourceRefTargetOid);

CREATE INDEX m_shadow_subtypes_idx ON m_shadow USING gin(subtypes);
CREATE INDEX m_shadow_policySituation_idx ON m_shadow USING GIN(policysituations gin__int_ops);
CREATE INDEX m_shadow_ext_idx ON m_shadow USING gin (ext);
CREATE INDEX m_shadow_attributes_idx ON m_shadow USING gin (attributes);
CREATE INDEX m_shadow_policySituation_idx ON m_shadow USING gin(policysituations gin__int_ops);
CREATE INDEX m_shadow_ext_idx ON m_shadow USING gin(ext);
CREATE INDEX m_shadow_attributes_idx ON m_shadow USING gin(attributes);
/*
TODO: reconsider, especially boolean things like dead (perhaps WHERE in other indexes?)
Also consider partitioning by some of the attributes (class/kind/intent?)
Expand Down Expand Up @@ -908,7 +908,7 @@ CREATE INDEX m_security_policy_nameOrig_idx ON m_security_policy (nameOrig);
ALTER TABLE m_security_policy ADD CONSTRAINT m_security_policy_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_security_policy_subtypes_idx ON m_security_policy USING gin(subtypes);
CREATE INDEX m_security_policy_policySituation_idx
ON m_security_policy USING GIN(policysituations gin__int_ops);
ON m_security_policy USING gin(policysituations gin__int_ops);

-- Represents ObjectCollectionType, see https://wiki.evolveum.com/display/midPoint/Object+Collections+and+Views+Configuration
CREATE TABLE m_object_collection (
Expand All @@ -929,7 +929,7 @@ CREATE INDEX m_object_collection_nameOrig_idx ON m_object_collection (nameOrig);
ALTER TABLE m_object_collection ADD CONSTRAINT m_object_collection_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_object_collection_subtypes_idx ON m_object_collection USING gin(subtypes);
CREATE INDEX m_object_collection_policySituation_idx
ON m_object_collection USING GIN(policysituations gin__int_ops);
ON m_object_collection USING gin(policysituations gin__int_ops);

-- Represents DashboardType, see https://wiki.evolveum.com/display/midPoint/Dashboard+configuration
CREATE TABLE m_dashboard (
Expand All @@ -950,7 +950,7 @@ CREATE INDEX m_dashboard_nameOrig_idx ON m_dashboard (nameOrig);
ALTER TABLE m_dashboard ADD CONSTRAINT m_dashboard_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_dashboard_subtypes_idx ON m_dashboard USING gin(subtypes);
CREATE INDEX m_dashboard_policySituation_idx
ON m_dashboard USING GIN(policysituations gin__int_ops);
ON m_dashboard USING gin(policysituations gin__int_ops);

-- Represents ValuePolicyType
CREATE TABLE m_value_policy (
Expand All @@ -971,7 +971,7 @@ CREATE INDEX m_value_policy_nameOrig_idx ON m_value_policy (nameOrig);
ALTER TABLE m_value_policy ADD CONSTRAINT m_value_policy_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_value_policy_subtypes_idx ON m_value_policy USING gin(subtypes);
CREATE INDEX m_value_policy_policySituation_idx
ON m_value_policy USING GIN(policysituations gin__int_ops);
ON m_value_policy USING gin(policysituations gin__int_ops);

-- Represents ReportType, see https://wiki.evolveum.com/display/midPoint/Report+Configuration
CREATE TABLE m_report (
Expand All @@ -991,7 +991,7 @@ CREATE TRIGGER m_report_oid_delete_tr AFTER DELETE ON m_report
CREATE INDEX m_report_nameOrig_idx ON m_report (nameOrig);
ALTER TABLE m_report ADD CONSTRAINT m_report_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_report_subtypes_idx ON m_report USING gin(subtypes);
CREATE INDEX m_report_policySituation_idx ON m_report USING GIN(policysituations gin__int_ops);
CREATE INDEX m_report_policySituation_idx ON m_report USING gin(policysituations gin__int_ops);

-- Represents ReportDataType, see also m_report above
CREATE TABLE m_report_data (
Expand All @@ -1015,7 +1015,7 @@ CREATE INDEX m_report_data_nameOrig_idx ON m_report_data (nameOrig);
ALTER TABLE m_report_data ADD CONSTRAINT m_report_data_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_report_data_subtypes_idx ON m_report_data USING gin(subtypes);
CREATE INDEX m_report_data_policySituation_idx
ON m_report_data USING GIN(policysituations gin__int_ops);
ON m_report_data USING gin(policysituations gin__int_ops);

-- Represents LookupTableType, see https://wiki.evolveum.com/display/midPoint/Lookup+Tables
CREATE TABLE m_lookup_table (
Expand All @@ -1036,7 +1036,7 @@ CREATE INDEX m_lookup_table_nameOrig_idx ON m_lookup_table (nameOrig);
ALTER TABLE m_lookup_table ADD CONSTRAINT m_lookup_table_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_lookup_table_subtypes_idx ON m_lookup_table USING gin(subtypes);
CREATE INDEX m_lookup_table_policySituation_idx
ON m_lookup_table USING GIN(policysituations gin__int_ops);
ON m_lookup_table USING gin(policysituations gin__int_ops);

-- Represents LookupTableRowType, see also m_lookup_table above
CREATE TABLE m_lookup_table_row (
Expand Down Expand Up @@ -1083,7 +1083,7 @@ CREATE INDEX m_connector_nameOrig_idx ON m_connector (nameOrig);
ALTER TABLE m_connector ADD CONSTRAINT m_connector_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_connector_subtypes_idx ON m_connector USING gin(subtypes);
CREATE INDEX m_connector_policySituation_idx
ON m_connector USING GIN(policysituations gin__int_ops);
ON m_connector USING gin(policysituations gin__int_ops);

-- Represents ConnectorHostType, see https://wiki.evolveum.com/display/midPoint/Connector+Server
CREATE TABLE m_connector_host (
Expand All @@ -1106,7 +1106,7 @@ CREATE INDEX m_connector_host_nameOrig_idx ON m_connector_host (nameOrig);
ALTER TABLE m_connector_host ADD CONSTRAINT m_connector_host_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_connector_host_subtypes_idx ON m_connector_host USING gin(subtypes);
CREATE INDEX m_connector_host_policySituation_idx
ON m_connector_host USING GIN(policysituations gin__int_ops);
ON m_connector_host USING gin(policysituations gin__int_ops);

-- Represents persistent TaskType, see https://wiki.evolveum.com/display/midPoint/Task+Manager
CREATE TABLE m_task (
Expand Down Expand Up @@ -1150,9 +1150,9 @@ ALTER TABLE m_task ADD CONSTRAINT m_task_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_task_parent_idx ON m_task (parent);
CREATE INDEX m_task_objectRefTargetOid_idx ON m_task(objectRefTargetOid);
ALTER TABLE m_task ADD CONSTRAINT m_task_taskIdentifier_key UNIQUE (taskIdentifier);
CREATE INDEX m_task_dependentTaskIdentifiers_idx ON m_task USING GIN(dependentTaskIdentifiers);
CREATE INDEX m_task_dependentTaskIdentifiers_idx ON m_task USING gin(dependentTaskIdentifiers);
CREATE INDEX m_task_subtypes_idx ON m_task USING gin(subtypes);
CREATE INDEX m_task_policySituation_idx ON m_task USING GIN(policysituations gin__int_ops);
CREATE INDEX m_task_policySituation_idx ON m_task USING gin(policysituations gin__int_ops);
-- endregion

-- region cases
Expand Down Expand Up @@ -1188,7 +1188,7 @@ CREATE TRIGGER m_case_oid_delete_tr AFTER DELETE ON m_case
CREATE INDEX m_case_nameOrig_idx ON m_case (nameOrig);
ALTER TABLE m_case ADD CONSTRAINT m_case_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_case_subtypes_idx ON m_case USING gin(subtypes);
CREATE INDEX m_case_policySituation_idx ON m_case USING GIN(policysituations gin__int_ops);
CREATE INDEX m_case_policySituation_idx ON m_case USING gin(policysituations gin__int_ops);

CREATE INDEX m_case_objectRefTargetOid_idx ON m_case(objectRefTargetOid);
CREATE INDEX m_case_targetRefTargetOid_idx ON m_case(targetRefTargetOid);
Expand Down Expand Up @@ -1272,8 +1272,8 @@ ALTER TABLE m_access_cert_definition
ADD CONSTRAINT m_access_cert_definition_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_access_cert_definition_subtypes_idx ON m_access_cert_definition USING gin(subtypes);
CREATE INDEX m_access_cert_definition_policySituation_idx
ON m_access_cert_definition USING GIN(policysituations gin__int_ops);
CREATE INDEX m_access_cert_definition_ext_idx ON m_access_cert_definition USING gin (ext);
ON m_access_cert_definition USING gin(policysituations gin__int_ops);
CREATE INDEX m_access_cert_definition_ext_idx ON m_access_cert_definition USING gin(ext);

CREATE TABLE m_access_cert_campaign (
oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid),
Expand Down Expand Up @@ -1306,8 +1306,8 @@ ALTER TABLE m_access_cert_campaign
ADD CONSTRAINT m_access_cert_campaign_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_access_cert_campaign_subtypes_idx ON m_access_cert_campaign USING gin(subtypes);
CREATE INDEX m_access_cert_campaign_policySituation_idx
ON m_access_cert_campaign USING GIN(policysituations gin__int_ops);
CREATE INDEX m_access_cert_campaign_ext_idx ON m_access_cert_campaign USING gin (ext);
ON m_access_cert_campaign USING gin(policysituations gin__int_ops);
CREATE INDEX m_access_cert_campaign_ext_idx ON m_access_cert_campaign USING gin(ext);

CREATE TABLE m_access_cert_case (
ownerOid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE,
Expand Down Expand Up @@ -1440,7 +1440,8 @@ CREATE TRIGGER m_object_template_oid_delete_tr AFTER DELETE ON m_object_template
CREATE INDEX m_object_template_nameOrig_idx ON m_object_template (nameOrig);
ALTER TABLE m_object_template ADD CONSTRAINT m_object_template_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_object_template_subtypes_idx ON m_object_template USING gin(subtypes);
CREATE INDEX m_object_template_policySituation_idx ON m_object_template USING GIN(policysituations gin__int_ops);
CREATE INDEX m_object_template_policySituation_idx
ON m_object_template USING gin(policysituations gin__int_ops);

-- stores ObjectTemplateType/includeRef
CREATE TABLE m_ref_include (
Expand Down Expand Up @@ -1476,7 +1477,7 @@ CREATE INDEX m_function_library_nameOrig_idx ON m_function_library (nameOrig);
ALTER TABLE m_function_library ADD CONSTRAINT m_function_library_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_function_library_subtypes_idx ON m_function_library USING gin(subtypes);
CREATE INDEX m_function_library_policySituation_idx
ON m_function_library USING GIN(policysituations gin__int_ops);
ON m_function_library USING gin(policysituations gin__int_ops);

-- Represents SequenceType, see https://wiki.evolveum.com/display/midPoint/Sequences
CREATE TABLE m_sequence (
Expand All @@ -1496,7 +1497,7 @@ CREATE TRIGGER m_sequence_oid_delete_tr AFTER DELETE ON m_sequence
CREATE INDEX m_sequence_nameOrig_idx ON m_sequence (nameOrig);
ALTER TABLE m_sequence ADD CONSTRAINT m_sequence_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_sequence_subtypes_idx ON m_sequence USING gin(subtypes);
CREATE INDEX m_sequence_policySituation_idx ON m_sequence USING GIN(policysituations gin__int_ops);
CREATE INDEX m_sequence_policySituation_idx ON m_sequence USING gin(policysituations gin__int_ops);

-- Represents FormType, see https://wiki.evolveum.com/display/midPoint/Custom+forms
CREATE TABLE m_form (
Expand All @@ -1516,7 +1517,7 @@ CREATE TRIGGER m_form_oid_delete_tr AFTER DELETE ON m_form
CREATE INDEX m_form_nameOrig_idx ON m_form (nameOrig);
ALTER TABLE m_form ADD CONSTRAINT m_form_nameNorm_key UNIQUE (nameNorm);
CREATE INDEX m_form_subtypes_idx ON m_form USING gin(subtypes);
CREATE INDEX m_form_policySituation_idx ON m_form USING GIN(policysituations gin__int_ops);
CREATE INDEX m_form_policySituation_idx ON m_form USING gin(policysituations gin__int_ops);
-- endregion

-- region Assignment/Inducement table
Expand Down Expand Up @@ -1546,6 +1547,7 @@ CREATE TABLE m_assignment (
extId INTEGER,
extOid TEXT, -- is this UUID too?
policySituations INTEGER[], -- soft-references m_uri, add index per table
subtypes TEXT[], -- only EQ filter
ext JSONB,
-- construction
resourceRefTargetOid UUID,
Expand Down Expand Up @@ -1578,8 +1580,10 @@ CREATE TABLE m_assignment (
)
INHERITS(m_container);

CREATE INDEX m_assignment_policySituation_idx ON m_assignment USING GIN(policysituations gin__int_ops);
CREATE INDEX m_assignment_ext_idx ON m_assignment USING gin (ext);
CREATE INDEX m_assignment_policySituation_idx
ON m_assignment USING gin(policysituations gin__int_ops);
CREATE INDEX m_assignment_subtypes_idx ON m_assignment USING gin(subtypes);
CREATE INDEX m_assignment_ext_idx ON m_assignment USING gin(ext);
-- TODO was: CREATE INDEX iAssignmentAdministrative ON m_assignment (administrativeStatus);
-- administrativeStatus has 3 states (ENABLED/DISABLED/ARCHIVED), not sure it's worth indexing
-- but it can be used as a condition to index other (e.g. WHERE administrativeStatus='ENABLED')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class MAssignment extends MContainer {
public Integer extId;
public String extOid;
public Integer[] policySituations;
public String[] subtypes;
public Jsonb ext;
// construction
public UUID resourceRefTargetOid;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public class QAssignment<OR extends MObject> extends QContainer<MAssignment, OR>
ColumnMetadata.named("extOid").ofType(Types.VARCHAR);
public static final ColumnMetadata POLICY_SITUATIONS =
ColumnMetadata.named("policySituations").ofType(Types.ARRAY);
public static final ColumnMetadata SUBTYPES =
ColumnMetadata.named("subtypes").ofType(Types.ARRAY);
public static final ColumnMetadata EXT = ColumnMetadata.named("ext").ofType(JSONB_TYPE);
// construction columns
public static final ColumnMetadata RESOURCE_REF_TARGET_OID =
Expand Down Expand Up @@ -148,6 +150,8 @@ public class QAssignment<OR extends MObject> extends QContainer<MAssignment, OR>
public final StringPath extOid = createString("extOid", EXT_OID);
public final ArrayPath<Integer[], Integer> policySituations =
createArray("policySituations", Integer[].class, POLICY_SITUATIONS);
public final ArrayPath<String[], String> subtypes =
createArray("subtypes", String[].class, SUBTYPES);
public final JsonbPath ext = addMetadata(add(new JsonbPath(forProperty("ext"))), EXT);
// construction attributes
public final UuidPath resourceRefTargetOid =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import static com.evolveum.midpoint.util.MiscUtil.asXMLGregorianCalendar;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType.*;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType.F_EXTENSION;

import java.util.Objects;

Expand Down Expand Up @@ -121,6 +120,7 @@ private QAssignmentMapping(
q -> q.tenantRefRelationId,
QOrgMapping::getOrgMapping);
addItemMapping(F_POLICY_SITUATION, multiUriMapper(q -> q.policySituations));
addItemMapping(F_SUBTYPE, multiStringMapper(q -> q.subtypes));

// TODO no idea how extId/Oid works, see RAssignment.getExtension
addExtensionMapping(F_EXTENSION, MExtItemHolderType.EXTENSION, q -> q.ext);
Expand Down Expand Up @@ -206,6 +206,11 @@ public AssignmentType toSchemaObject(MAssignment row) {
assignment.policySituation(resolveIdToUri(policySituationId));
}
}
if (row.subtypes != null) {
for (String subtype : row.subtypes) {
assignment.subtype(subtype);
}
}

if (row.resourceRefTargetOid != null) {
assignment.construction(new ConstructionType(prismContext())
Expand Down Expand Up @@ -289,6 +294,7 @@ public MAssignment insert(AssignmentType assignment, OR ownerRow, JdbcSession jd
// row.extId = assignment.getExtension()...id?;
// row.extOid =;
row.policySituations = processCacheableUris(assignment.getPolicySituation());
row.subtypes = listToArray(assignment.getSubtype());
row.ext = processExtensions(assignment.getExtension(), MExtItemHolderType.EXTENSION);

ConstructionType construction = assignment.getConstruction();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ public void initObjects() throws Exception {
.orgRef(org1Oid, OrgType.COMPLEX_TYPE, relation1)
.activation(new ActivationType(prismContext)
.validFrom("2021-03-01T00:00:00Z")
.validTo("2022-07-04T00:00:00Z")))
.validTo("2022-07-04T00:00:00Z"))
.subtype("ass-subtype-2"))
.assignment(new AssignmentType(prismContext)
.lifecycleState("assignment1-2")
.order(1))
Expand Down Expand Up @@ -235,7 +236,9 @@ public void initObjects() throws Exception {
.metadata(new MetadataType(prismContext)
.createApproverRef(user1Oid, UserType.COMPLEX_TYPE, ORG_DEFAULT))
.activation(new ActivationType(prismContext)
.validFrom("2021-01-01T00:00:00Z")))
.validFrom("2021-01-01T00:00:00Z"))
.subtype("ass-subtype-1")
.subtype("ass-subtype-2"))
.assignment(new AssignmentType(prismContext)
.activation(new ActivationType(prismContext)
.validTo("2022-01-01T00:00:00Z")))
Expand Down Expand Up @@ -620,6 +623,22 @@ private void searchCaseWorkItemByAssignee(String assigneeOid, String... expected
.extracting(o -> o.getOid())
.containsExactlyInAnyOrder(expectedCaseOids);
}

@Test
public void test190SearchUsersByAssignmentSubtype() throws Exception {
searchUsersTest("having assignment with specified subtype",
f -> f.item(UserType.F_ASSIGNMENT, AssignmentType.F_SUBTYPE).eq("ass-subtype-1"),
user3Oid);
}

@Test
public void test191SearchUsersByAssignmentSubtypeAnyValue() throws Exception {
searchUsersTest("having assignment with any of specified subtypes",
f -> f.item(UserType.F_ASSIGNMENT, AssignmentType.F_SUBTYPE)
.eq("ass-subtype-1", "ass-subtype-2"),
user1Oid, user3Oid);
}

// endregion

// region org filter
Expand Down

0 comments on commit 0018db7

Please sign in to comment.