Search in sources :

Example 6 with AndFilterExpression

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

the class AggregateBeforeJoinOptimizerTest method testWhereOnDimensionNotInProjectionNotRequiringJoin.

@Test
public void testWhereOnDimensionNotInProjectionNotRequiringJoin() {
    SQLTable gameRevenueTable = (SQLTable) metaDataStore.getTable("gameRevenue", NO_VERSION);
    FilterExpression where = new AndFilterExpression(new FilterPredicate(new Path(GameRevenue.class, dictionary, "countryIsoCode"), Operator.IN, Arrays.asList("foo")), new FilterPredicate(new Path(GameRevenue.class, dictionary, "category"), Operator.IN, Arrays.asList("foo")));
    Query query = Query.builder().source(gameRevenueTable).metricProjection(gameRevenueTable.getMetricProjection("revenue")).whereFilter(where).build();
    String expected = "SELECT MAX(`example_GameRevenue_XXX`.`INNER_AGG_XXX`) AS `revenue` " + "FROM (SELECT MAX(`example_GameRevenue`.`revenue`) AS `INNER_AGG_XXX`," + "`example_GameRevenue`.`country_id` AS `country_id` " + "FROM `gameRevenue` AS `example_GameRevenue` " + "WHERE `example_GameRevenue`.`category` IN (:XXX) " + "GROUP BY `example_GameRevenue`.`country_id` ) " + "AS `example_GameRevenue_XXX` " + "LEFT OUTER JOIN `countries` AS `example_GameRevenue_XXX_country_XXX` " + "ON `example_GameRevenue_XXX`.`country_id` = `example_GameRevenue_XXX_country_XXX`.`id` " + "WHERE `example_GameRevenue_XXX_country_XXX`.`iso_code` IN (:XXX)\n";
    compareQueryLists(expected, engine.explain(query));
    testQueryExecution(query);
}
Also used : Path(com.yahoo.elide.core.Path) Query(com.yahoo.elide.datastores.aggregation.query.Query) SQLTable(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) OrFilterExpression(com.yahoo.elide.core.filter.expression.OrFilterExpression) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) SQLUnitTest(com.yahoo.elide.datastores.aggregation.framework.SQLUnitTest) Test(org.junit.jupiter.api.Test)

Example 7 with AndFilterExpression

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

the class AggregateBeforeJoinOptimizerTest method testWhereOnTimeDimensionNotInProjectionNotRequiringJoin.

@Test
public void testWhereOnTimeDimensionNotInProjectionNotRequiringJoin() {
    SQLTable gameRevenueTable = (SQLTable) metaDataStore.getTable("gameRevenue", NO_VERSION);
    FilterExpression where = new AndFilterExpression(new FilterPredicate(new Path(GameRevenue.class, dictionary, "countryIsoCode"), Operator.IN, Arrays.asList("foo")), new FilterPredicate(new Path(GameRevenue.class, dictionary, "saleDate"), Operator.IN, Arrays.asList(new Day(new Date()))));
    Query query = Query.builder().source(gameRevenueTable).metricProjection(gameRevenueTable.getMetricProjection("revenue")).whereFilter(where).build();
    String expected = "SELECT MAX(`example_GameRevenue_XXX`.`INNER_AGG_XXX`) AS `revenue` " + "FROM (SELECT MAX(`example_GameRevenue`.`revenue`) AS `INNER_AGG_XXX`," + "`example_GameRevenue`.`country_id` AS `country_id` " + "FROM `gameRevenue` AS `example_GameRevenue` " + "WHERE PARSEDATETIME(FORMATDATETIME(`example_GameRevenue`.`saleDate`, 'yyyy-MM-dd'), 'yyyy-MM-dd') IN (:XXX) " + "GROUP BY `example_GameRevenue`.`country_id` ) " + "AS `example_GameRevenue_XXX` " + "LEFT OUTER JOIN `countries` AS `example_GameRevenue_XXX_country_XXX` " + "ON `example_GameRevenue_XXX`.`country_id` = `example_GameRevenue_XXX_country_XXX`.`id` " + "WHERE `example_GameRevenue_XXX_country_XXX`.`iso_code` IN (:XXX)\n";
    compareQueryLists(expected, engine.explain(query));
    testQueryExecution(query);
}
Also used : Path(com.yahoo.elide.core.Path) Query(com.yahoo.elide.datastores.aggregation.query.Query) SQLTable(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) OrFilterExpression(com.yahoo.elide.core.filter.expression.OrFilterExpression) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) Day(com.yahoo.elide.datastores.aggregation.timegrains.Day) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) Date(java.util.Date) SQLUnitTest(com.yahoo.elide.datastores.aggregation.framework.SQLUnitTest) Test(org.junit.jupiter.api.Test)

