Search in sources :

Example 6 with PredicateExtractionVisitor

use of com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor in project elide by yahoo.

the class RootCollectionFetchQueryBuilder method build.

/**
 * Constructs a query that fetches a root collection.
 *
 * @return the constructed query
 */
@Override
public Query build() {
    Type<?> entityClass = this.entityProjection.getType();
    String entityName = entityClass.getCanonicalName();
    String entityAlias = getTypeAlias(entityClass);
    Query query;
    FilterExpression filterExpression = entityProjection.getFilterExpression();
    if (filterExpression != null) {
        PredicateExtractionVisitor extractor = new PredicateExtractionVisitor();
        Collection<FilterPredicate> predicates = filterExpression.accept(extractor);
        // Build the WHERE clause
        String filterClause = WHERE + new FilterTranslator(dictionary).apply(filterExpression, USE_ALIAS);
        // Build the JOIN clause
        String joinClause = getJoinClauseFromFilters(filterExpression) + getJoinClauseFromSort(entityProjection.getSorting()) + extractToOneMergeJoins(entityClass, entityAlias);
        boolean requiresDistinct = entityProjection.getPagination() != null && containsOneToMany(filterExpression);
        boolean sortOverRelationship = entityProjection.getSorting() != null && entityProjection.getSorting().getSortingPaths().keySet().stream().anyMatch(path -> path.getPathElements().size() > 1);
        if (requiresDistinct && sortOverRelationship) {
            // SQL does not support distinct and order by on columns which are not selected
            throw new InvalidValueException("Combination of pagination, sorting over relationship and" + " filtering over toMany relationships unsupported");
        }
        query = session.createQuery(SELECT + (requiresDistinct ? DISTINCT : "") + entityAlias + FROM + entityName + AS + entityAlias + SPACE + joinClause + SPACE + filterClause + SPACE + getSortClause(entityProjection.getSorting()));
        // Fill in the query parameters
        supplyFilterQueryParameters(query, predicates);
    } else {
        query = session.createQuery(SELECT + entityAlias + FROM + entityName + AS + entityAlias + SPACE + getJoinClauseFromSort(entityProjection.getSorting()) + extractToOneMergeJoins(entityClass, entityAlias) + SPACE + getSortClause(entityProjection.getSorting()));
    }
    addPaginationToQuery(query);
    return query;
}
Also used : PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) InvalidValueException(com.yahoo.elide.core.exceptions.InvalidValueException) Type(com.yahoo.elide.core.type.Type) Collection(java.util.Collection) TypeHelper.getTypeAlias(com.yahoo.elide.core.utils.TypeHelper.getTypeAlias) EntityProjection(com.yahoo.elide.core.request.EntityProjection) Session(com.yahoo.elide.datastores.jpql.porting.Session) FilterTranslator(com.yahoo.elide.datastores.jpql.filter.FilterTranslator) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Query(com.yahoo.elide.datastores.jpql.porting.Query) InvalidValueException(com.yahoo.elide.core.exceptions.InvalidValueException) Query(com.yahoo.elide.datastores.jpql.porting.Query) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) FilterTranslator(com.yahoo.elide.datastores.jpql.filter.FilterTranslator)

Example 7 with PredicateExtractionVisitor

use of com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor in project elide by yahoo.

the class FilterPredicateTest method parse.

private Map<String, Set<FilterPredicate>> parse(MultivaluedMap<String, String> queryParams) {
    PredicateExtractionVisitor visitor = new PredicateExtractionVisitor();
    Map<String, FilterExpression> expressionMap;
    try {
        expressionMap = strategy.parseTypedExpression("/book", queryParams, NO_VERSION);
    } catch (ParseException e) {
        throw new BadRequestException(e.getMessage());
    }
    Map<String, Set<FilterPredicate>> returnMap = new HashMap<>();
    for (Map.Entry<String, FilterExpression> entry : expressionMap.entrySet()) {
        String typeName = entry.getKey();
        FilterExpression expression = entry.getValue();
        if (!returnMap.containsKey(typeName)) {
            returnMap.put(typeName, new HashSet<>());
        }
        returnMap.get(typeName).addAll(expression.accept(visitor));
    }
    return returnMap;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) ParseException(com.yahoo.elide.core.filter.dialect.ParseException) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) HashMap(java.util.HashMap) Map(java.util.Map) MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) MultivaluedMap(javax.ws.rs.core.MultivaluedMap)

Example 8 with PredicateExtractionVisitor

use of com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor in project elide by yahoo.

the class SQLQueryEngine method supplyFilterQueryParameters.

/**
 * Given a Prepared Statement, replaces any parameters with their values from client query.
 *
 * @param query The client query
 * @param stmt Customized Prepared Statement
 * @param dialect the SQL dialect
 */
private void supplyFilterQueryParameters(Query query, NamedParamPreparedStatement stmt, SQLDialect dialect) {
    Collection<FilterPredicate> predicates = new ArrayList<>();
    if (query.getWhereFilter() != null) {
        predicates.addAll(query.getWhereFilter().accept(new PredicateExtractionVisitor()));
    }
    if (query.getHavingFilter() != null) {
        predicates.addAll(query.getHavingFilter().accept(new PredicateExtractionVisitor()));
    }
    for (FilterPredicate filterPredicate : predicates) {
        Column column = metaDataStore.getColumn(filterPredicate.getEntityType(), filterPredicate.getField());
        if (filterPredicate.getOperator().isParameterized()) {
            boolean shouldEscape = filterPredicate.isMatchingOperator();
            filterPredicate.getParameters().forEach(param -> {
                try {
                    Object value = param.getValue();
                    value = convertForJdbc(filterPredicate.getEntityType(), column, value, dialect);
                    stmt.setObject(param.getName(), shouldEscape ? param.escapeMatching() : value);
                } catch (SQLException e) {
                    throw new IllegalStateException(e);
                }
            });
        }
    }
}
Also used : Column(com.yahoo.elide.datastores.aggregation.metadata.models.Column) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate)

