Search in sources :

Example 1 with QueryResult

use of com.yahoo.elide.datastores.aggregation.query.QueryResult in project elide by yahoo.

the class AggregationDataStoreTransaction method loadObjects.

@Override
public <T> DataStoreIterable<T> loadObjects(EntityProjection entityProjection, RequestScope scope) {
    QueryResult result = null;
    QueryResponse response = null;
    String cacheKey = null;
    try {
        // Convert multivalued map to map.
        Map<String, String> headers = scope.getRequestHeaders().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, (entry) -> entry.getValue().stream().collect(Collectors.joining(" "))));
        queryLogger.acceptQuery(scope.getRequestId(), scope.getUser(), headers, scope.getApiVersion(), scope.getQueryParams(), scope.getPath());
        Query query = buildQuery(entityProjection, scope);
        Table table = (Table) query.getSource();
        if (cache != null && !query.isBypassingCache()) {
            String tableVersion = queryEngine.getTableVersion(table, queryEngineTransaction);
            tableVersion = tableVersion == null ? "" : tableVersion;
            cacheKey = tableVersion + ';' + QueryKeyExtractor.extractKey(query);
            result = cache.get(cacheKey);
        }
        boolean isCached = result != null;
        List<String> queryText = queryEngine.explain(query);
        queryLogger.processQuery(scope.getRequestId(), query, queryText, isCached);
        if (result == null) {
            result = queryEngine.executeQuery(query, queryEngineTransaction);
            if (cacheKey != null) {
                // The query result needs to be streamed into an in memory list before caching.
                // TODO - add a cap to how many records can be streamed back.  If this is exceeded, abort caching
                // and return the results.
                QueryResult cacheableResult = QueryResult.builder().data(Lists.newArrayList(result.getData().iterator())).pageTotals(result.getPageTotals()).build();
                cache.put(cacheKey, cacheableResult);
                result = cacheableResult;
            }
        }
        if (entityProjection.getPagination() != null && entityProjection.getPagination().returnPageTotals()) {
            entityProjection.getPagination().setPageTotals(result.getPageTotals());
        }
        response = new QueryResponse(HttpStatus.SC_OK, result.getData(), null);
        return new DataStoreIterableBuilder(result.getData()).build();
    } catch (HttpStatusException e) {
        response = new QueryResponse(e.getStatus(), null, e.getMessage());
        throw e;
    } catch (Exception e) {
        response = new QueryResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, null, e.getMessage());
        throw e;
    } finally {
        queryLogger.completeQuery(scope.getRequestId(), response);
    }
}
Also used : HttpStatus(com.yahoo.elide.core.exceptions.HttpStatus) DataStoreIterableBuilder(com.yahoo.elide.core.datastore.DataStoreIterableBuilder) QueryResponse(com.yahoo.elide.datastores.aggregation.core.QueryResponse) HashMap(java.util.HashMap) Argument(com.yahoo.elide.core.request.Argument) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) Map(java.util.Map) MatchesTemplateVisitor(com.yahoo.elide.datastores.aggregation.filter.visitor.MatchesTemplateVisitor) Column(com.yahoo.elide.datastores.aggregation.metadata.models.Column) ToString(lombok.ToString) DataStoreIterable(com.yahoo.elide.core.datastore.DataStoreIterable) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) RequestScope(com.yahoo.elide.core.RequestScope) RequiresFilter(com.yahoo.elide.datastores.aggregation.metadata.models.RequiresFilter) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) Cache(com.yahoo.elide.datastores.aggregation.cache.Cache) Lists(org.apache.commons.compress.utils.Lists) EntityProjection(com.yahoo.elide.core.request.EntityProjection) QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Query(com.yahoo.elide.datastores.aggregation.query.Query) List(java.util.List) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) QueryKeyExtractor(com.yahoo.elide.datastores.aggregation.cache.QueryKeyExtractor) Type(com.yahoo.elide.core.type.Type) Table(com.yahoo.elide.datastores.aggregation.metadata.models.Table) VisibleForTesting(com.google.common.annotations.VisibleForTesting) MetaDataStore(com.yahoo.elide.datastores.aggregation.metadata.MetaDataStore) QueryLogger(com.yahoo.elide.datastores.aggregation.core.QueryLogger) Table(com.yahoo.elide.datastores.aggregation.metadata.models.Table) Query(com.yahoo.elide.datastores.aggregation.query.Query) DataStoreIterableBuilder(com.yahoo.elide.core.datastore.DataStoreIterableBuilder) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) ToString(lombok.ToString) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) IOException(java.io.IOException) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) QueryResponse(com.yahoo.elide.datastores.aggregation.core.QueryResponse) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with QueryResult

