use of com.yahoo.elide.datastores.aggregation.query.Query 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.datastores.aggregation.query.Query in project elide by yahoo.
the class AggregationDataStoreTransaction method buildQuery.
@VisibleForTesting
Query buildQuery(EntityProjection entityProjection, RequestScope scope) {
Table table = metaDataStore.getTable(scope.getDictionary().getJsonAliasFor(entityProjection.getType()), scope.getApiVersion());
String bypassCacheStr = scope.getRequestHeaderByName("bypasscache");
Boolean bypassCache = "true".equals(bypassCacheStr);
EntityProjectionTranslator translator = new EntityProjectionTranslator(queryEngine, table, entityProjection, scope, bypassCache);
Query query = translator.getQuery();
Query modifiedQuery = addTableFilterArguments(table, query, scope.getDictionary());
modifiedQuery = addColumnFilterArguments(table, modifiedQuery, scope.getDictionary());
return modifiedQuery;
}
use of com.yahoo.elide.datastores.aggregation.query.Query 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);
}
}
use of com.yahoo.elide.datastores.aggregation.query.Query 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();
}
use of com.yahoo.elide.datastores.aggregation.query.Query in project elide by yahoo.
the class SQLQueryEngine method explain.
/**
* Returns the actual query string(s) that would be executed for the input {@link Query}.
*
* @param query The query customized for a particular persistent storage or storage client.
* @param dialect SQL dialect to use for this storage.
* @return List of SQL string(s) corresponding to the given query.
*/
public List<String> explain(Query query, SQLDialect dialect) {
List<String> queries = new ArrayList<>();
Query expandedQuery = expandMetricQueryPlans(query);
NativeQuery sql = toSQL(expandedQuery, dialect);
Pagination pagination = query.getPagination();
if (returnPageTotals(pagination)) {
NativeQuery paginationSql = toPageTotalSQL(expandedQuery, sql, dialect);
if (paginationSql != null) {
queries.add(paginationSql.toString());
}
}
queries.add(sql.toString());
return queries;
}
Aggregations