Search in sources :

Example 1 with PredicateExtractionVisitor

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

the class DefaultQueryValidator method validateHavingClause.

@Override
public void validateHavingClause(Query query) {
    FilterExpression havingClause = query.getHavingFilter();
    if (havingClause == null) {
        return;
    }
    havingClause.accept(new PredicateExtractionVisitor()).forEach(predicate -> {
        Path path = predicate.getPath();
        if (path.getPathElements().size() > 1) {
            throw new InvalidOperationException("Relationship traversal not supported for analytic queries.");
        }
        validatePredicate(query, predicate);
        extractFilterProjections(query, havingClause).stream().forEach(projection -> {
            Predicate<ColumnProjection> filterByNameAndArgs = (column) -> (column.getAlias().equals(projection.getAlias()) || column.getName().equals(projection.getName())) && column.getArguments().equals(projection.getArguments());
            // Query by (alias or name) and arguments.   The filter may or may not be using the alias.
            if (query.getColumnProjection(filterByNameAndArgs) == null) {
                Predicate<ColumnProjection> filterByName = (column) -> (column.getAlias().equals(projection.getAlias()) || column.getName().equals(projection.getName()));
                // The column wasn't projected at all.
                if (query.getColumnProjection(filterByName) == null) {
                    throw new InvalidOperationException(String.format("Post aggregation filtering on '%s' requires the field to be projected in the response", projection.getAlias()));
                // The column was projected but arguments didn't match.
                } else {
                    throw new InvalidOperationException(String.format("Post aggregation filtering on '%s' requires the field to be projected " + "in the response with matching arguments", projection.getAlias()));
                }
            }
        });
    });
}
Also used : Path(com.yahoo.elide.core.Path) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) Path(com.yahoo.elide.core.Path) Queryable.extractFilterProjections(com.yahoo.elide.datastores.aggregation.query.Queryable.extractFilterProjections) Argument(com.yahoo.elide.core.request.Argument) HashSet(java.util.HashSet) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) Map(java.util.Map) Column(com.yahoo.elide.datastores.aggregation.metadata.models.Column) ColumnProjection(com.yahoo.elide.datastores.aggregation.query.ColumnProjection) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) LinkedHashSet(java.util.LinkedHashSet) Sorting(com.yahoo.elide.core.request.Sorting) Predicate(java.util.function.Predicate) ValueType(com.yahoo.elide.datastores.aggregation.metadata.enums.ValueType) ArgumentDefinition(com.yahoo.elide.datastores.aggregation.metadata.models.ArgumentDefinition) Set(java.util.Set) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Query(com.yahoo.elide.datastores.aggregation.query.Query) List(java.util.List) Stream(java.util.stream.Stream) SQLTable(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable) Type(com.yahoo.elide.core.type.Type) Operator(com.yahoo.elide.core.filter.Operator) Optional(java.util.Optional) ColumnProjection(com.yahoo.elide.datastores.aggregation.query.ColumnProjection) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression)

Example 2 with PredicateExtractionVisitor

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

the class DefaultQueryValidator method validateWhereClause.

@Override
public void validateWhereClause(Query query) {
    FilterExpression whereClause = query.getWhereFilter();
    if (whereClause == null) {
        return;
    }
    whereClause.accept(new PredicateExtractionVisitor()).forEach(predicate -> {
        Path path = predicate.getPath();
        if (path.getPathElements().size() > 1) {
            throw new InvalidOperationException("Relationship traversal not supported for analytic queries.");
        }
        validatePredicate(query, predicate);
    });
}
Also used : Path(com.yahoo.elide.core.Path) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression)

Example 3 with PredicateExtractionVisitor

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

the class Queryable method getFilterProjections.