use of com.yahoo.elide.datastores.aggregation.query.QueryResult in project elide by yahoo.

the class SQLQueryEngine method executeQuery.

@Override
public QueryResult executeQuery(Query query, Transaction transaction) {
    SqlTransaction sqlTransaction = (SqlTransaction) transaction;
    ConnectionDetails details = query.getConnectionDetails();
    DataSource dataSource = details.getDataSource();
    SQLDialect dialect = details.getDialect();
    Query expandedQuery = expandMetricQueryPlans(query);
    // Translate the query into SQL.
    NativeQuery sql = toSQL(expandedQuery, dialect);
    String queryString = sql.toString();
    QueryResult.QueryResultBuilder resultBuilder = QueryResult.builder();
    NamedParamPreparedStatement stmt;
    Pagination pagination = query.getPagination();
    if (returnPageTotals(pagination)) {
        resultBuilder.pageTotals(getPageTotal(expandedQuery, sql, query, sqlTransaction));
    }
    log.debug("SQL Query: " + queryString);
    stmt = sqlTransaction.initializeStatement(queryString, dataSource);
    // Supply the query parameters to the query
    supplyFilterQueryParameters(query, stmt, dialect);
    // Run the primary query and log the time spent.
    ResultSet resultSet = runQuery(stmt, queryString, Function.identity());
    resultBuilder.data(new EntityHydrator(resultSet, query, metadataDictionary));
    return resultBuilder.build();
}
Also used : NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery) Query(com.yahoo.elide.datastores.aggregation.query.Query) VersionQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.VersionQuery) DataSource(javax.sql.DataSource) Pagination(com.yahoo.elide.core.request.Pagination) QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery) SQLDialect(com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect) ResultSet(java.sql.ResultSet)

Example 3 with QueryResult

use of com.yahoo.elide.datastores.aggregation.query.QueryResult in project elide by yahoo.

the class QueryEngineTest method testPaginationWithFilter.

/**
 * Nested Queries with filter - Pagination
 * @throws Exception
 */
@Test
public void testPaginationWithFilter() throws Exception {
    Query query = Query.builder().source(playerStatsTable).metricProjection(playerStatsTable.getMetricProjection("dailyAverageScorePerPeriod")).dimensionProjection(playerStatsTable.getDimensionProjection("overallRating")).whereFilter(filterParser.parseFilterExpression("overallRating==Great", playerStatsType, false)).timeDimensionProjection(playerStatsTable.getTimeDimensionProjection("recordedDate")).pagination(new ImmutablePagination(0, 1, false, true)).build();
    QueryResult result = engine.executeQuery(query, transaction);
    List<Object> data = toList(result.getData());
    // Jon Doe,1234,72,Good,840,2019-07-12 00:00:00
    PlayerStats stats1 = new PlayerStats();
    stats1.setId("0");
    stats1.setDailyAverageScorePerPeriod(2412.0f);
    stats1.setOverallRating("Great");
    stats1.setRecordedDate(new Day(Date.valueOf("2019-07-11")));
    assertEquals(ImmutableList.of(stats1), data, "Returned record does not match");
    assertEquals(1, result.getPageTotals(), "Page totals does not match");
}
Also used : QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) Query(com.yahoo.elide.datastores.aggregation.query.Query) ImmutablePagination(com.yahoo.elide.datastores.aggregation.query.ImmutablePagination) PlayerStats(example.PlayerStats) Day(com.yahoo.elide.datastores.aggregation.timegrains.Day) SQLUnitTest(com.yahoo.elide.datastores.aggregation.framework.SQLUnitTest) Test(org.junit.jupiter.api.Test)

Example 4 with QueryResult

use of com.yahoo.elide.datastores.aggregation.query.QueryResult in project elide by yahoo.

the class AggregationDataStoreTransactionTest method loadObjectsPopulatesCache.

