>From Preetham Poluparthi <preetha...@apache.org>: Preetham Poluparthi has uploaded this change for review. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20133 )
Change subject: test ...................................................................... test Change-Id: I1b2e6f645f2d4c28d6b8233eabec60805a4222ce --- M asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AbstractCBOPlanNode.java M asterixdb/asterix-app/pom.xml M hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOScanPlanNode.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOPlanStateTree.java M asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cbo-join/index-advisor/simple-advise/simple-advise.1.ddl.sqlpp M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/IIndexEnumerator.java M asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise/simple-advise.4.adm M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FilterConditionParser.java M asterixdb/asterix-cloud/pom.xml M asterixdb/asterix-dashboard/pom.xml M asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise2/simple-advise2.4.adm M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilterCondition.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOJoinPlanNode.java M asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise1/simple-advise1.4.adm M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilter.java 19 files changed, 301 insertions(+), 109 deletions(-) git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/33/20133/1 diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AbstractCBOPlanNode.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AbstractCBOPlanNode.java index e9dbfee..3118e51 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AbstractCBOPlanNode.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AbstractCBOPlanNode.java @@ -33,4 +33,6 @@ private final PlanNodeType planNodeType; public abstract List<CBOScanPlanNode> getLeafs(); + + public abstract List<CBOJoinPlanNode> getJoins(); } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java index d01f63b..600ca0e 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java @@ -108,29 +108,35 @@ .get(4).getValue()).getValue()).getObject()).getStringValue(); DataverseName dataverse = DataverseName.createSinglePartName(dataverseName); - - Index actualIndex = actualIndexProvider.getIndex(databaseName, dataverse, datasetName, indexName); + Index fakeIndex = fakeIndexProvider.getIndex(databaseName, dataverse, datasetName, indexName); + Index actualIndex = lookupIndex(databaseName, dataverse, datasetName, + ((Index.ValueIndexDetails) fakeIndex.getIndexDetails()).getKeyFieldNames(), actualIndexProvider); if (actualIndex != null) { - indexAdvisor.addPresentAdvise(indexName, + indexAdvisor.addPresentAdvise(actualIndex.getIndexName(), ((Index.ValueIndexDetails) actualIndex.getIndexDetails()).getKeyFieldNames(), databaseName, dataverseName, datasetName); return; } - Index fakeIndex = fakeIndexProvider.getIndex(databaseName, dataverse, datasetName, indexName); - - if (fakeIndex != null) { - indexAdvisor.addRecommendedAdvise( - getIndexNameClause(((Index.ValueIndexDetails) fakeIndex.getIndexDetails()).getKeyFieldNames()), - ((Index.ValueIndexDetails) fakeIndex.getIndexDetails()).getKeyFieldNames(), databaseName, - dataverseName, datasetName); - } + indexAdvisor.addRecommendedAdvise( + getIndexNameClause(((Index.ValueIndexDetails) fakeIndex.getIndexDetails()).getKeyFieldNames()), + ((Index.ValueIndexDetails) fakeIndex.getIndexDetails()).getKeyFieldNames(), databaseName, + dataverseName, datasetName); } } + private static Index lookupIndex(String databaseName, DataverseName dataverseName, String datasetName, + List<List<String>> fieldsNames, IIndexProvider indexProvider) throws AlgebricksException { + return indexProvider.getDatasetIndexes(databaseName, dataverseName, datasetName).stream() + .filter(index -> index.getIndexDetails() instanceof Index.ValueIndexDetails) + .filter(index -> ((Index.ValueIndexDetails) index.getIndexDetails()).getKeyFieldNames() + .equals(fieldsNames)) + .findFirst().orElse(null); + } + public static String getIndexNameClause(List<List<String>> fields) { StringBuilder sb = new StringBuilder(); sb.append("idx_"); diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOJoinPlanNode.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOJoinPlanNode.java index 7df211e..60ad41c 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOJoinPlanNode.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOJoinPlanNode.java @@ -44,4 +44,17 @@ leafs.addAll(right.getLeafs()); return leafs; } + + @Override + public List<CBOJoinPlanNode> getJoins() { + List<CBOJoinPlanNode> joins = new ArrayList<>(); + joins.add(this); + joins.addAll(left.getJoins()); + joins.addAll(right.getJoins()); + return joins; + } + + public JoinFilter getJoinCondition() { + return joinCondition; + } } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOPlanStateTree.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOPlanStateTree.java index a924403..24d5624 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOPlanStateTree.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOPlanStateTree.java @@ -18,5 +18,33 @@ */ package org.apache.asterix.optimizer.rules.cbo.indexadvisor; -public record CBOPlanStateTree(AbstractCBOPlanNode cboPlanNode) { +import java.util.HashMap; +import java.util.Map; + +import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; +import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator; + +public class CBOPlanStateTree { + private final AbstractCBOPlanNode cboPlanNode; + private final Map<LogicalVariable, DataSourceScanOperator> dataSourceScanVariableMap; + + public CBOPlanStateTree(AbstractCBOPlanNode cboPlanNode) { + this.cboPlanNode = cboPlanNode; + dataSourceScanVariableMap = new HashMap<>(); + for (CBOScanPlanNode scanNode : cboPlanNode.getLeafs()) { + DataSourceScanOperator scanOperator = scanNode.getScanOperator(); + for (LogicalVariable variable : scanOperator.getVariables()) { + dataSourceScanVariableMap.put(variable, scanOperator); + } + } + } + + public AbstractCBOPlanNode getCboPlanNode() { + return cboPlanNode; + } + + public Map<LogicalVariable, DataSourceScanOperator> getDataSourceScanVariableMap() { + return dataSourceScanVariableMap; + } + } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOScanPlanNode.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOScanPlanNode.java index 7cdd6f8..26522dc 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOScanPlanNode.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/CBOScanPlanNode.java @@ -56,6 +56,11 @@ return leafs; } + @Override + public List<CBOJoinPlanNode> getJoins() { + return new ArrayList<>(); + } + public ScanFilter getFilter() { return filter; } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java index 9d344fd..bba3218 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java @@ -37,26 +37,27 @@ import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; import org.apache.hyracks.algebricks.common.utils.Pair; import org.apache.hyracks.algebricks.common.utils.Triple; +import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator; public class FakeIndexProvider implements IIndexProvider { - private final Map<Triple<String, DataverseName, String>, Map<String, Index>> datasetIndexesMap; + private final Map<Triple<String, DataverseName, String>, Map<String, Index>> filterIndexesMap; public FakeIndexProvider(CBOPlanStateTree planStateTree) { - - Map<Triple<String, DataverseName, String>, Pair<DataSourceScanOperator, Set<List<String>>>> dataSourceFieldNamesMap = + Map<Triple<String, DataverseName, String>, Pair<DataSourceScanOperator, Set<List<String>>>> singleDataSourceFieldNamesMap = new HashMap<>(); - datasetIndexesMap = new HashMap<>(); + Map<Triple<String, DataverseName, String>, Set<List<String>>> joinDataSourceFieldNamesMap = new HashMap<>(); + filterIndexesMap = new HashMap<>(); - for (CBOScanPlanNode scanPlanNode : planStateTree.cboPlanNode().getLeafs()) { + for (CBOScanPlanNode scanPlanNode : planStateTree.getCboPlanNode().getLeafs()) { DataSourceScanOperator scanOperator = scanPlanNode.getScanOperator(); DataSource dataSource = (DataSource) scanOperator.getDataSource(); String databaseName = dataSource.getId().getDatabaseName(); DataverseName dataverseName = dataSource.getId().getDataverseName(); String datasetName = dataSource.getId().getDatasourceName(); - dataSourceFieldNamesMap.put(new Triple<>(databaseName, dataverseName, datasetName), + singleDataSourceFieldNamesMap.put(new Triple<>(databaseName, dataverseName, datasetName), new Pair<>(scanOperator, new HashSet<>())); ScanFilter filter = scanPlanNode.getFilter(); @@ -64,13 +65,48 @@ for (ScanFilterCondition filterCondition : filterConditions) { Triple<String, DataverseName, String> key = new Triple<>(databaseName, dataverseName, datasetName); - dataSourceFieldNamesMap.get(key).getSecond().add(filterCondition.getLhsFieldAccessPath()); + singleDataSourceFieldNamesMap.get(key).getSecond().add(filterCondition.getLhsFieldAccessPath()); } } - for (Map.Entry<Triple<String, DataverseName, String>, Pair<DataSourceScanOperator, Set<List<String>>>> entry : dataSourceFieldNamesMap + for (CBOJoinPlanNode joinPlanNode : planStateTree.getCboPlanNode().getJoins()) { + + for (JoinFilterCondition filterCondition : joinPlanNode.getJoinCondition().joinFilterConditions()) { + LogicalVariable lhsVar = filterCondition.getLhsVar(); + DataSourceScanOperator lhsOp = planStateTree.getDataSourceScanVariableMap().get(lhsVar); + if (lhsOp == null) { + continue; + } + DataSource lhsDataSource = (DataSource) lhsOp.getDataSource(); + String lhsDatabaseName = lhsDataSource.getId().getDatabaseName(); + DataverseName lhsDataverseName = lhsDataSource.getId().getDataverseName(); + String lhsDatasetName = lhsDataSource.getId().getDatasourceName(); + joinDataSourceFieldNamesMap.putIfAbsent(new Triple<>(lhsDatabaseName, lhsDataverseName, lhsDatasetName), + new HashSet<>()); + joinDataSourceFieldNamesMap.get(new Triple<>(lhsDatabaseName, lhsDataverseName, lhsDatasetName)) + .add(filterCondition.getLhsFields()); + + LogicalVariable rhsVar = filterCondition.getRhsVar(); + DataSourceScanOperator rhsOp = planStateTree.getDataSourceScanVariableMap().get(rhsVar); + if (rhsOp == null) { + continue; + } + DataSource rhsDataSource = (DataSource) rhsOp.getDataSource(); + String rhsDatabaseName = rhsDataSource.getId().getDatabaseName(); + DataverseName rhsDataverseName = rhsDataSource.getId().getDataverseName(); + String rhsDatasetName = rhsDataSource.getId().getDatasourceName(); + joinDataSourceFieldNamesMap.putIfAbsent(new Triple<>(rhsDatabaseName, rhsDataverseName, rhsDatasetName), + new HashSet<>()); + joinDataSourceFieldNamesMap.get(new Triple<>(rhsDatabaseName, rhsDataverseName, rhsDatasetName)) + .add(filterCondition.getRhsFields()); + + } + + } + + for (Map.Entry<Triple<String, DataverseName, String>, Pair<DataSourceScanOperator, Set<List<String>>>> entry : singleDataSourceFieldNamesMap .entrySet()) { Triple<String, DataverseName, String> key = entry.getKey(); Set<List<String>> fieldNames = entry.getValue().getSecond(); @@ -80,7 +116,7 @@ ((InternalDatasetDetails) ((DatasetDataSource) scanOperator.getDataSource()).getDataset() .getDatasetDetails()).getPrimaryKey(); - datasetIndexesMap.put(key, new HashMap<>()); + filterIndexesMap.put(key, new HashMap<>()); String databaseName = key.first; DataverseName dataverseName = key.second; @@ -89,9 +125,9 @@ FakeIndex primIndex = new FakeIndex(databaseName, dataverseName, datasetName, primaryKeyName, primaryKeys, true); - datasetIndexesMap.get(key).put(primaryKeyName, primIndex); + filterIndexesMap.get(key).put(primaryKeyName, primIndex); - IIndexEnumerator indexEnumerator = IIndexEnumerator.ONLY_ALPHABETIC; + IIndexEnumerator indexEnumerator = IIndexEnumerator.alphabeticEnumerator(); indexEnumerator.init(fieldNames); Iterator<List<List<String>>> itr = indexEnumerator.getIterator(); @@ -99,21 +135,39 @@ String indexName = "fake_index_" + randomUUID(); FakeIndex fakeIndex = new FakeIndex(databaseName, dataverseName, datasetName, indexName, itr.next(), false); - datasetIndexesMap.get(key).put(indexName, fakeIndex); + filterIndexesMap.get(key).put(indexName, fakeIndex); } } + + for (Map.Entry<Triple<String, DataverseName, String>, Set<List<String>>> entry : joinDataSourceFieldNamesMap + .entrySet()) { + Triple<String, DataverseName, String> key = entry.getKey(); + Set<List<String>> fieldNames = entry.getValue(); + + IIndexEnumerator indexEnumerator = IIndexEnumerator.alphabeticEnumerator(); + indexEnumerator.init(fieldNames); + Iterator<List<List<String>>> itr = indexEnumerator.getIterator(); + + while (itr.hasNext()) { + String indexName = "fake_join_index_" + randomUUID(); + FakeIndex fakeIndex = new FakeIndex(key.first, key.second, key.third, indexName, itr.next(), false); + filterIndexesMap.get(key).put(indexName, fakeIndex); + } + + } + } @Override public Index getIndex(String database, DataverseName dataverseName, String datasetName, String indexName) throws AlgebricksException { - return datasetIndexesMap.get(new Triple<>(database, dataverseName, datasetName)).get(indexName); + return filterIndexesMap.get(new Triple<>(database, dataverseName, datasetName)).get(indexName); } @Override public List<Index> getDatasetIndexes(String database, DataverseName dataverseName, String datasetName) throws AlgebricksException { - return datasetIndexesMap.get(new Triple<>(database, dataverseName, datasetName)).values().stream().toList(); + return filterIndexesMap.get(new Triple<>(database, dataverseName, datasetName)).values().stream().toList(); } } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FilterConditionParser.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FilterConditionParser.java index 656951d..3147746 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FilterConditionParser.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FilterConditionParser.java @@ -27,24 +27,26 @@ import org.apache.asterix.om.functions.BuiltinFunctions; import org.apache.asterix.optimizer.rules.am.BTreeAccessMethod; import org.apache.commons.lang3.mutable.Mutable; -import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; import org.apache.hyracks.algebricks.common.utils.Pair; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator; import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag; import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; +import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression; import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression; import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression; +import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression; import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator; +import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator; import org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil; public class FilterConditionParser { - public static ScanFilter parseScanNode(ILogicalOperator op) throws AlgebricksException { + public static ScanFilter parseScanNode(ILogicalOperator op) { List<Mutable<ILogicalExpression>> filterExprs = new ArrayList<>(); ILogicalOperator tempOp = op; @@ -69,15 +71,7 @@ tempOp = op; do { if (tempOp.getOperatorTag() == LogicalOperatorTag.ASSIGN) { - AssignOperator assignOperator = (AssignOperator) tempOp; - for (Mutable<ILogicalExpression> filterExpr : filterExprs) { - for (int i = 0; i < assignOperator.getVariables().size(); i++) { - OperatorManipulationUtil.replaceVarWithExpr( - (AbstractFunctionCallExpression) filterExpr.getValue(), - assignOperator.getVariables().get(i), - assignOperator.getExpressions().get(i).getValue()); - } - } + replaceExprsWithAssign((AssignOperator) tempOp, filterExprs); } tempOp = tempOp.getInputs().getFirst().getValue(); } while (tempOp.hasInputs()); @@ -85,8 +79,7 @@ List<ScanFilterCondition> filterConditions = new ArrayList<>(); for (Mutable<ILogicalExpression> filterExpr : filterExprs) { - ScanFilterCondition filterCondition = - parseCondition((AbstractFunctionCallExpression) filterExpr.getValue()); + ScanFilterCondition filterCondition = parseCondition(filterExpr.getValue()); if (filterCondition != null) { filterConditions.add(filterCondition); } @@ -95,7 +88,10 @@ return new ScanFilter(filterConditions); } - private static ScanFilterCondition parseCondition(AbstractFunctionCallExpression expr) throws AlgebricksException { + private static ScanFilterCondition parseCondition(ILogicalExpression logicalExpression) { + if(!(logicalExpression instanceof AbstractFunctionCallExpression expr)) { + return null; + } FunctionIdentifier fi = expr.getFunctionIdentifier(); @@ -109,44 +105,108 @@ return null; } - List<String> lhs = parseLHS(expr.getArguments().get(0).getValue()); + Pair<LogicalVariable,List<String>> accessPath = parseAccessPath(expr.getArguments().get(0).getValue()); - if (lhs == null) { + if (accessPath == null) { return null; } - return new ScanFilterCondition(fi, lhs, (ConstantExpression) constantExpression); + return new ScanFilterCondition(fi, accessPath.getSecond(), (ConstantExpression) constantExpression); } - private static List<String> parseLHS(ILogicalExpression expr) throws AlgebricksException { - + private static Pair<LogicalVariable, List<String>> parseAccessPath(ILogicalExpression expr) { List<String> fieldNames = new LinkedList<>(); - while (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) { - if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { return null; } - ScalarFunctionCallExpression functionCallExpr = (ScalarFunctionCallExpression) expr; FunctionIdentifier fi = functionCallExpr.getFunctionIdentifier(); if (fi != BuiltinFunctions.FIELD_ACCESS_BY_NAME) { return null; } - String fieldName = ((AString) ((AsterixConstantValue) ((ConstantExpression) functionCallExpr.getArguments() .get(1).getValue()).getValue()).getObject()).getStringValue(); fieldNames.addFirst(fieldName); expr = functionCallExpr.getArguments().get(0).getValue(); - } - return fieldNames; + + VariableReferenceExpression varRef = (VariableReferenceExpression) expr; + LogicalVariable var = varRef.getVariableReference(); + return new Pair<>(var, fieldNames); } public static JoinFilter parseJoinNode(AbstractBinaryJoinOperator joinOp) { - List<Mutable<ILogicalExpression>> filterExprs = new ArrayList<>(); + List<Mutable<ILogicalExpression>> joinExprs = new ArrayList<>(); - return null; + ILogicalExpression joinExpression = joinOp.getCondition().getValue(); + List<Mutable<ILogicalExpression>> conjs = new ArrayList<>(); + if (joinExpression.splitIntoConjuncts(conjs)) { + joinExprs.addAll(conjs); + } else { + joinExprs.add(joinOp.getCondition()); + } + joinExprs = OperatorManipulationUtil.cloneExpressions(joinExprs); + traverseAndReplace(joinOp, joinExprs); + + List<JoinFilterCondition> joinConditions = new ArrayList<>(); + + for (Mutable<ILogicalExpression> joinExpr : joinExprs) { + JoinFilterCondition joinCondition = parseJoinCondition(joinExpr.getValue()); + if (joinCondition != null) { + joinConditions.add(joinCondition); + } + } + + return new JoinFilter(joinConditions); } + + private static void traverseAndReplace(AbstractLogicalOperator op, List<Mutable<ILogicalExpression>> exprs) { + + if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) { + replaceExprsWithAssign((AssignOperator) op, exprs); + } + + for (Mutable<ILogicalOperator> input : op.getInputs()) { + traverseAndReplace((AbstractLogicalOperator) input.getValue(), exprs); + } + + } + + public static void replaceExprsWithAssign(AssignOperator assignOp, List<Mutable<ILogicalExpression>> exprs) { + for (Mutable<ILogicalExpression> filterExpr : exprs) { + for (int i = 0; i < assignOp.getVariables().size(); i++) { + OperatorManipulationUtil.replaceVarWithExpr((AbstractFunctionCallExpression) filterExpr.getValue(), + assignOp.getVariables().get(i), assignOp.getExpressions().get(i).getValue()); + } + } + } + + public static JoinFilterCondition parseJoinCondition(ILogicalExpression logicalExpression) { + + if(!(logicalExpression instanceof AbstractFunctionCallExpression expr)) { + return null; + } + + FunctionIdentifier fi = expr.getFunctionIdentifier(); + + if (!BTreeAccessMethod.INSTANCE.getOptimizableFunctions().contains(new Pair<>(fi, false))) { + return null; + } + + ILogicalExpression lhs = expr.getArguments().get(0).getValue(); + ILogicalExpression rhs = expr.getArguments().get(1).getValue(); + + Pair<LogicalVariable,List<String>> lhsAccessPath = parseAccessPath(lhs); + if (lhsAccessPath == null) { + return null; + } + Pair<LogicalVariable,List<String>> rhsAccessPath = parseAccessPath(rhs); + if (rhsAccessPath == null) { + return null; + } + return new JoinFilterCondition(fi, lhsAccessPath.getFirst() ,lhsAccessPath.getSecond(), rhsAccessPath.getFirst(), rhsAccessPath.getSecond()); + } + } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/IIndexEnumerator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/IIndexEnumerator.java index 7eceb18..d554e83 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/IIndexEnumerator.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/IIndexEnumerator.java @@ -31,45 +31,50 @@ void init(Collection<List<String>> fieldNames); - IIndexEnumerator ONLY_ALL_FIELDS = new IIndexEnumerator() { - private PermutationIterator<List<String>> permutationIterator; + static IIndexEnumerator allFieldsEnumerator() { - @Override - public Iterator<List<List<String>>> getIterator() { - return permutationIterator; - } + return new IIndexEnumerator() { + private PermutationIterator<List<String>> permutationIterator; - @Override - public void init(Collection<List<String>> fieldNames) { - this.permutationIterator = new PermutationIterator<>(new ArrayList<>(fieldNames)); - } - }; + @Override + public Iterator<List<List<String>>> getIterator() { + return permutationIterator; + } - IIndexEnumerator ONLY_ALPHABETIC = new IIndexEnumerator() { - private List<List<String>> listOfAllFields; + @Override + public void init(Collection<List<String>> fieldNames) { + this.permutationIterator = new PermutationIterator<>(new ArrayList<>(fieldNames)); + } + }; + } - @Override - public Iterator<List<List<String>>> getIterator() { - ArrayList<List<List<String>>> list = new ArrayList<>(); - list.add(listOfAllFields); - return list.iterator(); - } + static IIndexEnumerator alphabeticEnumerator() { + return new IIndexEnumerator() { + private List<List<String>> listOfAllFields; - @Override - public void init(Collection<List<String>> fieldNames) { - this.listOfAllFields = new ArrayList<>(fieldNames); - listOfAllFields.sort((list1, list2) -> { - int minSize = Math.min(list1.size(), list2.size()); - for (int i = 0; i < minSize; i++) { - int comparison = list1.get(i).compareTo(list2.get(i)); - if (comparison != 0) { - return comparison; + @Override + public Iterator<List<List<String>>> getIterator() { + ArrayList<List<List<String>>> list = new ArrayList<>(); + list.add(listOfAllFields); + return list.iterator(); + } + + @Override + public void init(Collection<List<String>> fieldNames) { + this.listOfAllFields = new ArrayList<>(fieldNames); + listOfAllFields.sort((list1, list2) -> { + int minSize = Math.min(list1.size(), list2.size()); + for (int i = 0; i < minSize; i++) { + int comparison = list1.get(i).compareTo(list2.get(i)); + if (comparison != 0) { + return comparison; + } } - } - return Integer.compare(list1.size(), list2.size()); - }); + return Integer.compare(list1.size(), list2.size()); + }); - } - }; + } + }; + } } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilter.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilter.java index e38b6f4..d4e96a4 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilter.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilter.java @@ -20,8 +20,5 @@ import java.util.List; -public class JoinFilter { - - private List<JoinFilterCondition> joinFilterConditions; - +public record JoinFilter(List<JoinFilterCondition> joinFilterConditions) { } diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilterCondition.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilterCondition.java index 3e493eb..252ffd4 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilterCondition.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/JoinFilterCondition.java @@ -20,26 +20,40 @@ import java.util.List; +import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; public class JoinFilterCondition { private FunctionIdentifier fi; - private List<String> lhsFieldAccessPath; - private List<String> rhsFieldAccessPath; + private List<String> lhsFields; + private List<String> rhsFields; - public JoinFilterCondition(FunctionIdentifier fi, List<String> lhsFieldAccessPath, - List<String> rhsFieldAccessPath) { + private LogicalVariable lhsVar; + private LogicalVariable rhsVar; + + public JoinFilterCondition(FunctionIdentifier fi, LogicalVariable lhsVar, List<String> lhsFields, + LogicalVariable rhsVar, List<String> rhsFields) { this.fi = fi; - this.lhsFieldAccessPath = lhsFieldAccessPath; - this.rhsFieldAccessPath = rhsFieldAccessPath; + this.lhsFields = lhsFields; + this.rhsFields = rhsFields; + this.lhsVar = lhsVar; + this.rhsVar = rhsVar; } - public List<String> getLhsFieldAccessPath() { - return lhsFieldAccessPath; + public List<String> getLhsFields() { + return lhsFields; } - public List<String> getRhsFieldAccessPath() { - return rhsFieldAccessPath; + public List<String> getRhsFields() { + return rhsFields; + } + + public LogicalVariable getLhsVar() { + return lhsVar; + } + + public LogicalVariable getRhsVar() { + return rhsVar; } } diff --git a/asterixdb/asterix-app/pom.xml b/asterixdb/asterix-app/pom.xml index d2301a3..fae61c3 100644 --- a/asterixdb/asterix-app/pom.xml +++ b/asterixdb/asterix-app/pom.xml @@ -704,7 +704,7 @@ <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> - <version>1.13.4</version> + <version>1.15.1</version> <configuration> <nodeVersion>v14.15.4</nodeVersion> <npmVersion>6.14.11</npmVersion> diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java index ff33fd0..d34eccd 100644 --- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java +++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppExecutionTest.java @@ -67,7 +67,6 @@ @Test public void test() throws Exception { - LangExecutionUtil.test(tcCtx); } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cbo-join/index-advisor/simple-advise/simple-advise.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cbo-join/index-advisor/simple-advise/simple-advise.1.ddl.sqlpp index caeb0ed..18cf0e6 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cbo-join/index-advisor/simple-advise/simple-advise.1.ddl.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cbo-join/index-advisor/simple-advise/simple-advise.1.ddl.sqlpp @@ -25,4 +25,4 @@ CREATE DATASET A PRIMARY KEY ( a_0 : integer); CREATE DATASET B PRIMARY KEY ( b_0 : integer); -CREATE INDEX idx_a_0 ON A(a_1); \ No newline at end of file +CREATE INDEX idx_a_1 ON A(a_1); \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise/simple-advise.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise/simple-advise.4.adm index e3f0f4b..a47f9a3 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise/simple-advise.4.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise/simple-advise.4.adm @@ -1 +1 @@ -[{"#operator":"Advise","advice":{"#operator":"IndexAdvice","adviseinfo":{"current_indexes":[],"recommended_indexes":{"recommended_indexes":[{"index_statement":"CREATE INDEX idx_a_1 ON Default.test.A(a_1);"}]}}}}] \ No newline at end of file +[{"#operator":"Advise","advice":{"#operator":"IndexAdvice","adviseinfo":{"current_indexes":[{"index_statement":"CREATE INDEX idx_a_1 ON Default.test.A(a_1);"}],"recommended_indexes":{"indexes":[]}}}}] \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise1/simple-advise1.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise1/simple-advise1.4.adm index 8fca143..eebe476 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise1/simple-advise1.4.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise1/simple-advise1.4.adm @@ -1 +1 @@ -[{"#operator":"Advise","advice":{"#operator":"IndexAdvice","adviseinfo":{"current_indexes":[],"recommended_indexes":{"recommended_indexes":[{"index_statement":"CREATE INDEX idx_b ON Default.test.A(b);"}]}}}}] \ No newline at end of file +[{"#operator":"Advise","advice":{"#operator":"IndexAdvice","adviseinfo":{"current_indexes":[],"recommended_indexes":{"indexes":[{"index_statement":"CREATE INDEX idx_b ON Default.test.A(b);"}]}}}}] \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise2/simple-advise2.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise2/simple-advise2.4.adm index e936c07..8cf3680 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise2/simple-advise2.4.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/cbo-join/index-advisor/simple-advise2/simple-advise2.4.adm @@ -1 +1 @@ -[{"#operator":"Advise","advice":{"#operator":"IndexAdvice","adviseinfo":{"current_indexes":[],"recommended_indexes":{"recommended_indexes":[{"index_statement":"CREATE INDEX idx_a0__a1__a2 ON Default.test.A(a0,a1,a2);"}]}}}}] \ No newline at end of file +[{"#operator":"Advise","advice":{"#operator":"IndexAdvice","adviseinfo":{"current_indexes":[],"recommended_indexes":{"indexes":[{"index_statement":"CREATE INDEX idx_a0__a1__a2 ON Default.test.A(a0,a1,a2);"}]}}}}] \ No newline at end of file diff --git a/asterixdb/asterix-cloud/pom.xml b/asterixdb/asterix-cloud/pom.xml index efe8673..9c37753 100644 --- a/asterixdb/asterix-cloud/pom.xml +++ b/asterixdb/asterix-cloud/pom.xml @@ -173,7 +173,7 @@ <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> - <version>1.13.4</version> + <version>1.15.1</version> <configuration> <nodeVersion>v14.15.4</nodeVersion> <npmVersion>6.14.11</npmVersion> diff --git a/asterixdb/asterix-dashboard/pom.xml b/asterixdb/asterix-dashboard/pom.xml index f73653f..e0fbf14 100644 --- a/asterixdb/asterix-dashboard/pom.xml +++ b/asterixdb/asterix-dashboard/pom.xml @@ -66,7 +66,7 @@ <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> - <version>1.11.0</version> + <version>1.15.1</version> <configuration> <nodeVersion>v14.15.4</nodeVersion> <npmVersion>6.14.11</npmVersion> diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java index 66f5cb7..4a60d78 100644 --- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java +++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java @@ -92,7 +92,7 @@ indexNode.put("index_statement", advise.getCreateIndexClause()); recommendedIndexNode.add(indexNode); } - recommendedNode.put("recommended_indexes", recommendedIndexNode); + recommendedNode.put("indexes", recommendedIndexNode); adviseInfo.put("current_indexes", currentIndexNode); adviseInfo.put("recommended_indexes", recommendedNode); adviceNode.put("adviseinfo", adviseInfo); -- To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20133 To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Change-Id: I1b2e6f645f2d4c28d6b8233eabec60805a4222ce Gerrit-Change-Number: 20133 Gerrit-PatchSet: 1 Gerrit-Owner: Preetham Poluparthi <preetha...@apache.org> Gerrit-MessageType: newchange