use of com.yahoo.elide.core.filter.expression.FilterExpression in project elide by yahoo.
the class PermissionToFilterExpressionVisitorTest method filterExpressionForPermissions.
private FilterExpression filterExpressionForPermissions(String permission) {
Function<Check, Expression> checkFn = (check) -> new CheckExpression(check, null, requestScope, null, cache);
ParseTree expression = EntityPermissions.parseExpression(permission);
PermissionToFilterExpressionVisitor fev = new PermissionToFilterExpressionVisitor(dictionary, requestScope, null);
return expression.accept(new PermissionExpressionVisitor(dictionary, checkFn)).accept(NORMALIZATION_VISITOR).accept(fev);
}
use of com.yahoo.elide.core.filter.expression.FilterExpression in project elide by yahoo.
the class AggregationDataStoreTransaction method addColumnFilterArguments.
@VisibleForTesting
Query addColumnFilterArguments(Table table, Query query, EntityDictionary dictionary) {
Query.QueryBuilder queryBuilder = Query.builder();
query.getColumnProjections().stream().forEach(projection -> {
Column column = table.getColumn(Column.class, projection.getName());
FilterExpression requiredFilter = column.getRequiredFilter(dictionary);
if (requiredFilter != null) {
Map<String, Argument> allArguments = validateRequiredFilter(requiredFilter, query, column);
if (projection.getArguments() != null) {
allArguments.putAll(projection.getArguments());
}
queryBuilder.column(projection.withArguments(allArguments));
} else {
queryBuilder.column(projection);
}
});
return queryBuilder.arguments(query.getArguments()).havingFilter(query.getHavingFilter()).whereFilter(query.getWhereFilter()).sorting(query.getSorting()).pagination(query.getPagination()).bypassingCache(query.isBypassingCache()).source(query.getSource()).scope(query.getScope()).build();
}
use of com.yahoo.elide.core.filter.expression.FilterExpression in project elide by yahoo.
the class EntityProjectionMakerTest method testRootCollectionWithGlobalFilter.
@Test
public void testRootCollectionWithGlobalFilter() {
MultivaluedMap<String, String> queryParams = new MultivaluedHashMap<>();
queryParams.add("filter", "genre=='Science Fiction'");
String path = "/book";
RequestScope scope = new TestRequestScope(dictionary, path, queryParams);
FilterExpression expression = new InPredicate(new Path(Book.class, dictionary, "genre"), "Science Fiction");
EntityProjectionMaker maker = new EntityProjectionMaker(dictionary, scope);
EntityProjection expected = EntityProjection.builder().type(Book.class).attribute(Attribute.builder().name("language").type(String.class).build()).attribute(Attribute.builder().name("genre").type(String.class).build()).attribute(Attribute.builder().name("title").type(String.class).build()).attribute(Attribute.builder().name("awards").type(Collection.class).build()).attribute(Attribute.builder().name("publishDate").type(long.class).build()).attribute(Attribute.builder().name("authorTypes").type(Collection.class).build()).attribute(Attribute.builder().name("price").type(Price.class).build()).filterExpression(expression).relationship("publisher", EntityProjection.builder().type(Publisher.class).build()).relationship("editor", EntityProjection.builder().type(Editor.class).build()).relationship("authors", EntityProjection.builder().type(Author.class).build()).pagination(PaginationImpl.getDefaultPagination(ClassType.of(Book.class))).build();
EntityProjection actual = maker.parsePath(path);
projectionEquals(expected, actual);
}
use of com.yahoo.elide.core.filter.expression.FilterExpression in project elide by yahoo.
the class MatchesTemplateVisitor method isValid.
/**
* Determines if a client filter matches or contains a subexpression that matches a template filter.
* @param templateFilter A templated filter expression
* @param clientFilter The client provided filter expression.
* @param arguments If the client filter matches, extract any table arguments.
* @return True if the client filter matches. False otherwise.
*/
public static boolean isValid(FilterExpression templateFilter, FilterExpression clientFilter, Map<String, Argument> arguments) {
Preconditions.checkNotNull(templateFilter);
if (clientFilter == null) {
return false;
}
// First we normalize the filters so any NOT clauses are pushed down immediately in front of a predicate.
// This lets us treat logical AND and OR without regard for any preceding NOT clauses.
FilterExpression normalizedTemplateFilter = templateFilter.accept(new FilterExpressionNormalizationVisitor());
FilterExpression normalizedClientFilter = clientFilter.accept(new FilterExpressionNormalizationVisitor());
MatchesTemplateVisitor templateVisitor = new MatchesTemplateVisitor(normalizedTemplateFilter);
boolean matches = normalizedClientFilter.accept(templateVisitor);
if (matches) {
arguments.putAll(templateVisitor.arguments);
}
return matches;
}
use of com.yahoo.elide.core.filter.expression.FilterExpression 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()));
}
}
});
});
}
Aggregations