Example 8 with AndFilterExpression

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

the class FilterTranslatorTest method testHQLQueryVisitor.

@Test
public void testHQLQueryVisitor() throws Exception {
    List<Path.PathElement> p0Path = Arrays.asList(new Path.PathElement(Book.class, Author.class, "authors"));
    FilterPredicate p0 = new NotEmptyPredicate(new Path(p0Path));
    List<Path.PathElement> p1Path = Arrays.asList(new Path.PathElement(Book.class, Author.class, "authors"), new Path.PathElement(Author.class, String.class, "name"));
    FilterPredicate p1 = new InPredicate(new Path(p1Path), "foo", "bar");
    List<Path.PathElement> p2Path = Arrays.asList(new Path.PathElement(Book.class, String.class, "name"));
    FilterPredicate p2 = new InPredicate(new Path(p2Path), "blah");
    List<Path.PathElement> p3Path = Arrays.asList(new Path.PathElement(Book.class, String.class, "genre"));
    FilterPredicate p3 = new InPredicate(new Path(p3Path), "scifi");
    OrFilterExpression or = new OrFilterExpression(p2, p3);
    AndFilterExpression and1 = new AndFilterExpression(p0, p1);
    AndFilterExpression and2 = new AndFilterExpression(or, and1);
    NotFilterExpression not = new NotFilterExpression(and2);
    FilterTranslator filterOp = new FilterTranslator(dictionary);
    String query = filterOp.apply(not, false);
    query = query.trim().replaceAll(" +", " ");
    String p1Params = p1.getParameters().stream().map(FilterPredicate.FilterParameter::getPlaceholder).collect(Collectors.joining(", "));
    String p2Params = p2.getParameters().stream().map(FilterPredicate.FilterParameter::getPlaceholder).collect(Collectors.joining(", "));
    String p3Params = p3.getParameters().stream().map(FilterPredicate.FilterParameter::getPlaceholder).collect(Collectors.joining(", "));
    String expected = "NOT (((name IN (" + p2Params + ") OR genre IN (" + p3Params + ")) " + "AND (authors IS NOT EMPTY AND authors.name IN (" + p1Params + "))))";
    assertEquals(expected, query);
}
Also used : Path(com.yahoo.elide.core.Path) OrFilterExpression(com.yahoo.elide.core.filter.expression.OrFilterExpression) InPredicate(com.yahoo.elide.core.filter.predicates.InPredicate) NotFilterExpression(com.yahoo.elide.core.filter.expression.NotFilterExpression) Book(example.Book) Author(example.Author) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) NotEmptyPredicate(com.yahoo.elide.core.filter.predicates.NotEmptyPredicate) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) Test(org.junit.jupiter.api.Test)

Example 9 with AndFilterExpression

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

the class PersistentResource method loadRecords.

/**
 * Load a collection from the datastore.
 *
 * @param projection   the projection to load
 * @param requestScope the request scope
 * @param ids          a list of object identifiers to optionally load.  Can be empty.
 * @return a filtered collection of resources loaded from the datastore.
 */
