use of com.yahoo.elide.datastores.aggregation.metadata.models.Column 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.metadata.models.Column in project elide by yahoo.
the class SQLQueryEngine method toPageTotalSQL.
/**
* Takes a SQLQuery and creates a new clone that instead returns the total number of records of the original
* query.
*
* @param query The client query
* @param sql The generated SQL query
* @param sqlDialect the SQL dialect
* @return A new query that returns the total number of records.
*/
private NativeQuery toPageTotalSQL(Query query, NativeQuery sql, SQLDialect sqlDialect) {
// TODO: refactor this method
String groupByDimensions = query.getAllDimensionProjections().stream().map(SQLColumnProjection.class::cast).filter(SQLColumnProjection::isProjected).map((column) -> column.toSQL(query, metaDataStore)).collect(Collectors.joining(", "));
if (groupByDimensions.isEmpty()) {
// Metric projection without group by dimension will return onely 1 record.
return null;
}
NativeQuery innerQuery = NativeQuery.builder().projectionClause(groupByDimensions).fromClause(sql.getFromClause()).joinClause(sql.getJoinClause()).whereClause(sql.getWhereClause()).groupByClause(String.format("GROUP BY %s", groupByDimensions)).havingClause(sql.getHavingClause()).build();
return NativeQuery.builder().projectionClause("COUNT(*)").fromClause(QueryTranslator.getFromClause("(" + innerQuery + ")", applyQuotes("pagination_subquery", sqlDialect), sqlDialect)).build();
}
use of com.yahoo.elide.datastores.aggregation.metadata.models.Column in project elide by yahoo.
the class DefaultQueryValidator method validateColumnArguments.
protected void validateColumnArguments(Query query, ColumnProjection projection) {
SQLTable table = (SQLTable) query.getSource();
Column column = table.getColumn(Column.class, projection.getName());
column.getArgumentDefinitions().forEach(columnArgument -> {
Argument clientArgument = projection.getArguments().get(columnArgument.getName());
validateArgument(Optional.ofNullable(clientArgument), columnArgument, "column '" + projection.getAlias() + "'");
});
}
use of com.yahoo.elide.datastores.aggregation.metadata.models.Column 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.datastores.aggregation.metadata.models.Column in project elide by yahoo.
the class ColumnArgumentValidator method verifyLogicalReference.
private void verifyLogicalReference(LogicalReference reference) {
SQLTable sqlTable = (SQLTable) reference.getSource();
ColumnProjection columnProj = reference.getColumn();
// This will have dependent column's defined arguments merged with pinned arguments used to invoke this column.
Map<String, Argument> mergedArguments = columnProj.getArguments();
Column refColumn = sqlTable.getColumn(Column.class, columnProj.getName());
verifyPinnedArguments(mergedArguments, refColumn, String.format(errorMsgPrefix + "Type mismatch of Fixed value provided for Dependent Column: '%s' in table: '%s'. ", refColumn.getName(), sqlTable.getName()));
refColumn.getArgumentDefinitions().forEach(argDef -> {
String argName = argDef.getName();
if (column.hasArgumentDefinition(argName)) {
if (argDef.getType() != column.getArgumentDefinition(argName).getType()) {
throw new IllegalStateException(String.format(errorMsgPrefix + "Argument type mismatch. Dependent Column: '%s' in table: '%s' has same" + " Argument: '%s' with type '%s'.", refColumn.getName(), sqlTable.getName(), argName, argDef.getType()));
}
} else if (StringUtils.isBlank(argDef.getDefaultValue().toString()) && StringUtils.isBlank(mergedArguments.get(argName).getValue().toString())) {
throw new IllegalStateException(String.format(errorMsgPrefix + "Argument '%s' with type '%s' is not defined but is required for" + " Dependent Column: '%s' in table: '%s'.", argName, argDef.getType(), refColumn.getName(), sqlTable.getName()));
}
});
}
Aggregations