Search in sources :

Example 1 with RootHibernateQuery

use of com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery in project midpoint by Evolveum.

the class OrgRestriction method interpret.

@Override
public Condition interpret() throws QueryException {
    RootHibernateQuery hibernateQuery = getContext().getHibernateQuery();
    if (filter.isRoot()) {
        // oid in (select descendantOid from ROrgClosure group by descendantOid having count(descendantOid) = 1)
        return hibernateQuery.createIn(getBaseHqlEntity().getHqlPath() + ".oid", "select descendantOid from ROrgClosure group by descendantOid having count(descendantOid) = 1");
    }
    if (filter.getOrgRef() == null) {
        throw new QueryException("No organization reference defined in the search query.");
    }
    if (filter.getOrgRef().getOid() == null) {
        throw new QueryException("No oid specified in organization reference " + filter.getOrgRef().debugDump());
    }
    String orgOidParamName = hibernateQuery.addParameter("orgOid", filter.getOrgRef().getOid());
    String relationParamName = "";
    QName relation = filter.getOrgRef().getRelation();
    if (doesRelationRestrictionExist(relation)) {
        relationParamName = hibernateQuery.addParameter("relation", ReferenceRestriction.getRelationsToTest(relation, context));
    }
    // oid in ...
    String oidQueryText;
    switch(filter.getScope()) {
        case ONE_LEVEL:
            oidQueryText = // TODO distinct(ref.ownerOid) ? (was in original QueryInterpreter)
            "select ref.ownerOid " + "from RObjectReference ref " + "where " + "ref.referenceType = " + RReferenceType.OBJECT_PARENT_ORG.ordinal() + (doesRelationRestrictionExist(relation) ? " and ref.relation in (:" + relationParamName + ")" : "") + " and ref.targetOid = :" + orgOidParamName;
            break;
        case ANCESTORS:
            oidQueryText = "select c.ancestorOid " + "from ROrgClosure c " + "where " + "c.ancestorOid != :" + orgOidParamName + " and " + "c.descendantOid = :" + orgOidParamName;
            break;
        case SUBTREE:
        default:
            oidQueryText = "select ref.ownerOid " + "from RObjectReference ref " + "where " + "ref.referenceType = " + RReferenceType.OBJECT_PARENT_ORG.ordinal() + (doesRelationRestrictionExist(relation) ? " and ref.relation in (:" + relationParamName + ")" : "") + " and ref.targetOid in (" + "select descendantOid from ROrgClosure where ancestorOid = :" + orgOidParamName + ")";
    }
    return hibernateQuery.createIn(getBaseHqlEntity().getHqlPath() + ".oid", oidQueryText);
}
Also used : QueryException(com.evolveum.midpoint.repo.sqlbase.QueryException) RootHibernateQuery(com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery) QName(javax.xml.namespace.QName)

Example 2 with RootHibernateQuery

use of com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery in project midpoint by Evolveum.

the class TypeRestriction method interpret.

@Override
public Condition interpret() throws QueryException {
    InterpretationContext context = getContext();
    RootHibernateQuery hibernateQuery = context.getHibernateQuery();
    String property = getBaseHqlEntity().getHqlPath() + "." + RObject.F_OBJECT_TYPE_CLASS;
    Collection<RObjectType> values = getValues(filter.getType());
    Condition basedOnType;
    if (values.size() > 1) {
        basedOnType = hibernateQuery.createIn(property, values);
    } else {
        basedOnType = hibernateQuery.createEq(property, values.iterator().next());
    }
    if (filter.getFilter() == null) {
        return basedOnType;
    }
    QueryInterpreter interpreter = context.getInterpreter();
    Condition basedOnFilter = interpreter.interpretFilter(context, filter.getFilter(), this);
    return hibernateQuery.createAnd(basedOnType, basedOnFilter);
}
Also used : Condition(com.evolveum.midpoint.repo.sql.query.hqm.condition.Condition) RObjectType(com.evolveum.midpoint.repo.sql.data.common.other.RObjectType) InterpretationContext(com.evolveum.midpoint.repo.sql.query.InterpretationContext) RootHibernateQuery(com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery) QueryInterpreter(com.evolveum.midpoint.repo.sql.query.QueryInterpreter)