Example 9 with PredicateExtractionVisitor

use of com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor in project elide by yahoo.

the class EntityProjectionTranslator method addHavingMetrics.

/**
 * Adds to the list of queried metrics any metric in the HAVING filter that has not been explicitly requested
 * by the client.
 */
private void addHavingMetrics() {
    if (havingFilter == null) {
        return;
    }
    // Flatten the HAVING filter expression into a list of predicates...
    havingFilter.accept(new PredicateExtractionVisitor()).forEach(filterPredicate -> {
        String fieldName = filterPredicate.getField();
        // If the predicate field is a metric
        if (queriedTable.getMetric(fieldName) != null) {
            // If the query doesn't contain this metric.
            if (metrics.stream().noneMatch((metric -> metric.getName().equals(fieldName)))) {
                // Construct a new projection and add it to the query.
                MetricProjection havingMetric = engine.constructMetricProjection(queriedTable.getMetric(fieldName), fieldName, new HashMap<>());
                metrics.add(havingMetric);
            }
        }
    });
}
Also used : PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) DimensionProjection(com.yahoo.elide.datastores.aggregation.query.DimensionProjection) Set(java.util.Set) EntityProjection(com.yahoo.elide.core.request.EntityProjection) Dimension(com.yahoo.elide.datastores.aggregation.metadata.models.Dimension) HashMap(java.util.HashMap) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Objects(java.util.Objects) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) FilterConstraints(com.yahoo.elide.datastores.aggregation.filter.visitor.FilterConstraints) Query(com.yahoo.elide.datastores.aggregation.query.Query) List(java.util.List) ImmutablePagination(com.yahoo.elide.datastores.aggregation.query.ImmutablePagination) Argument.getArgumentMapFromArgumentSet(com.yahoo.elide.core.request.Argument.getArgumentMapFromArgumentSet) TimeDimension(com.yahoo.elide.datastores.aggregation.metadata.models.TimeDimension) Table(com.yahoo.elide.datastores.aggregation.metadata.models.Table) TimeDimensionProjection(com.yahoo.elide.datastores.aggregation.query.TimeDimensionProjection) MetricProjection(com.yahoo.elide.datastores.aggregation.query.MetricProjection) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Collections(java.util.Collections) LinkedHashSet(java.util.LinkedHashSet) RequestScope(com.yahoo.elide.core.RequestScope) SplitFilterExpressionVisitor(com.yahoo.elide.datastores.aggregation.filter.visitor.SplitFilterExpressionVisitor) MetricProjection(com.yahoo.elide.datastores.aggregation.query.MetricProjection) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor)

Example 10 with PredicateExtractionVisitor

use of com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor in project elide by yahoo.

the class AbstractHQLQueryBuilder method getJoinClauseFromFilters.

/**
 * Extracts all the HQL JOIN clauses from given filter expression.
 * @param filterExpression the filter expression to extract a join clause from
 * @param skipFetches JOIN but don't FETCH JOIN a relationship.
 * @return an HQL join clause
 */
protected String getJoinClauseFromFilters(FilterExpression filterExpression, boolean skipFetches) {
    PredicateExtractionVisitor visitor = new PredicateExtractionVisitor(new ArrayList<>());
    Collection<FilterPredicate> predicates = filterExpression.accept(visitor);
    return predicates.stream().map(predicate -> extractJoinClause(predicate.getPath(), skipFetches)).collect(Collectors.joining(SPACE));
}
Also used : PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) Path(com.yahoo.elide.core.Path) Sorting(com.yahoo.elide.core.request.Sorting) Predicate(java.util.function.Predicate) Collection(java.util.Collection) TypeHelper.appendAlias(com.yahoo.elide.core.utils.TypeHelper.appendAlias) TypeHelper.getTypeAlias(com.yahoo.elide.core.utils.TypeHelper.getTypeAlias) Set(java.util.Set) EntityProjection(com.yahoo.elide.core.request.EntityProjection) StringUtils(org.apache.commons.lang3.StringUtils) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Query(com.yahoo.elide.datastores.jpql.porting.Query) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) List(java.util.List) Pagination(com.yahoo.elide.core.request.Pagination) Type(com.yahoo.elide.core.type.Type) Map(java.util.Map) Session(com.yahoo.elide.datastores.jpql.porting.Session) RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate)

Aggregations

PredicateExtractionVisitor (com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor)14 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)11 FilterPredicate (com.yahoo.elide.core.filter.predicates.FilterPredicate)11 Set (java.util.Set)6 Query (com.yahoo.elide.datastores.jpql.porting.Query)5 ArrayList (java.util.ArrayList)5 List (java.util.List)5 Map (java.util.Map)5 Collectors (java.util.stream.Collectors)5 FilterTranslator (com.yahoo.elide.datastores.jpql.filter.FilterTranslator)4 HashMap (java.util.HashMap)4 Path (com.yahoo.elide.core.Path)3 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)3 InvalidOperationException (com.yahoo.elide.core.exceptions.InvalidOperationException)3 Argument (com.yahoo.elide.core.request.Argument)3 EntityProjection (com.yahoo.elide.core.request.EntityProjection)3 Type (com.yahoo.elide.core.type.Type)3 Collection (java.util.Collection)3 HashSet (java.util.HashSet)3 LinkedHashSet (java.util.LinkedHashSet)3