use of com.evolveum.midpoint.repo.sql.query2.InterpretationContext in project midpoint by Evolveum.
the class QueryInterpreter2 method interpret.
public RootHibernateQuery interpret(ObjectQuery query, @NotNull Class<? extends Containerable> type, Collection<SelectorOptions<GetOperationOptions>> options, @NotNull PrismContext prismContext, boolean countingObjects, @NotNull Session session) throws QueryException {
boolean distinct = GetOperationOptions.isDistinct(SelectorOptions.findRootOptions(options));
LOGGER.trace("Interpreting query for type '{}' (counting={}, distinct={}), query:\n{}", type, countingObjects, distinct, query);
InterpretationContext context = new InterpretationContext(this, type, prismContext, session);
interpretQueryFilter(context, query);
String rootAlias = context.getHibernateQuery().getPrimaryEntityAlias();
ResultStyle resultStyle = getResultStyle(context);
if (countingObjects) {
interpretPagingAndSorting(context, query, true);
RootHibernateQuery hibernateQuery = context.getHibernateQuery();
hibernateQuery.addProjectionElement(new CountProjectionElement(resultStyle.getIdentifiers(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();
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, session);
interpretPagingAndSorting(wrapperContext, query, false);
RootHibernateQuery wrapperQuery = wrapperContext.getHibernateQuery();
String wrappedRootAlias = wrapperQuery.getPrimaryEntityAlias();
wrapperQuery.setResultTransformer(resultStyle.getResultTransformer());
wrapperQuery.addProjectionElementsFor(resultStyle.getIdentifiers(wrappedRootAlias));
wrapperQuery.addProjectionElementsFor(resultStyle.getContentAttributes(wrappedRootAlias));
wrapperQuery.getConditions().add(wrapperQuery.createIn(wrapperQuery.getPrimaryEntityAlias() + ".oid", 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;
}
}
use of com.evolveum.midpoint.repo.sql.query2.InterpretationContext in project midpoint by Evolveum.
the class QueryInterpreter2 method findAndCreateRestriction.
private <T extends ObjectFilter> Restriction findAndCreateRestriction(@NotNull T filter, @NotNull InterpretationContext context, Restriction parent) throws QueryException {
LOGGER.trace("Determining restriction for filter {}", filter);
ItemPathResolver helper = context.getItemPathResolver();
JpaEntityDefinition baseEntityDefinition;
if (parent != null) {
baseEntityDefinition = parent.getBaseHqlEntityForChildren().getJpaDefinition();
} else {
baseEntityDefinition = context.getRootEntityDefinition();
}
Restriction restriction = findAndCreateRestrictionInternal(filter, context, parent, helper, baseEntityDefinition);
LOGGER.trace("Restriction for {} is {}", filter.getClass().getSimpleName(), restriction);
return restriction;
}
use of com.evolveum.midpoint.repo.sql.query2.InterpretationContext in project midpoint by Evolveum.
the class QueryInterpreter2 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<JpaDataNodeDefinition> 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);
}
}
use of com.evolveum.midpoint.repo.sql.query2.InterpretationContext in project midpoint by Evolveum.
the class ItemValueRestriction method createPropertyVsConstantCondition.
protected Condition createPropertyVsConstantCondition(String hqlPropertyPath, Object value, ValueFilter filter) throws QueryException {
ItemRestrictionOperation operation = findOperationForFilter(filter);
InterpretationContext context = getContext();
QueryInterpreter2 interpreter = context.getInterpreter();
Matcher matcher = interpreter.findMatcher(value);
String matchingRule = filter.getMatchingRule() != null ? filter.getMatchingRule().getLocalPart() : null;
// TODO treat null for multivalued properties (at least throw an exception!)
return matcher.match(context.getHibernateQuery(), operation, hqlPropertyPath, value, matchingRule);
}
use of com.evolveum.midpoint.repo.sql.query2.InterpretationContext in project midpoint by Evolveum.
the class NaryLogicalRestriction method updateJunction.
protected void updateJunction(List<? extends ObjectFilter> subfilters, JunctionCondition junction) throws QueryException {
InterpretationContext context = getContext();
QueryInterpreter2 interpreter = context.getInterpreter();
for (ObjectFilter subfilter : subfilters) {
Condition condition = interpreter.interpretFilter(context, subfilter, this);
junction.add(condition);
}
}
Aggregations