Example 3 with RootHibernateQuery

use of com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery in project midpoint by Evolveum.

the class QueryInterpreter method interpret.

public RootHibernateQuery interpret(ObjectQuery query, @NotNull Class<? extends Containerable> type, Collection<SelectorOptions<GetOperationOptions>> options, @NotNull PrismContext prismContext, @NotNull RelationRegistry relationRegistry, boolean countingObjects, @NotNull Session session) throws QueryException {
    boolean distinctRequested = GetOperationOptions.isDistinct(SelectorOptions.findRootOptions(options));
    LOGGER.trace("Interpreting query for type '{}' (counting={}, distinctRequested={}), query:\n{}", type, countingObjects, distinctRequested, query);
    InterpretationContext context = new InterpretationContext(this, type, prismContext, relationRegistry, extItemDictionary, session);
    interpretQueryFilter(context, query);
    String rootAlias = context.getHibernateQuery().getPrimaryEntityAlias();
    ResultStyle resultStyle = getResultStyle(context);
    if (countingObjects) {
        interpretPagingAndSorting(context, query, true);
        RootHibernateQuery hibernateQuery = context.getHibernateQuery();
        boolean distinct = distinctRequested && !hibernateQuery.isDistinctNotNecessary();
        hibernateQuery.addProjectionElement(new CountProjectionElement(resultStyle.getCountString(rootAlias), distinct));
        return hibernateQuery;
    }
    /*
           Some databases don't support DISTINCT on BLOBs. In these cases we have to create query like:
           select
             u.oid, u.fullObject, u.stringsCount, ..., u.booleansCount
           from
             RUser u
           where
             u.oid in (select distinct u.oid from RUser u where ...)
         */
    boolean distinctBlobCapable = !repoConfiguration.isUsingOracle() && !repoConfiguration.isUsingSQLServer();
    RootHibernateQuery hibernateQuery = context.getHibernateQuery();
    boolean distinct = distinctRequested && !hibernateQuery.isDistinctNotNecessary();
    hibernateQuery.setDistinct(distinct);
    hibernateQuery.addProjectionElementsFor(resultStyle.getIdentifiers(rootAlias));
    if (distinct && !distinctBlobCapable) {
        String subqueryText = "\n" + hibernateQuery.getAsHqlText(2, true);
        InterpretationContext wrapperContext = new InterpretationContext(this, type, prismContext, relationRegistry, extItemDictionary, session);
        try {
            interpretPagingAndSorting(wrapperContext, query, false);
        } catch (QueryException e) {
            // This fixes cases like MID-6561 and brings in needed joins and wheres
            // to the outer query, but we don't want to burden all queries with it.
            LOGGER.debug("Potentially recoverable '{}'.\n" + "Trying once more after wrapper context interprets the query.", e.toString());
            interpretQueryFilter(wrapperContext, query);
            interpretPagingAndSorting(wrapperContext, query, false);
        }
        RootHibernateQuery wrapperQuery = wrapperContext.getHibernateQuery();
        if (repoConfiguration.isUsingSQLServer() && resultStyle.getIdentifiers("").size() > 1) {
            // using 'where exists' clause
            // FIXME refactor this ugly code
            // to distinguish from the same alias in inner query
            String wrappedRootAlias = "_" + wrapperQuery.getPrimaryEntityAlias();
            wrapperQuery.setPrimaryEntityAlias(wrappedRootAlias);
            wrapperQuery.setResultTransformer(resultStyle.getResultTransformer());
            wrapperQuery.addProjectionElementsFor(resultStyle.getIdentifiers(wrappedRootAlias));
            wrapperQuery.addProjectionElementsFor(resultStyle.getContentAttributes(wrappedRootAlias));
            StringBuilder linkingCondition = new StringBuilder();
            for (String id : resultStyle.getIdentifiers(wrappedRootAlias)) {
                linkingCondition.append(" and ").append(id).append(" = ").append(id.substring(1));
            }
            wrapperQuery.getConditions().add(wrapperQuery.createExists(subqueryText, linkingCondition.toString()));
        } else {
            // using 'in' clause (multi-column only for Oracle)
            String wrappedRootAlias = wrapperQuery.getPrimaryEntityAlias();
            wrapperQuery.setResultTransformer(resultStyle.getResultTransformer());
            wrapperQuery.addProjectionElementsFor(resultStyle.getIdentifiers(wrappedRootAlias));
            wrapperQuery.addProjectionElementsFor(resultStyle.getContentAttributes(wrappedRootAlias));
            List<String> inVariablesList = resultStyle.getIdentifiers(wrapperQuery.getPrimaryEntityAlias());
            String inVariablesString = inVariablesList.size() != 1 ? "(" + StringUtils.join(inVariablesList, ", ") + ")" : inVariablesList.get(0);
            wrapperQuery.getConditions().add(wrapperQuery.createIn(inVariablesString, subqueryText));
        }
        wrapperQuery.addParametersFrom(hibernateQuery.getParameters());
        return wrapperQuery;
    } else {
        interpretPagingAndSorting(context, query, false);
        hibernateQuery.setResultTransformer(resultStyle.getResultTransformer());
        hibernateQuery.addProjectionElementsFor(resultStyle.getContentAttributes(rootAlias));
        if (distinct) {
            // SQL requires this
            hibernateQuery.addProjectionElementsFor(getOrderingAttributes(context));
        }
        return hibernateQuery;
    }
}
Also used : QueryException(com.evolveum.midpoint.repo.sqlbase.QueryException) CountProjectionElement(com.evolveum.midpoint.repo.sql.query.hqm.CountProjectionElement) RootHibernateQuery(com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) RPolyString(com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString)

