Search in sources :

Example 1 with Column

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();
}
Also used : Query(com.yahoo.elide.datastores.aggregation.query.Query) Argument(com.yahoo.elide.core.request.Argument) Column(com.yahoo.elide.datastores.aggregation.metadata.models.Column) ToString(lombok.ToString) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with Column

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();
}
Also used : PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) SQLColumnProjection(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLColumnProjection) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) Arrays(java.util.Arrays) Connection(java.sql.Connection) Dimension(com.yahoo.elide.datastores.aggregation.metadata.models.Dimension) NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery) Argument(com.yahoo.elide.core.request.Argument) EnumType(javax.persistence.EnumType) TimedFunction(com.yahoo.elide.core.utils.TimedFunction) Time(com.yahoo.elide.datastores.aggregation.timegrains.Time) NamespacePackage(com.yahoo.elide.datastores.aggregation.dynamic.NamespacePackage) Namespace(com.yahoo.elide.datastores.aggregation.metadata.models.Namespace) ResultSet(java.sql.ResultSet) Map(java.util.Map) Enumerated(javax.persistence.Enumerated) MetricProjection(com.yahoo.elide.datastores.aggregation.query.MetricProjection) DefaultQueryPlanMerger(com.yahoo.elide.datastores.aggregation.query.DefaultQueryPlanMerger) QueryPlanMerger(com.yahoo.elide.datastores.aggregation.query.QueryPlanMerger) Collection(java.util.Collection) ValueType(com.yahoo.elide.datastores.aggregation.metadata.enums.ValueType) Set(java.util.Set) QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) FromTable(com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.FromTable) ColumnContext.applyQuotes(com.yahoo.elide.datastores.aggregation.metadata.ColumnContext.applyQuotes) QueryValidator(com.yahoo.elide.datastores.aggregation.QueryValidator) CoerceUtil(com.yahoo.elide.core.utils.coerce.CoerceUtil) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Query(com.yahoo.elide.datastores.aggregation.query.Query) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) TimeDimension(com.yahoo.elide.datastores.aggregation.metadata.models.TimeDimension) Annotation(java.lang.annotation.Annotation) Table(com.yahoo.elide.datastores.aggregation.metadata.models.Table) Optimizer(com.yahoo.elide.datastores.aggregation.query.Optimizer) TimeDimensionProjection(com.yahoo.elide.datastores.aggregation.query.TimeDimensionProjection) MetaDataStore(com.yahoo.elide.datastores.aggregation.metadata.MetaDataStore) SQLDimensionProjection(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLDimensionProjection) VersionQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.VersionQuery) Getter(lombok.Getter) ColumnArgumentValidator(com.yahoo.elide.datastores.aggregation.validator.ColumnArgumentValidator) TableArgumentValidator(com.yahoo.elide.datastores.aggregation.validator.TableArgumentValidator) Function(java.util.function.Function) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SQLException(java.sql.SQLException) SQLDialect(com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect) QueryTranslator(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.QueryTranslator) Column(com.yahoo.elide.datastores.aggregation.metadata.models.Column) DataSource(javax.sql.DataSource) SQLTimeDimensionProjection(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLTimeDimensionProjection) QueryEngine(com.yahoo.elide.datastores.aggregation.QueryEngine) DimensionProjection(com.yahoo.elide.datastores.aggregation.query.DimensionProjection) FromSubquery(com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.FromSubquery) DefaultQueryValidator(com.yahoo.elide.datastores.aggregation.DefaultQueryValidator) QueryPlan(com.yahoo.elide.datastores.aggregation.query.QueryPlan) QueryPlanTranslator(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.QueryPlanTranslator) FormulaValidator(com.yahoo.elide.datastores.aggregation.metadata.FormulaValidator) Pagination(com.yahoo.elide.core.request.Pagination) SQLTable(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable) Type(com.yahoo.elide.core.type.Type) Preconditions(com.google.common.base.Preconditions) Metric(com.yahoo.elide.datastores.aggregation.metadata.models.Metric) SQLColumnProjection(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLColumnProjection) NativeQuery(com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery)

Example 3 with Column

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() + "'");
    });
}
Also used : Argument(com.yahoo.elide.core.request.Argument) Column(com.yahoo.elide.datastores.aggregation.metadata.models.Column) SQLTable(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable)

Example 4 with Column

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()));
                }
            }
        });
    });
}
Also used : Path(com.yahoo.elide.core.Path) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) FilterPredicate(com.yahoo.elide.core.filter.predicates.FilterPredicate) Path(com.yahoo.elide.core.Path) Queryable.extractFilterProjections(com.yahoo.elide.datastores.aggregation.query.Queryable.extractFilterProjections) Argument(com.yahoo.elide.core.request.Argument) HashSet(java.util.HashSet) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) Map(java.util.Map) Column(com.yahoo.elide.datastores.aggregation.metadata.models.Column) ColumnProjection(com.yahoo.elide.datastores.aggregation.query.ColumnProjection) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) LinkedHashSet(java.util.LinkedHashSet) Sorting(com.yahoo.elide.core.request.Sorting) Predicate(java.util.function.Predicate) ValueType(com.yahoo.elide.datastores.aggregation.metadata.enums.ValueType) ArgumentDefinition(com.yahoo.elide.datastores.aggregation.metadata.models.ArgumentDefinition) Set(java.util.Set) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Query(com.yahoo.elide.datastores.aggregation.query.Query) List(java.util.List) Stream(java.util.stream.Stream) SQLTable(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable) Type(com.yahoo.elide.core.type.Type) Operator(com.yahoo.elide.core.filter.Operator) Optional(java.util.Optional) ColumnProjection(com.yahoo.elide.datastores.aggregation.query.ColumnProjection) PredicateExtractionVisitor(com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression)

Example 5 with Column

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()));
        }
    });
}
Also used : Argument(com.yahoo.elide.core.request.Argument) Column(com.yahoo.elide.datastores.aggregation.metadata.models.Column) SQLTable(com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable) ColumnProjection(com.yahoo.elide.datastores.aggregation.query.ColumnProjection)

Aggregations

Column (com.yahoo.elide.datastores.aggregation.metadata.models.Column)9 Argument (com.yahoo.elide.core.request.Argument)5 SQLTable (com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable)5 ValueType (com.yahoo.elide.datastores.aggregation.metadata.enums.ValueType)4 ColumnProjection (com.yahoo.elide.datastores.aggregation.query.ColumnProjection)4 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)3 PredicateExtractionVisitor (com.yahoo.elide.core.filter.expression.PredicateExtractionVisitor)3 FilterPredicate (com.yahoo.elide.core.filter.predicates.FilterPredicate)3 Type (com.yahoo.elide.core.type.Type)3 Table (com.yahoo.elide.datastores.aggregation.metadata.models.Table)3 Query (com.yahoo.elide.datastores.aggregation.query.Query)3 List (java.util.List)3 InvalidOperationException (com.yahoo.elide.core.exceptions.InvalidOperationException)2 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)2 ArgumentDefinition (com.yahoo.elide.datastores.aggregation.metadata.models.ArgumentDefinition)2 TimeDimension (com.yahoo.elide.datastores.aggregation.metadata.models.TimeDimension)2 HashSet (java.util.HashSet)2 Map (java.util.Map)2 Set (java.util.Set)2 Collectors (java.util.stream.Collectors)2