>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

Reply via email to