Example 4 with RootHibernateQuery

use of com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery in project midpoint by Evolveum.

the class QueryInterpreter method interpretPagingAndSorting.

private void interpretPagingAndSorting(InterpretationContext context, ObjectQuery query, boolean countingObjects) throws QueryException {
    RootHibernateQuery hibernateQuery = context.getHibernateQuery();
    String rootAlias = hibernateQuery.getPrimaryEntityAlias();
    // noinspection StringEquality
    if (query != null && query.getPaging() != null && query.getPaging().hasCookie() && query.getPaging().getCookie() != ObjectRetriever.NULL_OID_MARKER) {
        ObjectPaging paging = query.getPaging();
        Condition c = hibernateQuery.createSimpleComparisonCondition(rootAlias + ".oid", paging.getCookie(), ">");
        hibernateQuery.addCondition(c);
    }
    if (!countingObjects && query != null && query.getPaging() != null) {
        if (query.getPaging().hasCookie()) {
            // very special case - ascending ordering by OID (nothing more)
            updatePagingAndSortingByOid(hibernateQuery, query.getPaging());
        } else {
            updatePagingAndSorting(context, query.getPaging());
        }
    }
}
Also used : Condition(com.evolveum.midpoint.repo.sql.query.hqm.condition.Condition) RootHibernateQuery(com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) RPolyString(com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString)

Example 5 with RootHibernateQuery

use of com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery in project midpoint by Evolveum.

the class QueryInterpreter method addOrdering.