@Test
public void loadObjectsPopulatesCache() {
    Mockito.reset(queryLogger);
    QueryResult queryResult = QueryResult.builder().data(DATA).build();
    NativeQuery myQuery = NativeQuery.builder().fromClause(playerStatsTable.getName()).projectionClause(" ").build();
    when(queryEngine.getTableVersion(playerStatsTable, qeTransaction)).thenReturn("foo");
    when(queryEngine.executeQuery(query, qeTransaction)).thenReturn(queryResult);
    when(queryEngine.explain(query)).thenReturn(Arrays.asList(myQuery.toString()));
    AggregationDataStoreTransaction transaction = new MyAggregationDataStoreTransaction(queryEngine, cache, queryLogger);
    EntityProjection entityProjection = EntityProjection.builder().type(PlayerStats.class).build();
    assertEquals(DATA, Lists.newArrayList(transaction.loadObjects(entityProjection, scope)));
    String cacheKey = "foo;" + queryKey;
    Mockito.verify(cache).get(cacheKey);
    Mockito.verify(cache).put(cacheKey, queryResult);
    Mockito.verifyNoMoreInteractions(cache);
    Mockito.verify(queryLogger, times(1)).acceptQuery(Mockito.eq(scope.getRequestId()), any(), any(), any(), any(), any());
    Mockito.verify(queryLogger, times(1)).processQuery(Mockito.eq(scope.getRequestId()), any(), any(), Mockito.eq(false));
    Mockito.verify(queryLogger, times(1)).completeQuery(Mockito.eq(scope.getRequestId()), any());
}
Also used : EntityProjection(com.yahoo.elide.core.request.EntityProjection) QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery) PlayerStats(example.PlayerStats) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) SQLUnitTest(com.yahoo.elide.datastores.aggregation.framework.SQLUnitTest) Test(org.junit.jupiter.api.Test)

Example 5 with QueryResult

use of com.yahoo.elide.datastores.aggregation.query.QueryResult in project elide by yahoo.

the class AggregationDataStoreTransactionTest method loadObjectsPassesPagination.

@Test
public void loadObjectsPassesPagination() {
    Mockito.reset(queryLogger);
    QueryResult queryResult = QueryResult.builder().data(DATA).pageTotals(314L).build();
    NativeQuery myQuery = NativeQuery.builder().fromClause(playerStatsTable.getName()).projectionClause(" ").build();
    when(cache.get(anyString())).thenReturn(queryResult);
    when(queryEngine.getTableVersion(playerStatsTable, qeTransaction)).thenReturn("foo");
    when(queryEngine.explain(query)).thenReturn(Arrays.asList(myQuery.toString()));
    AggregationDataStoreTransaction transaction = new MyAggregationDataStoreTransaction(queryEngine, cache, queryLogger);
    Pagination pagination = new PaginationImpl(String.class, null, null, DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT, true, false);
    EntityProjection entityProjection = EntityProjection.builder().type(PlayerStats.class).pagination(pagination).build();
    assertEquals(DATA, Lists.newArrayList(transaction.loadObjects(entityProjection, scope)));
    assertEquals(314L, entityProjection.getPagination().getPageTotals());
    String cacheKey = "foo;" + queryKey;
    Mockito.verify(queryEngine, never()).executeQuery(any(), any());
    Mockito.verify(cache).get(cacheKey);
    Mockito.verifyNoMoreInteractions(cache);
    Mockito.verify(queryLogger, times(1)).acceptQuery(Mockito.eq(scope.getRequestId()), any(), any(), any(), any(), any());
    Mockito.verify(queryLogger, times(1)).processQuery(Mockito.eq(scope.getRequestId()), any(), any(), Mockito.eq(true));
    Mockito.verify(queryLogger, times(1)).completeQuery(Mockito.eq(scope.getRequestId()), any());
}
Also used : Pagination(com.yahoo.elide.core.request.Pagination) EntityProjection(com.yahoo.elide.core.request.EntityProjection) QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) PaginationImpl(com.yahoo.elide.core.pagination.PaginationImpl) NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) SQLUnitTest(com.yahoo.elide.datastores.aggregation.framework.SQLUnitTest) Test(org.junit.jupiter.api.Test)

Aggregations

QueryResult (com.yahoo.elide.datastores.aggregation.query.QueryResult)12 Test (org.junit.jupiter.api.Test)10 SQLUnitTest (com.yahoo.elide.datastores.aggregation.framework.SQLUnitTest)7 EntityProjection (com.yahoo.elide.core.request.EntityProjection)6 NativeQuery (com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery)6 PlayerStats (example.PlayerStats)6 Query (com.yahoo.elide.datastores.aggregation.query.Query)4 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)4 Pagination (com.yahoo.elide.core.request.Pagination)2 ImmutablePagination (com.yahoo.elide.datastores.aggregation.query.ImmutablePagination)2 Day (com.yahoo.elide.datastores.aggregation.timegrains.Day)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 RequestScope (com.yahoo.elide.core.RequestScope)1 DataStoreIterable (com.yahoo.elide.core.datastore.DataStoreIterable)1 DataStoreIterableBuilder (com.yahoo.elide.core.datastore.DataStoreIterableBuilder)1 DataStoreTransaction (com.yahoo.elide.core.datastore.DataStoreTransaction)1 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)1 BadRequestException (com.yahoo.elide.core.exceptions.BadRequestException)1 HttpStatus (com.yahoo.elide.core.exceptions.HttpStatus)1 HttpStatusException (com.yahoo.elide.core.exceptions.HttpStatusException)1