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()));
}
}
});
});
}
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);
});
}
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;
}
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;
}
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;
}
Aggregations