public static Observable<PersistentResource> loadRecords(EntityProjection projection, List<String> ids, RequestScope requestScope) {
    Type<?> loadClass = projection.getType();
    Pagination pagination = projection.getPagination();
    Sorting sorting = projection.getSorting();
    FilterExpression filterExpression = projection.getFilterExpression();
    EntityDictionary dictionary = requestScope.getDictionary();
    DataStoreTransaction tx = requestScope.getTransaction();
    if (shouldSkipCollection(loadClass, ReadPermission.class, requestScope, projection.getRequestedFields())) {
        if (ids.isEmpty()) {
            return Observable.empty();
        }
        throw new InvalidObjectIdentifierException(ids.toString(), dictionary.getJsonAliasFor(loadClass));
    }
    Set<String> requestedFields = projection.getRequestedFields();
    if (pagination != null && !pagination.isDefaultInstance() && !CanPaginateVisitor.canPaginate(loadClass, dictionary, requestScope, requestedFields)) {
        throw new BadRequestException(String.format("Cannot paginate %s", dictionary.getJsonAliasFor(loadClass)));
    }
    Set<PersistentResource> newResources = new LinkedHashSet<>();
    if (!ids.isEmpty()) {
        String typeAlias = dictionary.getJsonAliasFor(loadClass);
        newResources = requestScope.getNewPersistentResources().stream().filter(resource -> typeAlias.equals(resource.getTypeName()) && ids.contains(resource.getUUID().orElse(""))).collect(Collectors.toSet());
        FilterExpression idExpression = buildIdFilterExpression(ids, loadClass, dictionary, requestScope);
        // Combine filters if necessary
        filterExpression = Optional.ofNullable(filterExpression).map(fe -> (FilterExpression) new AndFilterExpression(idExpression, fe)).orElse(idExpression);
    }
    Optional<FilterExpression> permissionFilter = getPermissionFilterExpression(loadClass, requestScope, requestedFields);
    if (permissionFilter.isPresent()) {
        if (filterExpression != null) {
            filterExpression = new AndFilterExpression(filterExpression, permissionFilter.get());
        } else {
            filterExpression = permissionFilter.get();
        }
    }
    EntityProjection modifiedProjection = projection.copyOf().filterExpression(filterExpression).sorting(sorting).pagination(pagination).build();
    Observable<PersistentResource> existingResources = filter(ReadPermission.class, Optional.ofNullable(modifiedProjection.getFilterExpression()), projection.getRequestedFields(), Observable.fromIterable(new PersistentResourceSet(tx.loadObjects(modifiedProjection, requestScope), requestScope)));
    // TODO: Sort again in memory now that two sets are glommed together?
    Observable<PersistentResource> allResources = Observable.fromIterable(newResources).mergeWith(existingResources);
    Set<String> foundIds = new HashSet<>();
    allResources = allResources.doOnNext((resource) -> {
        String id = (String) resource.getUUID().orElseGet(resource::getId);
        if (ids.contains(id)) {
            foundIds.add(id);
        }
    });
    allResources = allResources.doOnComplete(() -> {
        Set<String> missedIds = Sets.difference(new HashSet<>(ids), foundIds);
        if (!missedIds.isEmpty()) {
            throw new InvalidObjectIdentifierException(missedIds.toString(), dictionary.getJsonAliasFor(loadClass));
        }
    });
    return allResources;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Resource(com.yahoo.elide.jsonapi.models.Resource) Data(com.yahoo.elide.jsonapi.models.Data) StringUtils(org.apache.commons.lang3.StringUtils) UpdatePermission(com.yahoo.elide.annotation.UpdatePermission) ClassType(com.yahoo.elide.core.type.ClassType) DeletePermission(com.yahoo.elide.annotation.DeletePermission) Argument(com.yahoo.elide.core.request.Argument) InvalidSyntaxException(com.yahoo.elide.core.audit.InvalidSyntaxException) Map(java.util.Map) DataStoreIterable(com.yahoo.elide.core.datastore.DataStoreIterable) LifeCycleHookBinding(com.yahoo.elide.annotation.LifeCycleHookBinding) EntityBinding(com.yahoo.elide.core.dictionary.EntityBinding) NonNull(lombok.NonNull) Collection(java.util.Collection) Set(java.util.Set) CoerceUtil(com.yahoo.elide.core.utils.coerce.CoerceUtil) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Sets(com.google.common.collect.Sets) Serializable(java.io.Serializable) Objects(java.util.Objects) ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) List(java.util.List) Annotation(java.lang.annotation.Annotation) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) Optional(java.util.Optional) RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) Attribute(com.yahoo.elide.core.request.Attribute) InvalidAttributeException(com.yahoo.elide.core.exceptions.InvalidAttributeException) Function(java.util.function.Function) Supplier(java.util.function.Supplier) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) IterableUtils(org.apache.commons.collections4.IterableUtils) LogMessageImpl(com.yahoo.elide.core.audit.LogMessageImpl) DELETE(com.yahoo.elide.annotation.LifeCycleHookBinding.Operation.DELETE) EntityDictionary.getType(com.yahoo.elide.core.dictionary.EntityDictionary.getType) JsonIgnore(com.fasterxml.jackson.annotation.JsonIgnore) Predicates(com.google.common.base.Predicates) InternalServerErrorException(com.yahoo.elide.core.exceptions.InternalServerErrorException) CanPaginateVisitor(com.yahoo.elide.core.security.visitors.CanPaginateVisitor) Observable(io.reactivex.Observable) LogMessage(com.yahoo.elide.core.audit.LogMessage) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) LinkedHashSet(java.util.LinkedHashSet) UPDATE(com.yahoo.elide.annotation.LifeCycleHookBinding.Operation.UPDATE) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) VerifyFieldAccessFilterExpressionVisitor(com.yahoo.elide.core.filter.visitors.VerifyFieldAccessFilterExpressionVisitor) ChangeSpec(com.yahoo.elide.core.security.ChangeSpec) COLLECTION_TYPE(com.yahoo.elide.core.type.ClassType.COLLECTION_TYPE) Sorting(com.yahoo.elide.core.request.Sorting) InvalidEntityBodyException(com.yahoo.elide.core.exceptions.InvalidEntityBodyException) InvalidObjectIdentifierException(com.yahoo.elide.core.exceptions.InvalidObjectIdentifierException) InPredicate(com.yahoo.elide.core.filter.predicates.InPredicate) EntityProjection(com.yahoo.elide.core.request.EntityProjection) Relationship(com.yahoo.elide.jsonapi.models.Relationship) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException) ReadPermission(com.yahoo.elide.annotation.ReadPermission) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) Pagination(com.yahoo.elide.core.request.Pagination) ResourceIdentifier(com.yahoo.elide.jsonapi.models.ResourceIdentifier) TreeMap(java.util.TreeMap) CreatePermission(com.yahoo.elide.annotation.CreatePermission) CREATE(com.yahoo.elide.annotation.LifeCycleHookBinding.Operation.CREATE) Type(com.yahoo.elide.core.type.Type) Preconditions(com.google.common.base.Preconditions) Comparator(java.util.Comparator) Collections(java.util.Collections) EMPTY_BINDING(com.yahoo.elide.core.dictionary.EntityBinding.EMPTY_BINDING) Audit(com.yahoo.elide.annotation.Audit) NonTransferable(com.yahoo.elide.annotation.NonTransferable) EntityProjection(com.yahoo.elide.core.request.EntityProjection) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Sorting(com.yahoo.elide.core.request.Sorting) Pagination(com.yahoo.elide.core.request.Pagination) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) InvalidObjectIdentifierException(com.yahoo.elide.core.exceptions.InvalidObjectIdentifierException) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 10 with AndFilterExpression

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

