diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/AggregationDataStore.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/AggregationDataStore.java index 45efc525b1..f281ff1064 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/AggregationDataStore.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/AggregationDataStore.java @@ -151,7 +151,7 @@ private void validateModelExpressionChecks(EntityDictionary dictionary, Type } /** - * Validates the Expression Check class to check whether it complies with the given predicate + * Validates the Expression Check class to check whether it complies with the given predicate. * @param dictionary - Entity dictionary * @param expressionChecksIdentifiers - Set of identifiers for whose the security check class is validated * @param validCheckPredicate - Predicate that takes security check class as argument. diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/metadata/ColumnContext.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/metadata/ColumnContext.java index 3232a960d3..f8ec5e14d7 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/metadata/ColumnContext.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/metadata/ColumnContext.java @@ -9,15 +9,15 @@ import static com.yahoo.elide.core.request.Argument.getArgumentMapFromString; import static com.yahoo.elide.core.utils.TypeHelper.appendAlias; import static com.yahoo.elide.datastores.aggregation.query.ColumnProjection.createSafeAlias; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.PERIOD; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.applyQuotes; import static java.util.Collections.emptyMap; import static org.apache.commons.lang3.StringUtils.isBlank; import com.yahoo.elide.core.request.Argument; import com.yahoo.elide.datastores.aggregation.query.ColumnProjection; import com.yahoo.elide.datastores.aggregation.query.Queryable; +import com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect; import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLJoin; + import com.github.jknack.handlebars.EscapingStrategy; import com.github.jknack.handlebars.Formatter; import com.github.jknack.handlebars.Handlebars; @@ -46,6 +46,7 @@ public class ColumnContext extends HashMap { public static final String TBL_PREFIX = "$$table"; public static final String ARGS_KEY = "args"; public static final String EXPR_KEY = "expr"; + public static final String PERIOD = "."; protected final MetaDataStore metaDataStore; protected final Queryable queryable; @@ -250,4 +251,35 @@ public static Map mergedArgumentMap(Map refe Map callingObjectArgs) { return mergedArgumentMap(referencedObjectArgs, callingObjectArgs, emptyMap()); } + + /** + * Split a string on ".", append quotes around each split and join it back. + * eg: game.order_details to `game`.`order_details` . + * + * @param str column name / alias + * @param beginQuote prefix char + * @param endQuote suffix char + * @return quoted string + */ + private static String applyQuotes(String str, char beginQuote, char endQuote) { + if (isBlank(str)) { + return str; + } + if (str.contains(PERIOD)) { + return beginQuote + str.trim().replace(PERIOD, endQuote + PERIOD + beginQuote) + endQuote; + } + return beginQuote + str.trim() + endQuote; + } + + /** + * Split a string on ".", append quotes around each split and join it back. + * eg: game.order_details to `game`.`order_details` . + * + * @param str column name / alias + * @param dialect Elide SQL dialect + * @return quoted string + */ + public static String applyQuotes(String str, SQLDialect dialect) { + return applyQuotes(str, dialect.getBeginQuote(), dialect.getEndQuote()); + } } diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/metadata/PhysicalRefColumnContext.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/metadata/PhysicalRefColumnContext.java index a2a6e6844f..d939292818 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/metadata/PhysicalRefColumnContext.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/metadata/PhysicalRefColumnContext.java @@ -6,7 +6,6 @@ package com.yahoo.elide.datastores.aggregation.metadata; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.PERIOD; import static org.apache.commons.lang3.StringUtils.isBlank; import com.yahoo.elide.core.request.Argument; diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/query/Optimizer.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/query/Optimizer.java index 10045ec86e..587ddca31c 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/query/Optimizer.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/query/Optimizer.java @@ -6,8 +6,6 @@ package com.yahoo.elide.datastores.aggregation.query; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable; - /** * Optimizes query plans. */ @@ -31,12 +29,12 @@ default String negateHint() { * Verifies if this optimizer can execute on the given query. * @return True if the query can be optimized by this optimizer. */ - boolean canOptimize(Query query, SQLReferenceTable referenceTable); + boolean canOptimize(Query query); /** * Optimizes the query. * @param query The query to optimize. * @return A new optimized query. */ - Query optimize(Query query, SQLReferenceTable referenceTable); + Query optimize(Query query); } diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/query/Queryable.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/query/Queryable.java index 5b38e104c5..b05c5959c1 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/query/Queryable.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/query/Queryable.java @@ -303,7 +303,7 @@ default SQLDialect getDialect() { } /** - * Converts a filter expression into a set of ColumnProjections + * Converts a filter expression into a set of ColumnProjections. * @param query The parent query. * @param expression The filter expression to extract. * @return A set of zero or more column projections with their arguments. diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/SQLQueryEngine.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/SQLQueryEngine.java index 260c97eaae..0bebad76d3 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/SQLQueryEngine.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/SQLQueryEngine.java @@ -36,8 +36,6 @@ import com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.FromTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.VersionQuery; import com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.DynamicSQLReferenceTable; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.query.NativeQuery; import com.yahoo.elide.datastores.aggregation.queryengines.sql.query.QueryPlanTranslator; @@ -77,7 +75,6 @@ public class SQLQueryEngine extends QueryEngine { @Getter - private final SQLReferenceTable referenceTable; private final ConnectionDetails defaultConnectionDetails; private final Map connectionDetailsMap; private final Set optimizers; @@ -115,7 +112,6 @@ public SQLQueryEngine( this.formulaValidator = new FormulaValidator(metaDataStore); this.metadataDictionary = metaDataStore.getMetadataDictionary(); populateMetaData(metaDataStore); - this.referenceTable = new SQLReferenceTable(metaDataStore); this.optimizers = optimizers; } @@ -408,14 +404,13 @@ private Query expandMetricQueryPlans(Query query) { } } - QueryPlanTranslator queryPlanTranslator = new QueryPlanTranslator(query, referenceTable); + QueryPlanTranslator queryPlanTranslator = new QueryPlanTranslator(query, metaDataStore); Query merged = (mergedPlan == null) - ? QueryPlanTranslator.addHiddenProjections(referenceTable, query).build() + ? QueryPlanTranslator.addHiddenProjections(metaDataStore, query).build() : queryPlanTranslator.translate(mergedPlan); for (Optimizer optimizer : optimizers) { - SQLReferenceTable queryReferenceTable = new DynamicSQLReferenceTable(referenceTable, merged); SQLTable table = (SQLTable) query.getSource(); //TODO - support hints in table joins & query header. Query Header hints override join hints which @@ -428,8 +423,8 @@ private Query expandMetricQueryPlans(Query query) { continue; } - if (optimizer.canOptimize(merged, queryReferenceTable)) { - merged = optimizer.optimize(merged, queryReferenceTable); + if (optimizer.canOptimize(merged)) { + merged = optimizer.optimize(merged); } } diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/expression/ExpressionParser.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/expression/ExpressionParser.java index 769c2fbd39..78ce27c74c 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/expression/ExpressionParser.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/expression/ExpressionParser.java @@ -7,8 +7,8 @@ package com.yahoo.elide.datastores.aggregation.queryengines.sql.expression; import static com.yahoo.elide.core.request.Argument.getArgumentMapFromString; +import static com.yahoo.elide.datastores.aggregation.metadata.ColumnContext.PERIOD; import static com.yahoo.elide.datastores.aggregation.metadata.ColumnContext.mergedArgumentMap; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.PERIOD; import static org.apache.commons.lang3.StringUtils.isEmpty; import com.yahoo.elide.core.Path; import com.yahoo.elide.core.dictionary.EntityDictionary; diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/expression/JoinExpressionExtractor.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/expression/JoinExpressionExtractor.java index 165579fea2..b5fabed65c 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/expression/JoinExpressionExtractor.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/expression/JoinExpressionExtractor.java @@ -7,10 +7,10 @@ package com.yahoo.elide.datastores.aggregation.queryengines.sql.expression; import static com.yahoo.elide.core.utils.TypeHelper.appendAlias; +import static com.yahoo.elide.datastores.aggregation.metadata.ColumnContext.applyQuotes; import static com.yahoo.elide.datastores.aggregation.metadata.ColumnContext.mergedArgumentMap; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.applyQuotes; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.hasSql; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.resolveTableOrSubselect; +import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable.hasSql; +import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable.resolveTableOrSubselect; import static java.util.Collections.emptySet; import static org.apache.commons.lang3.StringUtils.EMPTY; import com.yahoo.elide.core.Path.PathElement; diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/DynamicSQLReferenceTable.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/DynamicSQLReferenceTable.java deleted file mode 100644 index c8c90d706d..0000000000 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/DynamicSQLReferenceTable.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2020, Yahoo Inc. - * Licensed under the Apache License, Version 2.0 - * See LICENSE file in project root for terms. - */ -package com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata; - -import com.yahoo.elide.datastores.aggregation.query.Queryable; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.Reference; -import com.google.common.collect.Sets; -import lombok.Getter; - -import java.util.List; - -/** - * Table stores all resolved physical reference and join paths of all columns for both static tables - * and an active query. This class avoids copying the static reference table for each query. - */ -public class DynamicSQLReferenceTable extends SQLReferenceTable { - - //Stores the static table references - @Getter - private final SQLReferenceTable staticReferenceTable; - - public DynamicSQLReferenceTable(SQLReferenceTable staticReferenceTable, Queryable query) { - super(staticReferenceTable.getMetaDataStore(), Sets.newHashSet(query)); - - this.staticReferenceTable = staticReferenceTable; - } - - @Override - public List getReferenceTree(Queryable queryable, String fieldName) { - if (staticReferenceTable.referenceTree.containsKey(queryable)) { - return staticReferenceTable.getReferenceTree(queryable, fieldName); - } - return referenceTree.get(queryable).get(fieldName); - } -} diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/SQLReferenceTable.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/SQLReferenceTable.java deleted file mode 100644 index 48dba26390..0000000000 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/SQLReferenceTable.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2020, Yahoo Inc. - * Licensed under the Apache License, Version 2.0 - * See LICENSE file in project root for terms. - */ -package com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata; - -import com.yahoo.elide.core.dictionary.EntityDictionary; -import com.yahoo.elide.core.type.ClassType; -import com.yahoo.elide.core.type.Type; -import com.yahoo.elide.datastores.aggregation.metadata.MetaDataStore; -import com.yahoo.elide.datastores.aggregation.metadata.models.Table; -import com.yahoo.elide.datastores.aggregation.query.Queryable; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.FromSubquery; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.FromTable; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialect; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.ExpressionParser; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.Reference; -import org.apache.commons.lang3.StringUtils; -import org.hibernate.annotations.Subselect; -import lombok.Getter; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Table stores all resolved physical reference and join paths of all columns. - */ -public class SQLReferenceTable { - public static final String PERIOD = "."; - - @Getter - protected final MetaDataStore metaDataStore; - - @Getter - protected final EntityDictionary dictionary; - - private final ExpressionParser parser; - - //Stores MAP> - protected final Map>> referenceTree = new HashMap<>(); - - public SQLReferenceTable(MetaDataStore metaDataStore) { - this(metaDataStore, - metaDataStore.getMetaData(ClassType.of(Table.class)) - .stream() - .map(SQLTable.class::cast) - .collect(Collectors.toSet())); - } - - protected SQLReferenceTable(MetaDataStore metaDataStore, Set queryables) { - this.metaDataStore = metaDataStore; - this.dictionary = this.metaDataStore.getMetadataDictionary(); - this.parser = new ExpressionParser(metaDataStore); - - queryables - .stream() - // If Queryable is root, then its SQLTable. - // We need to store references only for SQLTable and Nested Queries (Queryable -> Queryable -> SQLTable). - // In case of Query -> SQLTable. Query doesn't know about all logical references. - .filter(queryable -> queryable.isNested() || queryable.isRoot()) - .forEach(queryable -> { - Queryable next = queryable; - do { - resolveAndStoreAllReferencesAndJoins(next); - next = next.getSource(); - } while (next.isNested()); - }); - } - - /** - * Get the Reference tree for provided field. - * @param queryable Query / SQLTable - * @param fieldName field name. - * @return {@link Reference} Tree. - */ - public List getReferenceTree(Queryable queryable, String fieldName) { - return referenceTree.get(queryable).getOrDefault(fieldName, new ArrayList<>()); - } - - /** - * Resolve all references and joins for a table and store them in this reference table. - * - * @param queryable meta data table - */ - public void resolveAndStoreAllReferencesAndJoins(Queryable queryable) { - - //References and joins are stored by their source that produces them (rather than the query that asks for them). - Queryable key = queryable.getSource(); - - if (!referenceTree.containsKey(key)) { - referenceTree.put(key, new HashMap<>()); - } - - queryable.getColumnProjections().forEach(column -> { - String fieldName = column.getName(); - referenceTree.get(key).put(fieldName, parser.parse(queryable, column)); - }); - } - - /** - * Check whether a class is mapped to a subselect query instead of a physical table. - * - * @param cls The entity class - * @return True if the class has {@link Subselect} annotation - */ - public static boolean hasSql(Type cls) { - return cls.isAnnotationPresent(Subselect.class) || cls.isAnnotationPresent(FromSubquery.class); - } - - /** - * Maps an entity class to a physical table of subselect query, if neither {@link javax.persistence.Table} - * nor {@link Subselect} annotation is present on this class, try {@link FromTable} and {@link FromSubquery}. - * - * @param cls The entity class. - * @return The physical SQL table or subselect query. - */ - public static String resolveTableOrSubselect(EntityDictionary dictionary, Type cls) { - if (hasSql(cls)) { - if (cls.isAnnotationPresent(FromSubquery.class)) { - return dictionary.getAnnotation(cls, FromSubquery.class).sql(); - } - return dictionary.getAnnotation(cls, Subselect.class).value(); - } - javax.persistence.Table table = dictionary.getAnnotation(cls, javax.persistence.Table.class); - - if (table != null) { - return resolveTableAnnotation(table); - } - FromTable fromTable = dictionary.getAnnotation(cls, FromTable.class); - - return fromTable != null ? fromTable.name() : cls.getSimpleName(); - } - - /** - * Get the full table name from JPA {@link javax.persistence.Table} annotation. - * - * @param table table annotation - * @return catalog.schema.name - */ - private static String resolveTableAnnotation(javax.persistence.Table table) { - StringBuilder fullTableName = new StringBuilder(); - - if (!"".equals(table.catalog())) { - fullTableName.append(table.catalog()).append("."); - } - if (!"".equals(table.schema())) { - fullTableName.append(table.schema()).append("."); - } - fullTableName.append(table.name()); - - return fullTableName.toString(); - } - - /** - * Split a string on ".", append quotes around each split and join it back. - * eg: game.order_details to `game`.`order_details` . - * - * @param str column name / alias - * @param beginQuote prefix char - * @param endQuote suffix char - * @return quoted string - */ - private static String applyQuotes(String str, char beginQuote, char endQuote) { - if (StringUtils.isBlank(str)) { - return str; - } - if (str.contains(PERIOD)) { - return beginQuote + str.trim().replace(PERIOD, endQuote + PERIOD + beginQuote) + endQuote; - } - return beginQuote + str.trim() + endQuote; - } - - /** - * Split a string on ".", append quotes around each split and join it back. - * eg: game.order_details to `game`.`order_details` . - * - * @param str column name / alias - * @param dialect Elide SQL dialect - * @return quoted string - */ - public static String applyQuotes(String str, SQLDialect dialect) { - return applyQuotes(str, dialect.getBeginQuote(), dialect.getEndQuote()); - } -} diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/SQLTable.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/SQLTable.java index f480b8cfad..648677ebcb 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/SQLTable.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/metadata/SQLTable.java @@ -5,6 +5,7 @@ */ package com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata; +import static com.yahoo.elide.datastores.aggregation.metadata.ColumnContext.PERIOD; import static java.util.Collections.emptyMap; import com.yahoo.elide.core.dictionary.EntityBinding; import com.yahoo.elide.core.dictionary.EntityDictionary; @@ -28,9 +29,15 @@ import com.yahoo.elide.datastores.aggregation.query.Queryable; import com.yahoo.elide.datastores.aggregation.query.TimeDimensionProjection; import com.yahoo.elide.datastores.aggregation.queryengines.sql.ConnectionDetails; +import com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.FromSubquery; +import com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.FromTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLDimensionProjection; import com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLMetricProjection; import com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLTimeDimensionProjection; + +import org.apache.commons.lang3.StringUtils; +import org.hibernate.annotations.Subselect; + import lombok.EqualsAndHashCode; import lombok.Getter; @@ -314,4 +321,55 @@ private static Map prepareArgMap(Set argum .build()) .collect(Collectors.toMap(Argument::getName, Function.identity())); } + + /** + * Check whether a class is mapped to a subselect query instead of a physical table. + * @param cls The entity class. + * @return True if the class has {@link Subselect}/{@link FromSubquery} annotation. + */ + public static boolean hasSql(Type cls) { + return cls.isAnnotationPresent(Subselect.class) || cls.isAnnotationPresent(FromSubquery.class); + } + + /** + * Maps an entity class to a physical table or subselect query, if neither {@link javax.persistence.Table} + * nor {@link Subselect} annotation is present on this class, try {@link FromTable} and {@link FromSubquery}. + * @param cls The entity class. + * @return The physical SQL table or subselect query. + */ + public static String resolveTableOrSubselect(EntityDictionary dictionary, Type cls) { + if (hasSql(cls)) { + if (cls.isAnnotationPresent(FromSubquery.class)) { + return dictionary.getAnnotation(cls, FromSubquery.class).sql(); + } + return dictionary.getAnnotation(cls, Subselect.class).value(); + } + javax.persistence.Table table = dictionary.getAnnotation(cls, javax.persistence.Table.class); + + if (table != null) { + return resolveTableAnnotation(table); + } + FromTable fromTable = dictionary.getAnnotation(cls, FromTable.class); + + return fromTable != null ? fromTable.name() : cls.getSimpleName(); + } + + /** + * Get the full table name from JPA {@link javax.persistence.Table} annotation. + * @param table table annotation. + * @return catalog.schema.name + */ + private static String resolveTableAnnotation(javax.persistence.Table table) { + StringBuilder fullTableName = new StringBuilder(); + + if (StringUtils.isNotBlank(table.catalog())) { + fullTableName.append(table.catalog()).append(PERIOD); + } + + if (StringUtils.isNotBlank(table.schema())) { + fullTableName.append(table.schema()).append(PERIOD); + } + + return fullTableName.append(table.name()).toString(); + } } diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/AggregateBeforeJoinOptimizer.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/AggregateBeforeJoinOptimizer.java index b048ac6c23..61a1e3288f 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/AggregateBeforeJoinOptimizer.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/AggregateBeforeJoinOptimizer.java @@ -17,7 +17,6 @@ import com.yahoo.elide.datastores.aggregation.query.QueryVisitor; import com.yahoo.elide.datastores.aggregation.query.Queryable; import com.yahoo.elide.datastores.aggregation.query.TimeDimensionProjection; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable; import com.google.common.collect.Streams; import org.apache.commons.lang3.tuple.Pair; @@ -43,16 +42,11 @@ public AggregateBeforeJoinOptimizer(MetaDataStore metaDataStore) { } private class OptimizerVisitor implements QueryVisitor { - private SQLReferenceTable lookupTable; - - public OptimizerVisitor(SQLReferenceTable lookupTable) { - this.lookupTable = lookupTable; - } @Override public Queryable visitQuery(Query query) { SubqueryFilterSplitter.SplitFilter splitWhere = - SubqueryFilterSplitter.splitFilter(lookupTable, metaDataStore, query.getWhereFilter()); + SubqueryFilterSplitter.splitFilter(metaDataStore, query.getWhereFilter()); Set allProjections = Streams.concat( query.getColumnProjections().stream(), @@ -60,7 +54,7 @@ public Queryable visitQuery(Query query) { .collect(Collectors.toCollection(LinkedHashSet::new)); Set>> allProjectionsNested = allProjections.stream() - .map((projection) -> projection.nest(query, lookupTable.getMetaDataStore(), true)) + .map((projection) -> projection.nest(query, metaDataStore, true)) .collect(Collectors.toCollection(LinkedHashSet::new)); Set allOuterProjections = allProjectionsNested.stream() @@ -88,7 +82,7 @@ public Queryable visitQuery(Query query) { .collect(Collectors.toCollection(LinkedHashSet::new))) .whereFilter(splitWhere.getInner()); - addHiddenProjections(lookupTable, inner, query); + addHiddenProjections(metaDataStore, inner, query); Query outer = Query.builder() .metricProjections(allOuterProjections.stream() @@ -127,8 +121,7 @@ public String hint() { } @Override - public boolean canOptimize(Query query, SQLReferenceTable lookupTable) { - MetaDataStore store = lookupTable.getMetaDataStore(); + public boolean canOptimize(Query query) { //For simplicity, we will not optimize an already nested query. if (query.isNested()) { return false; @@ -136,7 +129,7 @@ public boolean canOptimize(Query query, SQLReferenceTable lookupTable) { //Every column must be nestable. if (! query.getColumnProjections().stream() - .allMatch((projection) -> projection.canNest(query, store))) { + .allMatch((projection) -> projection.canNest(query, metaDataStore))) { return false; } @@ -153,7 +146,7 @@ public boolean canOptimize(Query query, SQLReferenceTable lookupTable) { //the projection and we check projections below. if (query.getWhereFilter() != null) { SubqueryFilterSplitter.SplitFilter splitFilter = - SubqueryFilterSplitter.splitFilter(lookupTable, metaDataStore, query.getWhereFilter()); + SubqueryFilterSplitter.splitFilter(metaDataStore, query.getWhereFilter()); if (splitFilter.getOuter() != null) { return true; @@ -162,7 +155,7 @@ public boolean canOptimize(Query query, SQLReferenceTable lookupTable) { //Next check the projection for required joins. for (ColumnProjection column: query.getColumnProjections()) { - boolean requiresJoin = SQLColumnProjection.requiresJoin(query.getSource(), column, store); + boolean requiresJoin = SQLColumnProjection.requiresJoin(query.getSource(), column, metaDataStore); if (requiresJoin) { return true; @@ -173,11 +166,11 @@ public boolean canOptimize(Query query, SQLReferenceTable lookupTable) { } @Override - public Query optimize(Query query, SQLReferenceTable lookupTable) { - if (! canOptimize(query, lookupTable)) { + public Query optimize(Query query) { + if (! canOptimize(query)) { return query; } - return (Query) query.accept(new OptimizerVisitor(lookupTable)); + return (Query) query.accept(new OptimizerVisitor()); } } diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/QueryPlanTranslator.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/QueryPlanTranslator.java index d30a44d667..29c56c7aef 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/QueryPlanTranslator.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/QueryPlanTranslator.java @@ -6,14 +6,15 @@ package com.yahoo.elide.datastores.aggregation.queryengines.sql.query; +import com.yahoo.elide.datastores.aggregation.metadata.MetaDataStore; import com.yahoo.elide.datastores.aggregation.query.ColumnProjection; import com.yahoo.elide.datastores.aggregation.query.Query; import com.yahoo.elide.datastores.aggregation.query.QueryPlan; import com.yahoo.elide.datastores.aggregation.query.QueryVisitor; import com.yahoo.elide.datastores.aggregation.query.Queryable; +import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.ExpressionParser; import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.LogicalReference; import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.ReferenceExtractor; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable; import com.google.common.collect.Streams; import java.util.HashSet; @@ -33,10 +34,10 @@ public class QueryPlanTranslator implements QueryVisitor { //Whether or not this visitor has been invoked yet. private boolean invoked = false; - private SQLReferenceTable lookupTable; + private MetaDataStore metaDataStore; - public QueryPlanTranslator(Query clientQuery, SQLReferenceTable lookupTable) { - this.lookupTable = lookupTable; + public QueryPlanTranslator(Query clientQuery, MetaDataStore metaDataStore) { + this.metaDataStore = metaDataStore; this.clientQuery = clientQuery; } @@ -55,11 +56,11 @@ public Query translate(QueryPlan plan) { .build(); //Merge it with the metric plan. - if (plan.isNested() && !clientQueryPlan.canNest(lookupTable.getMetaDataStore())) { + if (plan.isNested() && !clientQueryPlan.canNest(metaDataStore)) { throw new UnsupportedOperationException("Cannot nest one or more dimensions from the client query"); } - QueryPlan merged = clientQueryPlan.merge(plan, lookupTable.getMetaDataStore()); + QueryPlan merged = clientQueryPlan.merge(plan, metaDataStore); //Decorate the result with filters, sorting, and pagination. return merged.accept(this).build(); @@ -94,7 +95,7 @@ private Query.QueryBuilder visitInnerQueryPlan(Queryable plan) { .whereFilter(clientQuery.getWhereFilter()) .arguments(clientQuery.getArguments()); - return addHiddenProjections(lookupTable, builder, clientQuery); + return addHiddenProjections(metaDataStore, builder, clientQuery); } private Query.QueryBuilder visitOuterQueryPlan(Queryable plan) { @@ -139,11 +140,11 @@ private Query.QueryBuilder visitUnnestedQueryPlan(Queryable plan) { .scope(clientQuery.getScope()) .arguments(clientQuery.getArguments()); - return addHiddenProjections(lookupTable, builder, clientQuery); + return addHiddenProjections(metaDataStore, builder, clientQuery); } public static Query.QueryBuilder addHiddenProjections( - SQLReferenceTable lookupTable, + MetaDataStore metaDataStore, Query.QueryBuilder builder, Query query ) { @@ -153,12 +154,13 @@ public static Query.QueryBuilder addHiddenProjections( query.getFilterProjections(query.getWhereFilter(), ColumnProjection.class).stream() ).collect(Collectors.toSet()); + ExpressionParser parser = new ExpressionParser(metaDataStore); Set indirectReferenceColumns = new HashSet<>(); directReferencedColumns.forEach(column -> { - lookupTable.getReferenceTree(query.getSource(), column.getName()).stream() + parser.parse(query.getSource(), column).stream() .map(reference -> reference.accept(new ReferenceExtractor( LogicalReference.class, - lookupTable.getMetaDataStore(), + metaDataStore, ReferenceExtractor.Mode.SAME_QUERY))) .flatMap(Set::stream) .map(LogicalReference::getColumn) @@ -177,7 +179,7 @@ public static Query.QueryBuilder addHiddenProjections( return builder; } - public static Query.QueryBuilder addHiddenProjections(SQLReferenceTable lookupTable, Query query) { + public static Query.QueryBuilder addHiddenProjections(MetaDataStore metaDataStore, Query query) { Query.QueryBuilder builder = Query.builder() .source(query.getSource()) .metricProjections(query.getMetricProjections()) @@ -190,6 +192,6 @@ public static Query.QueryBuilder addHiddenProjections(SQLReferenceTable lookupTa .scope(query.getScope()) .arguments(query.getArguments()); - return addHiddenProjections(lookupTable, builder, query); + return addHiddenProjections(metaDataStore, builder, query); } } diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/QueryTranslator.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/QueryTranslator.java index 819399b2de..9354364f67 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/QueryTranslator.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/QueryTranslator.java @@ -29,7 +29,6 @@ import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.ExpressionParser; import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.JoinExpressionExtractor; import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.Reference; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable; import java.util.Collection; import java.util.LinkedHashSet; @@ -369,6 +368,6 @@ private SQLColumnProjection fieldToColumnProjection(Query query, String fieldNam * @return quoted alias */ private String applyQuotes(String str) { - return SQLReferenceTable.applyQuotes(str, dialect); + return ColumnContext.applyQuotes(str, dialect); } } diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SQLPhysicalColumnProjection.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SQLPhysicalColumnProjection.java index f61a7286ba..a100104998 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SQLPhysicalColumnProjection.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SQLPhysicalColumnProjection.java @@ -6,7 +6,7 @@ package com.yahoo.elide.datastores.aggregation.queryengines.sql.query; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.applyQuotes; +import static com.yahoo.elide.datastores.aggregation.metadata.ColumnContext.applyQuotes; import com.yahoo.elide.core.request.Argument; import com.yahoo.elide.core.utils.TypeHelper; diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SubqueryFilterSplitter.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SubqueryFilterSplitter.java index 371a62f448..f4acad2f7e 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SubqueryFilterSplitter.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SubqueryFilterSplitter.java @@ -15,9 +15,9 @@ import com.yahoo.elide.core.filter.visitors.FilterExpressionNormalizationVisitor; import com.yahoo.elide.core.type.Type; import com.yahoo.elide.datastores.aggregation.metadata.MetaDataStore; +import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.ExpressionParser; import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.HasJoinVisitor; import com.yahoo.elide.datastores.aggregation.queryengines.sql.expression.Reference; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable; import lombok.Builder; import lombok.Data; @@ -39,16 +39,15 @@ public static class SplitFilter { FilterExpression inner; } - private SQLReferenceTable lookupTable; private MetaDataStore metaDataStore; + private ExpressionParser parser; - public SubqueryFilterSplitter(MetaDataStore metaDataStore, SQLReferenceTable lookupTable) { + public SubqueryFilterSplitter(MetaDataStore metaDataStore) { this.metaDataStore = metaDataStore; - this.lookupTable = lookupTable; + this.parser = new ExpressionParser(metaDataStore); } public static SplitFilter splitFilter( - SQLReferenceTable lookupTable, MetaDataStore metaDataStore, FilterExpression expression) { @@ -59,7 +58,7 @@ public static SplitFilter splitFilter( FilterExpressionNormalizationVisitor normalizer = new FilterExpressionNormalizationVisitor(); FilterExpression normalizedExpression = expression.accept(normalizer); - return normalizedExpression.accept(new SubqueryFilterSplitter(metaDataStore, lookupTable)); + return normalizedExpression.accept(new SubqueryFilterSplitter(metaDataStore)); } @Override @@ -69,7 +68,7 @@ public SplitFilter visitPredicate(FilterPredicate filterPredicate) { SQLTable table = metaDataStore.getTable(tableType); - List references = lookupTable.getReferenceTree(table, fieldName); + List references = parser.parse(table, table.getColumnProjection(fieldName)); boolean hasJoin = references.stream().anyMatch(ref -> ref.accept(new HasJoinVisitor())); if (hasJoin) { return SplitFilter.builder().outer(filterPredicate).build(); diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/validator/ColumnArgumentValidator.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/validator/ColumnArgumentValidator.java index e337fabadf..f8e71a5a0d 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/validator/ColumnArgumentValidator.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/validator/ColumnArgumentValidator.java @@ -68,10 +68,10 @@ public void validate() { List references = parser.parse(table, column.getExpression()); - ReferenceExtractor logicalRefExtractor = new ReferenceExtractor(LogicalReference.class, - metaDataStore, ReferenceExtractor.Mode.SAME_COLUMN); - ReferenceExtractor columnArgRefExtractor = new ReferenceExtractor(ColumnArgReference.class, - metaDataStore, ReferenceExtractor.Mode.SAME_COLUMN); + ReferenceExtractor logicalRefExtractor = new ReferenceExtractor( + LogicalReference.class, metaDataStore, ReferenceExtractor.Mode.SAME_COLUMN); + ReferenceExtractor columnArgRefExtractor = new ReferenceExtractor( + ColumnArgReference.class, metaDataStore, ReferenceExtractor.Mode.SAME_COLUMN); references.stream() .map(reference -> reference.accept(columnArgRefExtractor)) diff --git a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/validator/TableArgumentValidator.java b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/validator/TableArgumentValidator.java index ab6e213b9a..d2959978c9 100644 --- a/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/validator/TableArgumentValidator.java +++ b/elide-datastore/elide-datastore-aggregation/src/main/java/com/yahoo/elide/datastores/aggregation/validator/TableArgumentValidator.java @@ -6,8 +6,8 @@ package com.yahoo.elide.datastores.aggregation.validator; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.hasSql; -import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable.resolveTableOrSubselect; +import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable.hasSql; +import static com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable.resolveTableOrSubselect; import com.yahoo.elide.core.dictionary.EntityDictionary; import com.yahoo.elide.core.type.Type; diff --git a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/metadata/ColumnContextTest.java b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/metadata/ColumnContextTest.java index 75e361f8fa..94ff1fbba6 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/metadata/ColumnContextTest.java +++ b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/metadata/ColumnContextTest.java @@ -25,7 +25,6 @@ import com.yahoo.elide.datastores.aggregation.queryengines.sql.SQLQueryEngine; import com.yahoo.elide.datastores.aggregation.queryengines.sql.annotation.FromTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialectFactory; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLDimensionProjection; import com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLMetricProjection; @@ -47,7 +46,6 @@ public class ColumnContextTest { private SQLTable revenueFactTable; private MetaDataStore metaDataStore; private Map queryArgs = new HashMap<>(); - private SQLReferenceTable refTable; public ColumnContextTest() { Set> models = new HashSet<>(); @@ -65,7 +63,6 @@ public ColumnContextTest() { // The query engine populates the metadata store with actual tables. new SQLQueryEngine(metaDataStore, new ConnectionDetails(mockDataSource, SQLDialectFactory.getDefaultDialect())); - refTable = new SQLReferenceTable(metaDataStore); revenueFactTable = metaDataStore.getTable(ClassType.of(RevenueFact.class)); queryArgs.put("format", Argument.builder().name("format").value("999999D000000").build()); @@ -114,7 +111,7 @@ public void testLogicalReference() { .dimensionProjections(query.getDimensionProjections()) .arguments(query.getArguments()); - Query expandedQuery = addHiddenProjections(refTable, builder, query).build(); + Query expandedQuery = addHiddenProjections(metaDataStore, builder, query).build(); // definition: {{$$column.args.aggregation}}({{$impressions}}) // -> value of 'aggregation' argument is passed in the query for "impressions" column and same is used while @@ -195,7 +192,7 @@ public void testSqlHelper() { .metricProjections(query.getMetricProjections()) .arguments(query.getArguments()); - Query expandedQuery = addHiddenProjections(refTable, builder, query).build(); + Query expandedQuery = addHiddenProjections(metaDataStore, builder, query).build(); // definition: TO_CHAR(SUM({{$revenue}}) * {{sql from='rate' column='conversionRate[format:9999D0000]'}}, {{$$column.args.format}}) // -> value of 'format' argument is passed in the query for "revenueUsingSqlHelper" column and same is used for diff --git a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/metadata/PhysicalRefColumnContextTest.java b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/metadata/PhysicalRefColumnContextTest.java index 43c20e4781..4f3666f067 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/metadata/PhysicalRefColumnContextTest.java +++ b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/metadata/PhysicalRefColumnContextTest.java @@ -18,7 +18,6 @@ import com.yahoo.elide.datastores.aggregation.queryengines.sql.ConnectionDetails; import com.yahoo.elide.datastores.aggregation.queryengines.sql.SQLQueryEngine; import com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialectFactory; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLDimensionProjection; import com.yahoo.elide.datastores.aggregation.queryengines.sql.query.SQLMetricProjection; @@ -37,7 +36,6 @@ public class PhysicalRefColumnContextTest { private SQLTable revenueFactTable; private MetaDataStore metaDataStore; private Map queryArgs = new HashMap<>(); - private SQLReferenceTable refTable; public PhysicalRefColumnContextTest() { Set> models = new HashSet<>(); @@ -55,7 +53,6 @@ public PhysicalRefColumnContextTest() { // The query engine populates the metadata store with actual tables. new SQLQueryEngine(metaDataStore, new ConnectionDetails(mockDataSource, SQLDialectFactory.getDefaultDialect())); - refTable = new SQLReferenceTable(metaDataStore); revenueFactTable = metaDataStore.getTable(ClassType.of(RevenueFact.class)); queryArgs.put("format", Argument.builder().name("format").value("999999D000000").build()); @@ -104,7 +101,7 @@ public void testLogicalReference() { .dimensionProjections(query.getDimensionProjections()) .arguments(query.getArguments()); - Query expandedQuery = addHiddenProjections(refTable, builder, query).build(); + Query expandedQuery = addHiddenProjections(metaDataStore, builder, query).build(); // definition: {{$$column.args.aggregation}}({{$impressions}}) // -> value of 'aggregation' argument is passed in the query for "impressions" column and same is used while @@ -177,7 +174,7 @@ public void testSqlHelper() { .metricProjections(query.getMetricProjections()) .arguments(query.getArguments()); - Query expandedQuery = addHiddenProjections(refTable, builder, query).build(); + Query expandedQuery = addHiddenProjections(metaDataStore, builder, query).build(); // definition: TO_CHAR(SUM({{$revenue}}) * {{sql from='rate' column='conversionRate[format:9999D0000]'}}, {{$$column.args.format}}) // -> value of 'format' argument is passed in the query for "revenueUsingSqlHelper" column and same is used for diff --git a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/AggregateBeforeJoinOptimizerTest.java b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/AggregateBeforeJoinOptimizerTest.java index 139030b51c..2fd0aef481 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/AggregateBeforeJoinOptimizerTest.java +++ b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/AggregateBeforeJoinOptimizerTest.java @@ -28,7 +28,6 @@ import com.yahoo.elide.datastores.aggregation.query.Optimizer; import com.yahoo.elide.datastores.aggregation.query.Query; import com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.impl.H2Dialect; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.DynamicSQLReferenceTable; import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLTable; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -153,9 +152,7 @@ public void testNoOptimizationNoJoins() { AggregateBeforeJoinOptimizer optimizer = new AggregateBeforeJoinOptimizer(metaDataStore); - DynamicSQLReferenceTable lookupTable = new DynamicSQLReferenceTable(engine.getReferenceTable(), query); - - assertFalse(optimizer.canOptimize(query, lookupTable)); + assertFalse(optimizer.canOptimize(query)); } @Test @@ -170,9 +167,7 @@ public void testNoOptimizationNestedQuery() { AggregateBeforeJoinOptimizer optimizer = new AggregateBeforeJoinOptimizer(metaDataStore); - DynamicSQLReferenceTable lookupTable = new DynamicSQLReferenceTable(engine.getReferenceTable(), query); - - assertFalse(optimizer.canOptimize(query, lookupTable)); + assertFalse(optimizer.canOptimize(query)); } @Test diff --git a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SkipOptimizerTest.java b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SkipOptimizerTest.java index 2996d93206..84730a3a5e 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SkipOptimizerTest.java +++ b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SkipOptimizerTest.java @@ -54,7 +54,7 @@ public void testSkippingOptimizer() { Query query = TestQuery.WHERE_AND.getQuery(); engine.explain(query); - verify(optimizer, never()).optimize(any(), any()); + verify(optimizer, never()).optimize(any()); } @Test @@ -64,6 +64,6 @@ public void testNegatingOptimizer() { Query query = TestQuery.WHERE_AND.getQuery(); engine.explain(query); - verify(optimizer, never()).optimize(any(), any()); + verify(optimizer, never()).optimize(any()); } } diff --git a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SubqueryFilterSplitterTest.java b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SubqueryFilterSplitterTest.java index 21bbbf5c3c..988bd17823 100644 --- a/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SubqueryFilterSplitterTest.java +++ b/elide-datastore/elide-datastore-aggregation/src/test/java/com/yahoo/elide/datastores/aggregation/queryengines/sql/query/SubqueryFilterSplitterTest.java @@ -25,7 +25,6 @@ import com.yahoo.elide.datastores.aggregation.queryengines.sql.ConnectionDetails; import com.yahoo.elide.datastores.aggregation.queryengines.sql.SQLQueryEngine; import com.yahoo.elide.datastores.aggregation.queryengines.sql.dialects.SQLDialectFactory; -import com.yahoo.elide.datastores.aggregation.queryengines.sql.metadata.SQLReferenceTable; import org.junit.jupiter.api.Test; import java.util.HashMap; @@ -36,7 +35,6 @@ public class SubqueryFilterSplitterTest { private MetaDataStore metaDataStore; - private SQLReferenceTable lookupTable; private RSQLFilterDialect dialect; private static final Type PLAYER_STATS_TYPE = ClassType.of(PlayerStats.class); @@ -61,7 +59,6 @@ public SubqueryFilterSplitterTest() { new SQLQueryEngine(metaDataStore, new ConnectionDetails(mockDataSource, SQLDialectFactory.getDefaultDialect())); - lookupTable = new SQLReferenceTable(metaDataStore); dialect = new RSQLFilterDialect(dictionary); } @@ -71,7 +68,7 @@ public void testSinglePredicateNoJoin() throws Exception { FilterExpression expression = parse("overallRating=='Foo'"); SubqueryFilterSplitter.SplitFilter splitExpressions = - SubqueryFilterSplitter.splitFilter(lookupTable, metaDataStore, expression); + SubqueryFilterSplitter.splitFilter(metaDataStore, expression); assertNull(splitExpressions.getOuter()); assertEquals(expression, splitExpressions.getInner()); @@ -82,7 +79,7 @@ public void testSinglePredicateWithJoin() throws Exception { FilterExpression expression = parse("countryUnSeats>3"); SubqueryFilterSplitter.SplitFilter splitExpressions = - SubqueryFilterSplitter.splitFilter(lookupTable, metaDataStore, expression); + SubqueryFilterSplitter.splitFilter(metaDataStore, expression); assertNull(splitExpressions.getInner()); assertEquals(expression, splitExpressions.getOuter()); @@ -95,7 +92,7 @@ public void testSplitByAnd() throws Exception { FilterExpression expectedInner = parse("overallRating=='Foo'"); SubqueryFilterSplitter.SplitFilter splitExpressions = - SubqueryFilterSplitter.splitFilter(lookupTable, metaDataStore, expression); + SubqueryFilterSplitter.splitFilter(metaDataStore, expression); assertEquals(expectedOuter, splitExpressions.getOuter()); assertEquals(expectedInner, splitExpressions.getInner()); @@ -106,7 +103,7 @@ public void testSplitByOr() throws Exception { FilterExpression expression = parse("countryUnSeats>3,overallRating=='Foo'"); SubqueryFilterSplitter.SplitFilter splitExpressions = - SubqueryFilterSplitter.splitFilter(lookupTable, metaDataStore, expression); + SubqueryFilterSplitter.splitFilter(metaDataStore, expression); assertEquals(expression, splitExpressions.getOuter()); assertNull(splitExpressions.getInner()); @@ -121,7 +118,7 @@ public void testCompoundSplitByAnd() throws Exception { FilterExpression expectedInner = parse("overallRating=='Bar',overallRating=='Blah'"); SubqueryFilterSplitter.SplitFilter splitExpressions = - SubqueryFilterSplitter.splitFilter(lookupTable, metaDataStore, expression); + SubqueryFilterSplitter.splitFilter(metaDataStore, expression); assertEquals(expectedOuter, splitExpressions.getOuter()); assertEquals(expectedInner, splitExpressions.getInner()); @@ -133,7 +130,7 @@ public void testCompoundSplitByOr() throws Exception { "(countryUnSeats>3;overallRating=='Foo'),(overallRating=='Bar';overallRating=='Blah')"); SubqueryFilterSplitter.SplitFilter splitExpressions = - SubqueryFilterSplitter.splitFilter(lookupTable, metaDataStore, expression); + SubqueryFilterSplitter.splitFilter(metaDataStore, expression); assertEquals(expression, splitExpressions.getOuter()); assertNull(splitExpressions.getInner()); @@ -145,7 +142,7 @@ public void testAllOrsWithNoJoins() throws Exception { "(overallRating=='Foobar',overallRating=='Foo'),(overallRating=='Bar',overallRating=='Blah')"); SubqueryFilterSplitter.SplitFilter splitExpressions = - SubqueryFilterSplitter.splitFilter(lookupTable, metaDataStore, expression); + SubqueryFilterSplitter.splitFilter(metaDataStore, expression); assertEquals(expression, splitExpressions.getInner()); assertNull(splitExpressions.getOuter());