default List<ColumnProjection> getFilterProjections(FilterExpression expression) {
    List<ColumnProjection> results = new ArrayList<>();
    if (expression == null) {
        return results;
    }
    Collection<FilterPredicate> predicates = expression.accept(new PredicateExtractionVisitor());
    predicates.stream().forEach((predicate -> {
        Map<String, Argument> arguments = new HashMap<>();
        predicate.getPath().lastElement().get().getArguments().forEach(argument -> arguments.put(argument.getName(), argument));
        ColumnProjection projection = getSource().getColumnProjection(predicate.getField(), arguments);
        results.add(projection);
    }));
    return results;
}
Also used : PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Set(java.util.Set) HashMap(java.util.HashMap) Streams(com.google.common.collect.Streams) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) Argument(com.yahoo.elide.core.request.Argument) ConnectionDetails(com.yahoo.elide.datastores.aggregation.queryengines.sql.ConnectionDetails) List(java.util.List) SQLDialect(com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect) SQLJoin(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLJoin) Map(java.util.Map) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Collections(java.util.Collections) LinkedHashSet(java.util.LinkedHashSet) ArrayList(java.util.ArrayList) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) HashMap(java.util.HashMap) Map(java.util.Map)

Example 4 with PredicateExtractionVisitor

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

the class Queryable method extractFilterProjections.

/**
 * Converts a filter expression into a set of ColumnProjections.
 * @param query The parent query.
 * @param expression The filter expression to extract.
 * @return A set of zero or more column projections with their arguments.
 */
static Set<ColumnProjection> extractFilterProjections(Queryable query, FilterExpression expression) {
    if (expression == null) {
        return new LinkedHashSet<>();
    }
    Collection<FilterPredicate> predicates = expression.accept(new PredicateExtractionVisitor());
    Set<ColumnProjection> filterProjections = new LinkedHashSet<>();
    predicates.stream().forEach((predicate -> {
        Map<String, Argument> arguments = new HashMap<>();
        predicate.getPath().lastElement().get().getArguments().forEach(argument -> arguments.put(argument.getName(), argument));
        ColumnProjection projection = query.getSource().getColumnProjection(predicate.getField(), arguments);
        if (projection != null) {
            filterProjections.add(projection);
        }
    }));
    return filterProjections;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Set(java.util.Set) HashMap(java.util.HashMap) Streams(com.google.common.collect.Streams) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) Argument(com.yahoo.elide.core.request.Argument) ConnectionDetails(com.yahoo.elide.datastores.aggregation.queryengines.sql.ConnectionDetails) List(java.util.List) SQLDialect(com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect) SQLJoin(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLJoin) Map(java.util.Map) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Collections(java.util.Collections) LinkedHashSet(java.util.LinkedHashSet) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with PredicateExtractionVisitor

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

the class RootCollectionPageTotalsQueryBuilder method build.

/**
 * Constructs a query that returns the count of a root collection.
 *
 * Constructs a query like:
 *
 * SELECT COUNT(DISTINCT Author)
 * FROM Author AS Author
 *
 * @return the constructed query
 */
@Override
public Query build() {
    Type<?> entityClass = entityProjection.getType();
    String entityName = entityClass.getCanonicalName();
    String entityAlias = getTypeAlias(entityClass);
    Collection<FilterPredicate> predicates;
    String filterClause;
    String joinClause;
    FilterExpression filterExpression = entityProjection.getFilterExpression();
    if (filterExpression != null) {
        PredicateExtractionVisitor extractor = new PredicateExtractionVisitor();
        predicates = filterExpression.accept(extractor);
        // Build the WHERE clause
        filterClause = WHERE + new FilterTranslator(dictionary).apply(filterExpression, USE_ALIAS);
        // Build the JOIN clause
        joinClause = getJoinClauseFromFilters(filterExpression, true);
    } else {
        predicates = new HashSet<>();
        filterClause = "";
        joinClause = "";
    }
    Query query = session.createQuery("SELECT COUNT(DISTINCT " + entityAlias + ") " + FROM + entityName + AS + entityAlias + SPACE + joinClause + SPACE + filterClause);
    supplyFilterQueryParameters(query, predicates);
    return query;
}
Also used : 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)

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