private void addOrdering(InterpretationContext context, ObjectOrdering ordering) throws QueryException {
    ItemPath orderByPath = ordering.getOrderBy();
    // TODO if we'd like to have order-by extension properties, we'd need to provide itemDefinition for them
    ProperDataSearchResult<?> result = context.getItemPathResolver().findProperDataDefinition(context.getRootEntityDefinition(), orderByPath, null, JpaDataNodeDefinition.class, context.getPrismContext());
    if (result == null) {
        LOGGER.error("Unknown path '" + orderByPath + "', couldn't find definition for it, " + "list will not be ordered by it.");
        return;
    }
    JpaDataNodeDefinition targetDefinition = result.getLinkDefinition().getTargetDefinition();
    if (targetDefinition instanceof JpaAnyContainerDefinition) {
        throw new QueryException("Sorting based on extension item or attribute is not supported yet: " + orderByPath);
    } else if (targetDefinition instanceof JpaReferenceDefinition) {
        throw new QueryException("Sorting based on reference is not supported: " + orderByPath);
    } else if (result.getLinkDefinition().isMultivalued()) {
        throw new QueryException("Sorting based on multi-valued item is not supported: " + orderByPath);
    } else if (targetDefinition instanceof JpaEntityDefinition) {
        throw new QueryException("Sorting based on entity is not supported: " + orderByPath);
    } else if (!(targetDefinition instanceof JpaPropertyDefinition)) {
        throw new IllegalStateException("Unknown item definition type: " + result.getClass());
    }
    JpaEntityDefinition baseEntityDefinition = result.getEntityDefinition();
    JpaPropertyDefinition orderByDefinition = (JpaPropertyDefinition) targetDefinition;
    String hqlPropertyPath = context.getItemPathResolver().resolveItemPath(orderByPath, null, context.getPrimaryEntityAlias(), baseEntityDefinition, true).getHqlPath();
    if (RPolyString.class.equals(orderByDefinition.getJpaClass())) {
        hqlPropertyPath += ".orig";
    }
    RootHibernateQuery hibernateQuery = context.getHibernateQuery();
    if (ordering.getDirection() != null) {
        switch(ordering.getDirection()) {
            case ASCENDING:
                hibernateQuery.addOrdering(hqlPropertyPath, OrderDirection.ASCENDING);
                break;
            case DESCENDING:
                hibernateQuery.addOrdering(hqlPropertyPath, OrderDirection.DESCENDING);
                break;
        }
    } else {
        hibernateQuery.addOrdering(hqlPropertyPath, OrderDirection.ASCENDING);
    }
}
Also used : QueryException(com.evolveum.midpoint.repo.sqlbase.QueryException) RootHibernateQuery(com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) RPolyString(com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Aggregations

RootHibernateQuery (com.evolveum.midpoint.repo.sql.query.hqm.RootHibernateQuery)14 QueryException (com.evolveum.midpoint.repo.sqlbase.QueryException)8 PolyString (com.evolveum.midpoint.prism.polystring.PolyString)5 RPolyString (com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString)4 Condition (com.evolveum.midpoint.repo.sql.query.hqm.condition.Condition)4 QName (javax.xml.namespace.QName)3 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)2 QueryInterpreter (com.evolveum.midpoint.repo.sql.query.QueryInterpreter)2 JoinSpecification (com.evolveum.midpoint.repo.sql.query.hqm.JoinSpecification)2 AndCondition (com.evolveum.midpoint.repo.sql.query.hqm.condition.AndCondition)2 HqlDataInstance (com.evolveum.midpoint.repo.sql.query.resolution.HqlDataInstance)2 PrismReferenceValue (com.evolveum.midpoint.prism.PrismReferenceValue)1 AllFilter (com.evolveum.midpoint.prism.query.AllFilter)1 ComparativeFilter (com.evolveum.midpoint.prism.query.ComparativeFilter)1 EqualFilter (com.evolveum.midpoint.prism.query.EqualFilter)1 RObjectType (com.evolveum.midpoint.repo.sql.data.common.other.RObjectType)1 InterpretationContext (com.evolveum.midpoint.repo.sql.query.InterpretationContext)1 RQuery (com.evolveum.midpoint.repo.sql.query.RQuery)1 RQueryImpl (com.evolveum.midpoint.repo.sql.query.RQueryImpl)1 JpaDataNodeDefinition (com.evolveum.midpoint.repo.sql.query.definition.JpaDataNodeDefinition)1