the class SplitFilterExpressionVisitorTest method testVisitAndExpression.

@Test
public void testVisitAndExpression() {
    // pure-W AND pure-W
    AndFilterExpression filterExpression = new AndFilterExpression(WHERE_PREDICATE, WHERE_PREDICATE);
    assertEquals("(playerStats.overallRating IN [foo] AND playerStats.overallRating IN [foo])", splitFilterExpressionVisitor.visitAndExpression(filterExpression).getWhereExpression().toString());
    assertNull(splitFilterExpressionVisitor.visitAndExpression(filterExpression).getHavingExpression());
    // pure-H AND pure-W
    filterExpression = new AndFilterExpression(HAVING_PREDICATE, WHERE_PREDICATE);
    assertEquals("playerStats.overallRating IN [foo]", splitFilterExpressionVisitor.visitAndExpression(filterExpression).getWhereExpression().toString());
    assertEquals("playerStats.highScore GT [99]", splitFilterExpressionVisitor.visitAndExpression(filterExpression).getHavingExpression().toString());
    // pure-W AND pure-H
    filterExpression = new AndFilterExpression(WHERE_PREDICATE, HAVING_PREDICATE);
    assertEquals("playerStats.overallRating IN [foo]", splitFilterExpressionVisitor.visitAndExpression(filterExpression).getWhereExpression().toString());
    assertEquals("playerStats.highScore GT [99]", splitFilterExpressionVisitor.visitAndExpression(filterExpression).getHavingExpression().toString());
    // non-pure case - H1 AND W1 AND H2
    AndFilterExpression and1 = new AndFilterExpression(HAVING_PREDICATE, WHERE_PREDICATE);
    AndFilterExpression and2 = new AndFilterExpression(and1, HAVING_PREDICATE);
    assertEquals("playerStats.overallRating IN [foo]", splitFilterExpressionVisitor.visitAndExpression(and2).getWhereExpression().toString());
    assertEquals("(playerStats.highScore GT [99] AND playerStats.highScore GT [99])", splitFilterExpressionVisitor.visitAndExpression(and2).getHavingExpression().toString());
    // non-pure case - (H1 OR H2) AND W1
    OrFilterExpression or = new OrFilterExpression(HAVING_PREDICATE, HAVING_PREDICATE);
    AndFilterExpression and = new AndFilterExpression(or, WHERE_PREDICATE);
    assertEquals("playerStats.overallRating IN [foo]", splitFilterExpressionVisitor.visitAndExpression(and).getWhereExpression().toString());
    assertEquals("(playerStats.highScore GT [99] OR playerStats.highScore GT [99])", splitFilterExpressionVisitor.visitAndExpression(and).getHavingExpression().toString());
}
Also used : OrFilterExpression(com.yahoo.elide.core.filter.expression.OrFilterExpression) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) Test(org.junit.jupiter.api.Test)

Aggregations

AndFilterExpression (com.yahoo.elide.core.filter.expression.AndFilterExpression)34 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)22 OrFilterExpression (com.yahoo.elide.core.filter.expression.OrFilterExpression)21 FilterPredicate (com.yahoo.elide.core.filter.predicates.FilterPredicate)20 Test (org.junit.jupiter.api.Test)17 Path (com.yahoo.elide.core.Path)15 NotFilterExpression (com.yahoo.elide.core.filter.expression.NotFilterExpression)10 InPredicate (com.yahoo.elide.core.filter.predicates.InPredicate)10 SQLUnitTest (com.yahoo.elide.datastores.aggregation.framework.SQLUnitTest)7 Query (com.yahoo.elide.datastores.aggregation.query.Query)7 SQLTable (com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable)7 Book (example.Book)6 Author (example.Author)5 PathElement (com.yahoo.elide.core.Path.PathElement)4 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)4 Date (java.util.Date)4 DataStoreIterable (com.yahoo.elide.core.datastore.DataStoreIterable)3 RelationshipType (com.yahoo.elide.core.dictionary.RelationshipType)3 Type (com.yahoo.elide.core.type.Type)3 Day (com.yahoo.elide.datastores.aggregation.timegrains.Day)3