Merge commit '8930f0d' from stabilization-f69489

Change-Id: I64cf862bc5ebe19a24acbccf821f68556699222e
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
index 318b18c..5b1ed0f 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
@@ -255,7 +255,6 @@
         // The following rule should be fired after PushAggregateIntoNestedSubplanRule because
         // pulling invariants out of a subplan will make PushAggregateIntoGroupby harder.
         condPushDownAndJoinInference.add(new AsterixMoveFreeVariableOperatorOutOfSubplanRule());
-        // once meta() is replaced before logical plan generation, this can be removed
         condPushDownAndJoinInference.add(new MetaFunctionToMetaVariableRule());
         return condPushDownAndJoinInference;
     }
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
index c8bec85..d232ce0 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
@@ -34,7 +34,9 @@
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.dataflow.data.common.ExpressionTypeComputer;
 import org.apache.asterix.metadata.declared.MetadataProvider;
+import org.apache.asterix.metadata.entities.Dataset;
 import org.apache.asterix.metadata.entities.Index;
+import org.apache.asterix.metadata.utils.DatasetUtil;
 import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.AOrderedList;
 import org.apache.asterix.om.base.AString;
@@ -51,6 +53,7 @@
 import org.apache.asterix.optimizer.base.AnalysisUtil;
 import org.apache.asterix.optimizer.rules.am.OptimizableOperatorSubTree.DataSourceType;
 import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableInt;
 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;
@@ -533,17 +536,20 @@
      */
     protected boolean fillIndexExprs(List<Index> datasetIndexes, List<String> fieldName, IAType fieldType,
             IOptimizableFuncExpr optFuncExpr, int matchedFuncExprIndex, int varIdx,
-            OptimizableOperatorSubTree matchedSubTree, AccessMethodAnalysisContext analysisCtx)
+            OptimizableOperatorSubTree matchedSubTree, AccessMethodAnalysisContext analysisCtx, int fieldSource)
             throws AlgebricksException {
         List<Index> indexCandidates = new ArrayList<>();
         // Add an index to the candidates if one of the indexed fields is fieldName
         for (Index index : datasetIndexes) {
             // Need to also verify the index is pending no op
-            if (index.getKeyFieldNames().contains(fieldName) && index.getPendingOp() == MetadataUtil.PENDING_NO_OP) {
+            int keyIdx = index.getKeyFieldNames().indexOf(fieldName);
+            List<Integer> keySources = index.getKeyFieldSourceIndicators();
+            if (keyIdx >= 0 && keySourceMatches(keySources, keyIdx, fieldSource)
+                    && index.getPendingOp() == MetadataUtil.PENDING_NO_OP) {
                 indexCandidates.add(index);
                 boolean isFieldTypeUnknown = fieldType == BuiltinType.AMISSING || fieldType == BuiltinType.ANY;
                 if (isFieldTypeUnknown && (!index.isOverridingKeyFieldTypes() || index.isEnforced())) {
-                    IAType indexedType = index.getKeyFieldTypes().get(index.getKeyFieldNames().indexOf(fieldName));
+                    IAType indexedType = index.getKeyFieldTypes().get(keyIdx);
                     optFuncExpr.setFieldType(varIdx, indexedType);
                 }
                 analysisCtx.addIndexExpr(matchedSubTree.getDataset(), index, matchedFuncExprIndex, varIdx);
@@ -556,6 +562,11 @@
         return true;
     }
 
+    private static boolean keySourceMatches(List<Integer> keySources, int keyIdx, int fieldSource) {
+        // TODO(ali): keySources from Index should not be null. should investigate if it can happen (ie on external ds)
+        return keySources == null ? fieldSource == 0 : keySources.get(keyIdx) == fieldSource;
+    }
+
     protected void fillAllIndexExprs(OptimizableOperatorSubTree subTree, AccessMethodAnalysisContext analysisCtx,
             IOptimizationContext context) throws AlgebricksException {
         int optFuncExprIndex = 0;
@@ -624,6 +635,7 @@
         // Remember matching subtree.
         optFuncExpr.setOptimizableSubTree(funcVarIndex, subTree);
         List<String> fieldName = null;
+        MutableInt fieldSource = new MutableInt(0);
         if (subTree.getDataSourceType() == DataSourceType.COLLECTION_SCAN) {
             VariableReferenceExpression varRef = new VariableReferenceExpression(var);
             varRef.setSourceLocation(unnestOp.getSourceLocation());
@@ -631,7 +643,7 @@
         } else {
             fieldName = getFieldNameFromSubTree(optFuncExpr, subTree, assignOrUnnestIndex, 0, subTree.getRecordType(),
                     funcVarIndex, optFuncExpr.getFuncExpr().getArguments().get(funcVarIndex).getValue(),
-                    subTree.getMetaRecordType(), datasetMetaVar);
+                    subTree.getMetaRecordType(), datasetMetaVar, fieldSource);
             if (fieldName.isEmpty()) {
                 return;
             }
@@ -640,13 +652,13 @@
                 (IAType) context.getOutputTypeEnvironment(unnestOp).getType(optFuncExpr.getLogicalExpr(funcVarIndex));
         // Set the fieldName in the corresponding matched function
         // expression.
-        optFuncExpr.setFieldName(funcVarIndex, fieldName);
+        optFuncExpr.setFieldName(funcVarIndex, fieldName, fieldSource.intValue());
         optFuncExpr.setFieldType(funcVarIndex, fieldType);
 
         setTypeTag(context, subTree, optFuncExpr, funcVarIndex);
         if (subTree.hasDataSource()) {
             fillIndexExprs(datasetIndexes, fieldName, fieldType, optFuncExpr, optFuncExprIndex, funcVarIndex, subTree,
-                    analysisCtx);
+                    analysisCtx, fieldSource.intValue());
         }
     }
 
@@ -655,6 +667,7 @@
             IOptimizationContext context, List<Index> datasetIndexes, int optFuncExprIndex,
             AccessMethodAnalysisContext analysisCtx) throws AlgebricksException {
         List<LogicalVariable> varList = assignOp.getVariables();
+        MutableInt fieldSource = new MutableInt(0);
         for (int varIndex = 0; varIndex < varList.size(); varIndex++) {
             LogicalVariable var = varList.get(varIndex);
             int optVarIndex = optFuncExpr.findLogicalVar(var);
@@ -667,21 +680,22 @@
             // Remember matching subtree.
             optFuncExpr.setOptimizableSubTree(optVarIndex, subTree);
 
+            fieldSource.setValue(0);
             List<String> fieldName = getFieldNameFromSubTree(optFuncExpr, subTree, assignOrUnnestIndex, varIndex,
                     subTree.getRecordType(), optVarIndex,
                     optFuncExpr.getFuncExpr().getArguments().get(optVarIndex).getValue(), subTree.getMetaRecordType(),
-                    datasetMetaVar);
+                    datasetMetaVar, fieldSource);
 
             IAType fieldType = (IAType) context.getOutputTypeEnvironment(assignOp).getVarType(var);
             // Set the fieldName in the corresponding matched
             // function expression.
-            optFuncExpr.setFieldName(optVarIndex, fieldName);
+            optFuncExpr.setFieldName(optVarIndex, fieldName, fieldSource.intValue());
             optFuncExpr.setFieldType(optVarIndex, fieldType);
 
             setTypeTag(context, subTree, optFuncExpr, optVarIndex);
             if (subTree.hasDataSource()) {
                 fillIndexExprs(datasetIndexes, fieldName, fieldType, optFuncExpr, optFuncExprIndex, optVarIndex,
-                        subTree, analysisCtx);
+                        subTree, analysisCtx, fieldSource.intValue());
             }
         }
     }
@@ -690,6 +704,7 @@
             List<Index> datasetIndexes, List<LogicalVariable> dsVarList, OptimizableOperatorSubTree subTree,
             AccessMethodAnalysisContext analysisCtx, IOptimizationContext context, boolean fromAdditionalDataSource)
             throws AlgebricksException {
+        MutableInt mutableFieldSource = new MutableInt(0);
         for (int varIndex = 0; varIndex < dsVarList.size(); varIndex++) {
             LogicalVariable var = dsVarList.get(varIndex);
             int funcVarIndex = optFuncExpr.findLogicalVar(var);
@@ -701,28 +716,39 @@
             List<String> fieldName = null;
             IAType fieldType = null;
             List<List<String>> subTreePKs = null;
+            mutableFieldSource.setValue(0);
 
             if (!fromAdditionalDataSource) {
-                subTreePKs = subTree.getDataset().getPrimaryKeys();
+                Dataset dataset = subTree.getDataset();
+                subTreePKs = dataset.getPrimaryKeys();
                 // Check whether this variable is PK, not a record variable.
                 if (varIndex <= subTreePKs.size() - 1) {
                     fieldName = subTreePKs.get(varIndex);
                     fieldType = (IAType) context.getOutputTypeEnvironment(subTree.getDataSourceRef().getValue())
                             .getVarType(var);
+                    List<Integer> keySourceIndicators = DatasetUtil.getKeySourceIndicators(dataset);
+                    if (keySourceIndicators != null) {
+                        mutableFieldSource.setValue(keySourceIndicators.get(varIndex));
+                    }
                 }
             } else {
                 // Need to check additional dataset one by one
                 for (int i = 0; i < subTree.getIxJoinOuterAdditionalDatasets().size(); i++) {
-                    if (subTree.getIxJoinOuterAdditionalDatasets().get(i) != null) {
-                        subTreePKs = subTree.getIxJoinOuterAdditionalDatasets().get(i).getPrimaryKeys();
-
+                    Dataset dataset = subTree.getIxJoinOuterAdditionalDatasets().get(i);
+                    if (dataset != null) {
+                        subTreePKs = dataset.getPrimaryKeys();
                         // Check whether this variable is PK, not a record variable.
+                        // TODO(ali): investigate why var (LogicalVariable) is looked up in subTreePKs (List<List<str>>)
                         if (subTreePKs.contains(var) && varIndex <= subTreePKs.size() - 1) {
                             fieldName = subTreePKs.get(varIndex);
                             fieldType = (IAType) context
                                     .getOutputTypeEnvironment(
                                             subTree.getIxJoinOuterAdditionalDataSourceRefs().get(i).getValue())
                                     .getVarType(var);
+                            List<Integer> keySourceIndicators = DatasetUtil.getKeySourceIndicators(dataset);
+                            if (keySourceIndicators != null) {
+                                mutableFieldSource.setValue(keySourceIndicators.get(varIndex));
+                            }
                             break;
                         }
                     }
@@ -730,7 +756,8 @@
             }
             // Set the fieldName in the corresponding matched function
             // expression, and remember matching subtree.
-            optFuncExpr.setFieldName(funcVarIndex, fieldName);
+            int fieldSource = mutableFieldSource.intValue();
+            optFuncExpr.setFieldName(funcVarIndex, fieldName, fieldSource);
             optFuncExpr.setOptimizableSubTree(funcVarIndex, subTree);
             optFuncExpr.setSourceVar(funcVarIndex, var);
             VariableReferenceExpression varRef = new VariableReferenceExpression(var);
@@ -739,7 +766,7 @@
             setTypeTag(context, subTree, optFuncExpr, funcVarIndex);
             if (subTree.hasDataSourceScan()) {
                 fillIndexExprs(datasetIndexes, fieldName, fieldType, optFuncExpr, optFuncExprIndex, funcVarIndex,
-                        subTree, analysisCtx);
+                        subTree, analysisCtx, fieldSource);
             }
         }
     }
@@ -761,7 +788,7 @@
      */
     protected List<String> getFieldNameFromSubTree(IOptimizableFuncExpr optFuncExpr, OptimizableOperatorSubTree subTree,
             int opIndex, int assignVarIndex, ARecordType recordType, int funcVarIndex,
-            ILogicalExpression parentFuncExpr, ARecordType metaType, LogicalVariable metaVar)
+            ILogicalExpression parentFuncExpr, ARecordType metaType, LogicalVariable metaVar, MutableInt fieldSource)
             throws AlgebricksException {
         // Get expression corresponding to opVar at varIndex.
         AbstractLogicalExpression expr = null;
@@ -830,6 +857,11 @@
         if (isFieldAccess) {
             LogicalVariable sourceVar =
                     ((VariableReferenceExpression) funcExpr.getArguments().get(0).getValue()).getVariableReference();
+            if (sourceVar.equals(metaVar)) {
+                fieldSource.setValue(1);
+            } else {
+                fieldSource.setValue(0);
+            }
             if (optFuncExpr != null) {
                 optFuncExpr.setLogicalExpr(funcVarIndex, parentFuncExpr);
             }
@@ -870,7 +902,7 @@
                 //Recursive call on nested assign
                 List<String> parentFieldNames = getFieldNameFromSubTree(optFuncExpr, subTree,
                         assignAndExpressionIndexes[0], assignAndExpressionIndexes[1], recordType, funcVarIndex,
-                        parentFuncExpr, metaType, metaVar);
+                        parentFuncExpr, metaType, metaVar, fieldSource);
 
                 if (parentFieldNames.isEmpty()) {
                     //Nested assign was not a field access.
@@ -946,7 +978,7 @@
                     if (var.equals(curVar) && optFuncExpr != null) {
                         optFuncExpr.setSourceVar(funcVarIndex, var);
                         return getFieldNameFromSubTree(optFuncExpr, subTree, assignOrUnnestIndex, varIndex, recordType,
-                                funcVarIndex, childFuncExpr, metaType, metaVar);
+                                funcVarIndex, childFuncExpr, metaType, metaVar, fieldSource);
                     }
                 }
             } else {
@@ -954,7 +986,7 @@
                 LogicalVariable var = unnestOp.getVariable();
                 if (var.equals(curVar)) {
                     getFieldNameFromSubTree(optFuncExpr, subTree, assignOrUnnestIndex, 0, recordType, funcVarIndex,
-                            childFuncExpr, metaType, metaVar);
+                            childFuncExpr, metaType, metaVar, fieldSource);
                 }
             }
         }
@@ -973,6 +1005,7 @@
                 datasetMetaVar = datasetVars.get(datasetVars.size() - 1);
             }
         }
+        MutableInt fieldSource = new MutableInt(0);
         for (int assignOrUnnestIndex = 0; assignOrUnnestIndex < subTree.getAssignsAndUnnests()
                 .size(); assignOrUnnestIndex++) {
             AbstractLogicalOperator op = subTree.getAssignsAndUnnests().get(assignOrUnnestIndex);
@@ -983,8 +1016,10 @@
                     LogicalVariable var = varList.get(varIndex);
                     // funcVarIndex is not required. Thus, we set it to -1.
                     // optFuncExpr and parentFuncExpr are not required, too. Thus, we set them to null.
+                    fieldSource.setValue(0);
                     List<String> fieldName = getFieldNameFromSubTree(null, subTree, assignOrUnnestIndex, varIndex,
-                            subTree.getRecordType(), -1, null, subTree.getMetaRecordType(), datasetMetaVar);
+                            subTree.getRecordType(), -1, null, subTree.getMetaRecordType(), datasetMetaVar,
+                            fieldSource);
                     if (fieldName != null && !fieldName.isEmpty()) {
                         subTree.getVarsToFieldNameMap().put(var, fieldName);
                     }
@@ -996,8 +1031,9 @@
                 if (subTree.getDataSourceType() != DataSourceType.COLLECTION_SCAN) {
                     // funcVarIndex is not required. Thus, we set it to -1.
                     // optFuncExpr and parentFuncExpr are not required, too. Thus, we set them to null.
+                    fieldSource.setValue(0);
                     fieldName = getFieldNameFromSubTree(null, subTree, assignOrUnnestIndex, 0, subTree.getRecordType(),
-                            -1, null, subTree.getMetaRecordType(), datasetMetaVar);
+                            -1, null, subTree.getMetaRecordType(), datasetMetaVar, fieldSource);
                     if (fieldName != null && !fieldName.isEmpty()) {
                         subTree.getVarsToFieldNameMap().put(var, fieldName);
                     }
@@ -1022,8 +1058,10 @@
                     LogicalVariable var = varList.get(varIndex);
                     // funcVarIndex is not required. Thus, we set it to -1.
                     // optFuncExpr and parentFuncExpr are not required, too. Thus, we set them to null.
+                    fieldSource.setValue(0);
                     List<String> fieldName = getFieldNameFromSubTree(null, subTree, assignOrUnnestIndex, varIndex,
-                            subTree.getRecordType(), -1, null, subTree.getMetaRecordType(), datasetMetaVar);
+                            subTree.getRecordType(), -1, null, subTree.getMetaRecordType(), datasetMetaVar,
+                            fieldSource);
                     if (fieldName != null && !fieldName.isEmpty()) {
                         subTree.getVarsToFieldNameMap().put(var, fieldName);
                     }
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
index 99412dd..85e0c72 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
@@ -351,10 +351,12 @@
         for (Pair<Integer, Integer> exprIndex : exprAndVarList) {
             // Position of the field of matchedFuncExprs.get(exprIndex) in the chosen index's indexed exprs.
             IOptimizableFuncExpr optFuncExpr = analysisCtx.getMatchedFuncExpr(exprIndex.first);
-            int keyPos = indexOf(optFuncExpr.getFieldName(0), chosenIndex.getKeyFieldNames());
+            int keyPos = indexOf(optFuncExpr.getFieldName(0), optFuncExpr.getFieldSource(0),
+                    chosenIndex.getKeyFieldNames(), chosenIndex.getKeyFieldSourceIndicators());
             if (keyPos < 0 && optFuncExpr.getNumLogicalVars() > 1) {
                 // If we are optimizing a join, the matching field may be the second field name.
-                keyPos = indexOf(optFuncExpr.getFieldName(1), chosenIndex.getKeyFieldNames());
+                keyPos = indexOf(optFuncExpr.getFieldName(1), optFuncExpr.getFieldSource(1),
+                        chosenIndex.getKeyFieldNames(), chosenIndex.getKeyFieldSourceIndicators());
             }
             if (keyPos < 0) {
                 throw CompilationException.create(ErrorCode.NO_INDEX_FIELD_NAME_FOR_GIVEN_FUNC_EXPR,
@@ -818,10 +820,11 @@
         }
     }
 
-    private <T> int indexOf(T value, List<T> coll) {
+    private static int indexOf(List<String> fieldName, int fieldSource, List<List<String>> keyNames,
+            List<Integer> keySources) {
         int i = 0;
-        for (T member : coll) {
-            if (member.equals(value)) {
+        for (List<String> keyName : keyNames) {
+            if (keyName.equals(fieldName) && keyMatches(keySources, i, fieldSource)) {
                 return i;
             }
             i++;
@@ -829,6 +832,10 @@
         return -1;
     }
 
+    private static boolean keyMatches(List<Integer> keySources, int keyIndex, int fieldSource) {
+        return keySources == null ? fieldSource == 0 : keySources.get(keyIndex) == fieldSource;
+    }
+
     private LimitType getLimitType(IOptimizableFuncExpr optFuncExpr, OptimizableOperatorSubTree probeSubTree) {
         ComparisonKind ck =
                 AlgebricksBuiltinFunctions.getComparisonType(optFuncExpr.getFuncExpr().getFunctionIdentifier());
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
index 05dc4a6..6278865 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
@@ -43,10 +43,12 @@
 
     public ILogicalExpression getLogicalExpr(int index);
 
-    public void setFieldName(int index, List<String> fieldName);
+    public void setFieldName(int index, List<String> fieldName, int fieldSource);
 
     public List<String> getFieldName(int index);
 
+    public int getFieldSource(int index);
+
     public void setFieldType(int index, IAType fieldName);
 
     public IAType getFieldType(int index);
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java
index 42af276..109812b 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceLSMComponentFilterRule.java
@@ -117,7 +117,9 @@
             for (int i = 0; i < analysisCtx.getMatchedFuncExprs().size(); i++) {
                 IOptimizableFuncExpr optFuncExpr = analysisCtx.getMatchedFuncExpr(i);
                 boolean found = findMacthedExprFieldName(optFuncExpr, op, dataset, recType, datasetIndexes, context);
-                if (found && optFuncExpr.getFieldName(0).equals(filterFieldName)) {
+                // the field name source should be from the dataset record, i.e. source should be == 0
+                if (found && optFuncExpr.getFieldName(0).equals(filterFieldName)
+                        && optFuncExpr.getFieldSource(0) == 0) {
                     optFuncExprs.add(optFuncExpr);
                 }
             }
@@ -500,12 +502,13 @@
                     if (funcVarIndex == -1) {
                         continue;
                     }
+                    // TODO(ali): this SQ NPE should be investigated
                     List<String> fieldName =
                             getFieldNameFromSubAssignTree(optFuncExpr, descendantOp, varIndex, recType).second;
                     if (fieldName == null) {
                         return false;
                     }
-                    optFuncExpr.setFieldName(funcVarIndex, fieldName);
+                    optFuncExpr.setFieldName(funcVarIndex, fieldName, 0);
                     return true;
                 }
             } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
@@ -522,7 +525,9 @@
                     if (fieldName == null) {
                         return false;
                     }
-                    optFuncExpr.setFieldName(funcVarIndex, fieldName);
+                    List<Integer> keySourceIndicators = DatasetUtil.getKeySourceIndicators(dataset);
+                    int keySource = getKeySource(keySourceIndicators, varIndex);
+                    optFuncExpr.setFieldName(funcVarIndex, fieldName, keySource);
                     return true;
                 }
             } else if (descendantOp.getOperatorTag() == LogicalOperatorTag.UNNEST_MAP) {
@@ -560,15 +565,19 @@
                     ARecordType metaRecType = (ARecordType) metaItemType;
                     int numSecondaryKeys = KeyFieldTypeUtil.getNumSecondaryKeys(index, recType, metaRecType);
                     List<String> fieldName;
+                    int keySource;
                     if (varIndex >= numSecondaryKeys) {
-                        fieldName = dataset.getPrimaryKeys().get(varIndex - numSecondaryKeys);
+                        int idx = varIndex - numSecondaryKeys;
+                        fieldName = dataset.getPrimaryKeys().get(idx);
+                        keySource = getKeySource(DatasetUtil.getKeySourceIndicators(dataset), idx);
                     } else {
                         fieldName = index.getKeyFieldNames().get(varIndex);
+                        keySource = getKeySource(index.getKeyFieldSourceIndicators(), varIndex);
                     }
                     if (fieldName == null) {
                         return false;
                     }
-                    optFuncExpr.setFieldName(funcVarIndex, fieldName);
+                    optFuncExpr.setFieldName(funcVarIndex, fieldName, keySource);
                     return true;
                 }
             }
@@ -581,6 +590,10 @@
         return false;
     }
 
+    private static int getKeySource(List<Integer> keySourceIndicators, int keyIdx) {
+        return keySourceIndicators == null ? 0 : keySourceIndicators.get(keyIdx);
+    }
+
     private Pair<ARecordType, List<String>> getFieldNameFromSubAssignTree(IOptimizableFuncExpr optFuncExpr,
             AbstractLogicalOperator op, int varIndex, ARecordType recType) {
         AbstractLogicalExpression expr = null;
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java
index 1389f5e..7b04340 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java
@@ -37,6 +37,7 @@
     protected final LogicalVariable[] sourceVars;
     protected final ILogicalExpression[] logicalExprs;
     protected final List<List<String>> fieldNames;
+    protected final int[] fieldSources;
     protected final IAType[] fieldTypes;
     protected final OptimizableOperatorSubTree[] subTrees;
     protected final ILogicalExpression[] constantExpressions;
@@ -51,6 +52,7 @@
         this.logicalExprs = new ILogicalExpression[logicalVars.length];
         this.constantExpressionTypes = constantExpressionTypes;
         this.constantExpressions = constantExpressions;
+        this.fieldSources = new int[logicalVars.length];
         this.fieldNames = new ArrayList<List<String>>();
         for (int i = 0; i < logicalVars.length; i++) {
             fieldNames.add(new ArrayList<String>());
@@ -74,6 +76,7 @@
         this.logicalExprs = new ILogicalExpression[1];
         this.constantExpressions = new ILogicalExpression[] { constantExpression };
         this.constantExpressionTypes = new IAType[] { constantExpressionType };
+        this.fieldSources = new int[logicalVars.length];
         this.fieldNames = new ArrayList<List<String>>();
         for (int i = 0; i < logicalVars.length; i++) {
             fieldNames.add(new ArrayList<String>());
@@ -118,8 +121,9 @@
     }
 
     @Override
-    public void setFieldName(int index, List<String> fieldName) {
+    public void setFieldName(int index, List<String> fieldName, int fieldSource) {
         fieldNames.set(index, fieldName);
+        fieldSources[index] = fieldSource;
     }
 
     @Override
@@ -128,6 +132,11 @@
     }
 
     @Override
+    public int getFieldSource(int index) {
+        return fieldSources[index];
+    }
+
+    @Override
     public void setFieldType(int index, IAType fieldType) {
         fieldTypes[index] = fieldType;
     }
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
index 7311644..2f1db8c 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
@@ -80,6 +80,7 @@
     private ARecordType metaRecordType = null;
     // Contains the field names for all assign operations in this sub-tree.
     // This will be used for the index-only plan check.
+    // TODO(ali): this map should be fixed to include the source of the field (dataset record or meta record)
     private Map<LogicalVariable, List<String>> varsToFieldNameMap = new HashMap<>();
 
     // Additional datasources can exist if IntroduceJoinAccessMethodRule has been applied.
diff --git a/asterixdb/asterix-app/data/csv/people3.csv b/asterixdb/asterix-app/data/csv/people3.csv
new file mode 100644
index 0000000..817b4a6
--- /dev/null
+++ b/asterixdb/asterix-app/data/csv/people3.csv
@@ -0,0 +1,9 @@
+76041664,"{""id"":""1"", ""name"":""John Mad"", ""age"":29, ""hobby"":""reading""}"
+52037425,"{""id"":""2"", ""name"":""Scott Scott"", ""age"":30, ""hobby"":""hiking""}"
+45962603,"{""id"":""3"", ""name"":""Dan David"", ""age"":40, ""hobby"":""bowling""}"
+51041435,"{""id"":""4"", ""name"":""Robert Moore"", ""age"":32, ""hobby"":""reading""}"
+7,"{""id"":""5"", ""name"":""Sandy Donald"", ""age"":35, ""hobby"":""soccer""}"
+13071782,"{""id"":""6"", ""name"":""Joe Dana"", ""age"":24, ""hobby"":""tennis""}"
+5,"{""id"":""7"", ""name"":""Watson Jordon"", ""age"":28, ""hobby"":""basketball""}"
+32571888,"{""id"":""8"", ""name"":""Mat Steve"", ""age"":45, ""hobby"":""tennis""}"
+86897761,"{""id"":""9"", ""name"":""Sandra Pec"", ""age"":36, ""hobby"":""hiking""}"
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_01.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_01.sqlpp
new file mode 100644
index 0000000..7955726
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_01.sqlpp
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that data scan is used (no primary index is used)
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+
+// DS1 primary index is on meta().id
+select * from DS1
+where id = "2";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_02.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_02.sqlpp
new file mode 100644
index 0000000..398c028
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_02.sqlpp
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+
+// DS1 primary index is on meta().id
+select * from DS1
+where meta().id = "5";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_03.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_03.sqlpp
new file mode 100644
index 0000000..a701d86
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_03.sqlpp
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS2(DataType) with meta(MetaType) primary key id;
+
+// DS2 primary index is on id
+select * from DS2
+where id = "2";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_04.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_04.sqlpp
new file mode 100644
index 0000000..a63697a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_04.sqlpp
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that data scan is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS2(DataType) with meta(MetaType) primary key id;
+
+// DS2 primary index is on id
+select * from DS2
+where meta().id = "5";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_05.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_05.sqlpp
new file mode 100644
index 0000000..67d016e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_05.sqlpp
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that data scan is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+create dataset DS2(DataType) with meta(MetaType) primary key id;
+
+// DS2 primary index is on id. DS1 primary index is on meta().id
+use test;
+
+from DS2 as ds2 join DS1 as ds1 on ds2.id /*+ indexnl */ = ds1.id
+select ds2, ds1
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_06.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_06.sqlpp
new file mode 100644
index 0000000..8a72f86
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_06.sqlpp
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index of DS1 is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+create dataset DS2(DataType) with meta(MetaType) primary key id;
+
+// DS2 primary index is on id. DS1 primary index is on meta().id
+use test;
+
+from DS2 as ds2 join DS1 as ds1 on ds2.id /*+ indexnl */ = meta(ds1).id
+select meta(ds1).id as ds1_meta_id, ds2, ds1
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_07.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_07.sqlpp
new file mode 100644
index 0000000..9753c9c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_07.sqlpp
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index of DS2 is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+create dataset DS2(DataType) with meta(MetaType) primary key id;
+
+// DS2 primary index is on id. DS1 primary index is on meta().id
+use test;
+
+from DS1 as ds1 join DS2 as ds2 on ds1.id /*+ indexnl */ = ds2.id
+select ds1, ds2
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_08.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_08.sqlpp
new file mode 100644
index 0000000..5540b38
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_08.sqlpp
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that secondary index is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+create index id_sec_idx on DS1(id);
+
+// DS1 primary index is on meta().id & now has a secondary index on id
+
+select * from DS1
+where id = "2";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_09.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_09.sqlpp
new file mode 100644
index 0000000..27b69db
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_09.sqlpp
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+create index id_sec_idx on DS1(id);
+
+// DS1 primary index is on meta().id & now has a secondary index on id
+select * from DS1
+where meta().id = "5";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_10.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_10.sqlpp
new file mode 100644
index 0000000..68cee62
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_10.sqlpp
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that secondary index of DS1 is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+create dataset DS2(DataType) with meta(MetaType) primary key id;
+create index id_sec_idx on DS1(id);
+
+// DS1 primary index is on meta().id & now has a secondary index on id. DS2 primary index is on id
+from DS2 as ds2 join DS1 as ds1 on ds2.id /*+ indexnl */ = ds1.id
+select ds2, ds1
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_11.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_11.sqlpp
new file mode 100644
index 0000000..d5b922a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/meta/indexes_on_dataset_with_meta_11.sqlpp
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index of DS1 is used
+ * Expected Res : Success
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+create dataset DS2(DataType) with meta(MetaType) primary key id;
+create index id_sec_idx on DS1(id);
+
+// DS1 primary index is on meta().id & now has a secondary index on id. DS2 primary index is on id
+from DS2 as ds2 join DS1 as ds1 on ds2.id /*+ indexnl */ = meta(ds1).id
+select meta(ds1).id as ds1_meta_id, ds2, ds1
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_1.plan
index 4bef88b..000f2f0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_1.plan
@@ -11,4 +11,4 @@
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                       -- DATASOURCE_SCAN  |PARTITIONED|
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_2.plan
index 697008a..efb6c63 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_2.plan
@@ -8,4 +8,4 @@
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                 -- BTREE_SEARCH  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_3.plan
index 697008a..efb6c63 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_3.plan
@@ -8,4 +8,4 @@
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                 -- BTREE_SEARCH  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_4.plan
index 4bef88b..000f2f0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_4.plan
@@ -11,4 +11,4 @@
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                       -- DATASOURCE_SCAN  |PARTITIONED|
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_01.plan
new file mode 100644
index 0000000..5df1890
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_01.plan
@@ -0,0 +1,10 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_SELECT  |PARTITIONED|
+          -- STREAM_PROJECT  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_02.plan
new file mode 100644
index 0000000..fec009a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_02.plan
@@ -0,0 +1,10 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            -- BTREE_SEARCH  |PARTITIONED|
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- ASSIGN  |PARTITIONED|
+                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_03.plan
new file mode 100644
index 0000000..fec009a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_03.plan
@@ -0,0 +1,10 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            -- BTREE_SEARCH  |PARTITIONED|
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- ASSIGN  |PARTITIONED|
+                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_04.plan
new file mode 100644
index 0000000..1a11a0c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_04.plan
@@ -0,0 +1,11 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- STREAM_SELECT  |PARTITIONED|
+            -- STREAM_PROJECT  |PARTITIONED|
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_05.plan
new file mode 100644
index 0000000..f275419
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_05.plan
@@ -0,0 +1,24 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- SORT_MERGE_EXCHANGE [$$27(ASC) ]  |PARTITIONED|
+            -- STABLE_SORT [$$27(ASC)]  |PARTITIONED|
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- STREAM_PROJECT  |PARTITIONED|
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    -- HYBRID_HASH_JOIN [$$27][$$32]  |PARTITIONED|
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
+                        -- ASSIGN  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_06.plan
new file mode 100644
index 0000000..c5d6e9f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_06.plan
@@ -0,0 +1,17 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- SORT_MERGE_EXCHANGE [$$31(ASC) ]  |PARTITIONED|
+            -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- STREAM_PROJECT  |PARTITIONED|
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_07.plan
new file mode 100644
index 0000000..c129ee0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_07.plan
@@ -0,0 +1,18 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- SORT_MERGE_EXCHANGE [$$29(ASC) ]  |PARTITIONED|
+            -- STREAM_PROJECT  |PARTITIONED|
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- BTREE_SEARCH  |PARTITIONED|
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                      -- HASH_PARTITION_EXCHANGE [$$31]  |PARTITIONED|
+                        -- ASSIGN  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_08.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_08.plan
new file mode 100644
index 0000000..05f667d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_08.plan
@@ -0,0 +1,17 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_SELECT  |PARTITIONED|
+          -- STREAM_PROJECT  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- BTREE_SEARCH  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
+                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_09.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_09.plan
new file mode 100644
index 0000000..fec009a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_09.plan
@@ -0,0 +1,10 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            -- BTREE_SEARCH  |PARTITIONED|
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- ASSIGN  |PARTITIONED|
+                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_10.plan
new file mode 100644
index 0000000..0ac8731
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_10.plan
@@ -0,0 +1,24 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- SORT_MERGE_EXCHANGE [$$27(ASC) ]  |PARTITIONED|
+            -- STABLE_SORT [$$27(ASC)]  |PARTITIONED|
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- STREAM_SELECT  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_11.plan
new file mode 100644
index 0000000..c5d6e9f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_11.plan
@@ -0,0 +1,17 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- SORT_MERGE_EXCHANGE [$$31(ASC) ]  |PARTITIONED|
+            -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- STREAM_PROJECT  |PARTITIONED|
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.01.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.01.ddl.sqlpp
new file mode 100644
index 0000000..ae60888
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.01.ddl.sqlpp
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type DataType as open {
+id:string,
+name:string,
+age:int,
+hobby:string
+};
+
+create type MetaType as closed {
+id:string
+};
+
+create dataset DS1(DataType) with meta(MetaType) primary key meta().id;
+create dataset DS2(DataType) with meta(MetaType) primary key id;
+
+create feed DsStream1 with {
+ "adapter-name" : "localfs",
+ "reader" : "localfs",
+ "parser" : "record-with-metadata",
+ "type-name" : "DataType",
+ "meta-type-name" : "MetaType",
+ "path" : "asterix_nc1://data/csv/people3.csv",
+ "format" : "csv",
+ "delimiter" : ",",
+ "record-format" : "adm",
+ "record-index" : "1",
+ "key-indexes" : "0",
+ "key-indicators" : "1",
+ "header" : "false"
+};
+
+create feed DsStream2 with {
+ "adapter-name" : "localfs",
+ "reader" : "localfs",
+ "parser" : "record-with-metadata",
+ "type-name" : "DataType",
+ "meta-type-name" : "MetaType",
+ "path" : "asterix_nc1://data/csv/people3.csv",
+ "format" : "csv",
+ "delimiter" : ",",
+ "record-format" : "adm",
+ "record-index" : "1",
+ "key-indexes" : "0",
+ "key-indicators" : "0",
+ "header" : "false"
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.02.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.02.update.sqlpp
new file mode 100644
index 0000000..3174cc5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.02.update.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use test;
+
+set `wait-for-completion-feed` "true";
+connect feed DsStream1 to dataset DS1;
+start feed DsStream1;
+
+connect feed DsStream2 to dataset DS2;
+start feed DsStream2;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.03.query.sqlpp
new file mode 100644
index 0000000..39e3707
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.03.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that data scan is used (no primary index is used)
+ * Expected Res : Success
+ */
+
+// DS1 primary index is on meta().id
+use test;
+
+select * from DS1
+where id = "2";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.04.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.04.query.sqlpp
new file mode 100644
index 0000000..cb87da7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.04.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index is used
+ * Expected Res : Success
+ */
+
+// DS1 primary index is on meta().id
+use test;
+
+select * from DS1
+where meta().id = "5";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.05.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.05.query.sqlpp
new file mode 100644
index 0000000..55a2cee
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.05.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index is used
+ * Expected Res : Success
+ */
+
+// DS2 primary index is on id
+use test;
+
+select * from DS2
+where id = "2";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.06.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.06.query.sqlpp
new file mode 100644
index 0000000..2b1b11d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.06.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that data scan is used
+ * Expected Res : Success
+ */
+
+// DS2 primary index is on id
+use test;
+
+select * from DS2
+where meta().id = "5";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.07.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.07.query.sqlpp
new file mode 100644
index 0000000..22ba5b2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.07.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that data scan is used
+ * Expected Res : Success
+ */
+
+// DS2 primary index is on id. DS1 primary index is on meta().id
+use test;
+
+from DS2 as ds2 join DS1 as ds1 on ds2.id /*+ indexnl */ = ds1.id
+select ds2, ds1
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.08.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.08.query.sqlpp
new file mode 100644
index 0000000..4b85cf9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.08.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index of DS1 is used
+ * Expected Res : Success
+ */
+
+// DS2 primary index is on id. DS1 primary index is on meta().id
+use test;
+
+from DS2 as ds2 join DS1 as ds1 on ds2.id /*+ indexnl */ = meta(ds1).id
+select meta(ds1).id as ds1_meta_id, ds2, ds1
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.09.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.09.query.sqlpp
new file mode 100644
index 0000000..0c4c744
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.09.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index of DS2 is used
+ * Expected Res : Success
+ */
+
+// DS2 primary index is on id. DS1 primary index is on meta().id
+use test;
+
+from DS1 as ds1 join DS2 as ds2 on ds1.id /*+ indexnl */ = ds2.id
+select ds1, ds2
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.10.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.10.ddl.sqlpp
new file mode 100644
index 0000000..204dfd9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.10.ddl.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use test;
+
+create index id_sec_idx on DS1(id);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.11.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.11.query.sqlpp
new file mode 100644
index 0000000..bc12e9c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.11.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that secondary index is used
+ * Expected Res : Success
+ */
+
+// DS1 primary index is on meta().id & now has a secondary index on id
+use test;
+
+select * from DS1
+where id = "2";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.12.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.12.query.sqlpp
new file mode 100644
index 0000000..e14e8ba
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.12.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index is used
+ * Expected Res : Success
+ */
+
+// DS1 primary index is on meta().id & now has a secondary index on id
+use test;
+
+select * from DS1
+where meta().id = "5";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.13.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.13.query.sqlpp
new file mode 100644
index 0000000..07f96c2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.13.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that secondary index of DS1 is used
+ * Expected Res : Success
+ */
+
+// DS1 primary index is on meta().id & now has a secondary index on id. DS2 primary index is on id
+use test;
+
+from DS2 as ds2 join DS1 as ds1 on ds2.id /*+ indexnl */ = ds1.id
+select ds2, ds1
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.14.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.14.query.sqlpp
new file mode 100644
index 0000000..f1e3c7c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.14.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description  : Testing that primary index of DS1 is used
+ * Expected Res : Success
+ */
+
+// DS1 primary index is on meta().id & now has a secondary index on id. DS2 primary index is on id
+use test;
+
+from DS2 as ds2 join DS1 as ds1 on ds2.id /*+ indexnl */ = meta(ds1).id
+select meta(ds1).id as ds1_meta_id, ds2, ds1
+order by ds2.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.15.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.15.ddl.sqlpp
new file mode 100644
index 0000000..548e632
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/dataset-with-meta/dataset-with-meta.15.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse test if exists;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/meta/resolving_pk_with_meta/resolving_pk_with_meta.7.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/meta/resolving_pk_with_meta/resolving_pk_with_meta.7.ddl.sqlpp
index f12a2b7..821b1a7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/meta/resolving_pk_with_meta/resolving_pk_with_meta.7.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/meta/resolving_pk_with_meta/resolving_pk_with_meta.7.ddl.sqlpp
@@ -17,4 +17,4 @@
  * under the License.
  */
 
-drop dataverse test;
\ No newline at end of file
+drop dataverse test;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.11.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.11.adm
index 375d551..a7bb19e 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.11.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.11.adm
@@ -6,4 +6,4 @@
 { "rec": { "id": 9, "name": "Sandra Pec", "age": 36, "hobby": "hiking" }, "meta": { "id": "rec9_US", "class_type": 3, "updated_date": "2018-06-09" }, "count": [ 9 ] }
 { "rec": { "id": 10, "name": "Sandra Lan", "age": 36, "hobby": "football" }, "meta": { "id": "rec10_US", "class_type": 3, "updated_date": "2017-06-09" }, "count": [ 9 ] }
 { "rec": { "id": 13, "name": "Sally Bush", "age": 29, "hobby": "reading" }, "meta": { "id": "rec13_US", "class_type": 2, "updated_date": "2014-09-01" }, "count": [ 9 ] }
-{ "rec": { "id": 14, "name": "Sarah Tran", "age": 20, "hobby": "reading" }, "meta": { "id": "rec14_US", "class_type": 1, "updated_date": "2010-09-01" }, "count": [ 9 ] }
\ No newline at end of file
+{ "rec": { "id": 14, "name": "Sarah Tran", "age": 20, "hobby": "reading" }, "meta": { "id": "rec14_US", "class_type": 1, "updated_date": "2010-09-01" }, "count": [ 9 ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.12.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.12.adm
index 79062f5..e21ab6a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.12.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.12.adm
@@ -2,4 +2,4 @@
 { "rec": { "id": 5, "name": "Sandy Donald", "age": 35, "hobby": "soccer" }, "meta": { "id": "rec5_UK", "class_type": 2, "updated_date": "2018-01-04" }, "count": [ 5 ] }
 { "rec": { "id": 8, "name": "Mat Steve", "age": 45, "hobby": "tennis" }, "meta": { "id": "rec8_UK", "class_type": 2, "updated_date": "2018-06-05" }, "count": [ 5 ] }
 { "rec": { "id": 11, "name": "Trever Jones", "age": 36, "hobby": "hiking" }, "meta": { "id": "rec11_UK", "class_type": 3, "updated_date": "2018-09-09" }, "count": [ 5 ] }
-{ "rec": { "id": 12, "name": "Ruth Pec", "age": 36, "hobby": "swimming" }, "meta": { "id": "rec12_UK", "class_type": 3, "updated_date": "2016-09-01" }, "count": [ 5 ] }
\ No newline at end of file
+{ "rec": { "id": 12, "name": "Ruth Pec", "age": 36, "hobby": "swimming" }, "meta": { "id": "rec12_UK", "class_type": 3, "updated_date": "2016-09-01" }, "count": [ 5 ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.13.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.13.adm
index 18202fc..6b30bb0 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.13.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.13.adm
@@ -2,4 +2,4 @@
 { "rec": { "id": 2, "name": "Scott Scott", "age": 30, "hobby": "hiking" }, "meta": { "id": "rec2_US", "class_type": 1, "updated_date": "2008-02-04" }, "count": [ 5 ] }
 { "rec": { "id": 4, "name": "Robert Moore", "age": 32, "hobby": "reading" }, "meta": { "id": "rec4_US", "class_type": 1, "updated_date": "2006-01-04" }, "count": [ 5 ] }
 { "rec": { "id": 7, "name": "Watson Jordon", "age": 28, "hobby": "basketball" }, "meta": { "id": "rec7_US", "class_type": 1, "updated_date": "2018-06-07" }, "count": [ 5 ] }
-{ "rec": { "id": 14, "name": "Sarah Tran", "age": 20, "hobby": "reading" }, "meta": { "id": "rec14_US", "class_type": 1, "updated_date": "2010-09-01" }, "count": [ 5 ] }
\ No newline at end of file
+{ "rec": { "id": 14, "name": "Sarah Tran", "age": 20, "hobby": "reading" }, "meta": { "id": "rec14_US", "class_type": 1, "updated_date": "2010-09-01" }, "count": [ 5 ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.14.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.14.adm
index 533eee0..47827a9 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.14.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.14.adm
@@ -2,4 +2,4 @@
 { "rec": { "id": 5, "name": "Sandy Donald", "age": 35, "hobby": "soccer" }, "meta": { "id": "rec5_UK", "class_type": 2, "updated_date": "2018-01-04" }, "count": [ 5 ] }
 { "rec": { "id": 6, "name": "Joe Dana", "age": 24, "hobby": "tennis" }, "meta": { "id": "rec6_US", "class_type": 2, "updated_date": "2018-06-05" }, "count": [ 5 ] }
 { "rec": { "id": 8, "name": "Mat Steve", "age": 45, "hobby": "tennis" }, "meta": { "id": "rec8_UK", "class_type": 2, "updated_date": "2018-06-05" }, "count": [ 5 ] }
-{ "rec": { "id": 13, "name": "Sally Bush", "age": 29, "hobby": "reading" }, "meta": { "id": "rec13_US", "class_type": 2, "updated_date": "2014-09-01" }, "count": [ 5 ] }
\ No newline at end of file
+{ "rec": { "id": 13, "name": "Sally Bush", "age": 29, "hobby": "reading" }, "meta": { "id": "rec13_US", "class_type": 2, "updated_date": "2014-09-01" }, "count": [ 5 ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.15.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.15.adm
index 3f25df9..2422d52 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.15.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.15.adm
@@ -1,4 +1,4 @@
 { "rec": { "id": 9, "name": "Sandra Pec", "age": 36, "hobby": "hiking" }, "meta": { "id": "rec9_US", "class_type": 3, "updated_date": "2018-06-09" }, "count": [ 4 ] }
 { "rec": { "id": 10, "name": "Sandra Lan", "age": 36, "hobby": "football" }, "meta": { "id": "rec10_US", "class_type": 3, "updated_date": "2017-06-09" }, "count": [ 4 ] }
 { "rec": { "id": 11, "name": "Trever Jones", "age": 36, "hobby": "hiking" }, "meta": { "id": "rec11_UK", "class_type": 3, "updated_date": "2018-09-09" }, "count": [ 4 ] }
-{ "rec": { "id": 12, "name": "Ruth Pec", "age": 36, "hobby": "swimming" }, "meta": { "id": "rec12_UK", "class_type": 3, "updated_date": "2016-09-01" }, "count": [ 4 ] }
\ No newline at end of file
+{ "rec": { "id": 12, "name": "Ruth Pec", "age": 36, "hobby": "swimming" }, "meta": { "id": "rec12_UK", "class_type": 3, "updated_date": "2016-09-01" }, "count": [ 4 ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.16.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.16.adm
index b2b76f2..20bf380 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.16.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.16.adm
@@ -2,4 +2,4 @@
 { "rec": { "id": 2, "name": "Scott Scott", "age": 30, "hobby": "hiking" }, "meta": { "id": "rec2_US", "class_type": 1, "updated_date": "2008-02-04" }, "count": [ 5 ] }
 { "rec": { "id": 4, "name": "Robert Moore", "age": 32, "hobby": "reading" }, "meta": { "id": "rec4_US", "class_type": 1, "updated_date": "2006-01-04" }, "count": [ 5 ] }
 { "rec": { "id": 13, "name": "Sally Bush", "age": 29, "hobby": "reading" }, "meta": { "id": "rec13_US", "class_type": 2, "updated_date": "2014-09-01" }, "count": [ 5 ] }
-{ "rec": { "id": 14, "name": "Sarah Tran", "age": 20, "hobby": "reading" }, "meta": { "id": "rec14_US", "class_type": 1, "updated_date": "2010-09-01" }, "count": [ 5 ] }
\ No newline at end of file
+{ "rec": { "id": 14, "name": "Sarah Tran", "age": 20, "hobby": "reading" }, "meta": { "id": "rec14_US", "class_type": 1, "updated_date": "2010-09-01" }, "count": [ 5 ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.17.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.17.adm
index 79e173d..07bbe09 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.17.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.17.adm
@@ -6,4 +6,4 @@
 { "rec": { "id": 9, "name": "Sandra Pec", "age": 36, "hobby": "hiking" }, "meta": { "id": "rec9_US", "class_type": 3, "updated_date": "2018-06-09" }, "count": [ 9 ] }
 { "rec": { "id": 10, "name": "Sandra Lan", "age": 36, "hobby": "football" }, "meta": { "id": "rec10_US", "class_type": 3, "updated_date": "2017-06-09" }, "count": [ 9 ] }
 { "rec": { "id": 11, "name": "Trever Jones", "age": 36, "hobby": "hiking" }, "meta": { "id": "rec11_UK", "class_type": 3, "updated_date": "2018-09-09" }, "count": [ 9 ] }
-{ "rec": { "id": 12, "name": "Ruth Pec", "age": 36, "hobby": "swimming" }, "meta": { "id": "rec12_UK", "class_type": 3, "updated_date": "2016-09-01" }, "count": [ 9 ] }
\ No newline at end of file
+{ "rec": { "id": 12, "name": "Ruth Pec", "age": 36, "hobby": "swimming" }, "meta": { "id": "rec12_UK", "class_type": 3, "updated_date": "2016-09-01" }, "count": [ 9 ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.6.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.6.adm
index 533eee0..47827a9 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.6.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.6.adm
@@ -2,4 +2,4 @@
 { "rec": { "id": 5, "name": "Sandy Donald", "age": 35, "hobby": "soccer" }, "meta": { "id": "rec5_UK", "class_type": 2, "updated_date": "2018-01-04" }, "count": [ 5 ] }
 { "rec": { "id": 6, "name": "Joe Dana", "age": 24, "hobby": "tennis" }, "meta": { "id": "rec6_US", "class_type": 2, "updated_date": "2018-06-05" }, "count": [ 5 ] }
 { "rec": { "id": 8, "name": "Mat Steve", "age": 45, "hobby": "tennis" }, "meta": { "id": "rec8_UK", "class_type": 2, "updated_date": "2018-06-05" }, "count": [ 5 ] }
-{ "rec": { "id": 13, "name": "Sally Bush", "age": 29, "hobby": "reading" }, "meta": { "id": "rec13_US", "class_type": 2, "updated_date": "2014-09-01" }, "count": [ 5 ] }
\ No newline at end of file
+{ "rec": { "id": 13, "name": "Sally Bush", "age": 29, "hobby": "reading" }, "meta": { "id": "rec13_US", "class_type": 2, "updated_date": "2014-09-01" }, "count": [ 5 ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.7.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.7.adm
index 3f25df9..2422d52 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.7.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/feeds/change-feed-with-filter-on-meta/change-feed-with-filter-on-meta.7.adm
@@ -1,4 +1,4 @@
 { "rec": { "id": 9, "name": "Sandra Pec", "age": 36, "hobby": "hiking" }, "meta": { "id": "rec9_US", "class_type": 3, "updated_date": "2018-06-09" }, "count": [ 4 ] }
 { "rec": { "id": 10, "name": "Sandra Lan", "age": 36, "hobby": "football" }, "meta": { "id": "rec10_US", "class_type": 3, "updated_date": "2017-06-09" }, "count": [ 4 ] }
 { "rec": { "id": 11, "name": "Trever Jones", "age": 36, "hobby": "hiking" }, "meta": { "id": "rec11_UK", "class_type": 3, "updated_date": "2018-09-09" }, "count": [ 4 ] }
-{ "rec": { "id": 12, "name": "Ruth Pec", "age": 36, "hobby": "swimming" }, "meta": { "id": "rec12_UK", "class_type": 3, "updated_date": "2016-09-01" }, "count": [ 4 ] }
\ No newline at end of file
+{ "rec": { "id": 12, "name": "Ruth Pec", "age": 36, "hobby": "swimming" }, "meta": { "id": "rec12_UK", "class_type": 3, "updated_date": "2016-09-01" }, "count": [ 4 ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.03.adm
new file mode 100644
index 0000000..708eef0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.03.adm
@@ -0,0 +1 @@
+{ "DS1": { "id": "2", "name": "Scott Scott", "age": 30, "hobby": "hiking" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.04.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.04.adm
new file mode 100644
index 0000000..2c1129d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.04.adm
@@ -0,0 +1 @@
+{ "DS1": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.05.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.05.adm
new file mode 100644
index 0000000..fd1e899
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.05.adm
@@ -0,0 +1 @@
+{ "DS2": { "id": "2", "name": "Scott Scott", "age": 30, "hobby": "hiking" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.06.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.06.adm
new file mode 100644
index 0000000..227dd34
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.06.adm
@@ -0,0 +1 @@
+{ "DS2": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.07.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.07.adm
new file mode 100644
index 0000000..43ef810
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.07.adm
@@ -0,0 +1,9 @@
+{ "ds2": { "id": "1", "name": "John Mad", "age": 29, "hobby": "reading" }, "ds1": { "id": "1", "name": "John Mad", "age": 29, "hobby": "reading" } }
+{ "ds2": { "id": "2", "name": "Scott Scott", "age": 30, "hobby": "hiking" }, "ds1": { "id": "2", "name": "Scott Scott", "age": 30, "hobby": "hiking" } }
+{ "ds2": { "id": "3", "name": "Dan David", "age": 40, "hobby": "bowling" }, "ds1": { "id": "3", "name": "Dan David", "age": 40, "hobby": "bowling" } }
+{ "ds2": { "id": "4", "name": "Robert Moore", "age": 32, "hobby": "reading" }, "ds1": { "id": "4", "name": "Robert Moore", "age": 32, "hobby": "reading" } }
+{ "ds2": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" }, "ds1": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" } }
+{ "ds2": { "id": "6", "name": "Joe Dana", "age": 24, "hobby": "tennis" }, "ds1": { "id": "6", "name": "Joe Dana", "age": 24, "hobby": "tennis" } }
+{ "ds2": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" }, "ds1": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" } }
+{ "ds2": { "id": "8", "name": "Mat Steve", "age": 45, "hobby": "tennis" }, "ds1": { "id": "8", "name": "Mat Steve", "age": 45, "hobby": "tennis" } }
+{ "ds2": { "id": "9", "name": "Sandra Pec", "age": 36, "hobby": "hiking" }, "ds1": { "id": "9", "name": "Sandra Pec", "age": 36, "hobby": "hiking" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.08.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.08.adm
new file mode 100644
index 0000000..99fd8f1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.08.adm
@@ -0,0 +1,2 @@
+{ "ds1_meta_id": "5", "ds2": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" }, "ds1": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" } }
+{ "ds1_meta_id": "7", "ds2": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" }, "ds1": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.09.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.09.adm
new file mode 100644
index 0000000..eeb11e5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.09.adm
@@ -0,0 +1,9 @@
+{ "ds1": { "id": "1", "name": "John Mad", "age": 29, "hobby": "reading" }, "ds2": { "id": "1", "name": "John Mad", "age": 29, "hobby": "reading" } }
+{ "ds1": { "id": "2", "name": "Scott Scott", "age": 30, "hobby": "hiking" }, "ds2": { "id": "2", "name": "Scott Scott", "age": 30, "hobby": "hiking" } }
+{ "ds1": { "id": "3", "name": "Dan David", "age": 40, "hobby": "bowling" }, "ds2": { "id": "3", "name": "Dan David", "age": 40, "hobby": "bowling" } }
+{ "ds1": { "id": "4", "name": "Robert Moore", "age": 32, "hobby": "reading" }, "ds2": { "id": "4", "name": "Robert Moore", "age": 32, "hobby": "reading" } }
+{ "ds1": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" }, "ds2": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" } }
+{ "ds1": { "id": "6", "name": "Joe Dana", "age": 24, "hobby": "tennis" }, "ds2": { "id": "6", "name": "Joe Dana", "age": 24, "hobby": "tennis" } }
+{ "ds1": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" }, "ds2": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" } }
+{ "ds1": { "id": "8", "name": "Mat Steve", "age": 45, "hobby": "tennis" }, "ds2": { "id": "8", "name": "Mat Steve", "age": 45, "hobby": "tennis" } }
+{ "ds1": { "id": "9", "name": "Sandra Pec", "age": 36, "hobby": "hiking" }, "ds2": { "id": "9", "name": "Sandra Pec", "age": 36, "hobby": "hiking" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.11.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.11.adm
new file mode 100644
index 0000000..708eef0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.11.adm
@@ -0,0 +1 @@
+{ "DS1": { "id": "2", "name": "Scott Scott", "age": 30, "hobby": "hiking" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.12.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.12.adm
new file mode 100644
index 0000000..2c1129d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.12.adm
@@ -0,0 +1 @@
+{ "DS1": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.13.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.13.adm
new file mode 100644
index 0000000..43ef810
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.13.adm
@@ -0,0 +1,9 @@
+{ "ds2": { "id": "1", "name": "John Mad", "age": 29, "hobby": "reading" }, "ds1": { "id": "1", "name": "John Mad", "age": 29, "hobby": "reading" } }
+{ "ds2": { "id": "2", "name": "Scott Scott", "age": 30, "hobby": "hiking" }, "ds1": { "id": "2", "name": "Scott Scott", "age": 30, "hobby": "hiking" } }
+{ "ds2": { "id": "3", "name": "Dan David", "age": 40, "hobby": "bowling" }, "ds1": { "id": "3", "name": "Dan David", "age": 40, "hobby": "bowling" } }
+{ "ds2": { "id": "4", "name": "Robert Moore", "age": 32, "hobby": "reading" }, "ds1": { "id": "4", "name": "Robert Moore", "age": 32, "hobby": "reading" } }
+{ "ds2": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" }, "ds1": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" } }
+{ "ds2": { "id": "6", "name": "Joe Dana", "age": 24, "hobby": "tennis" }, "ds1": { "id": "6", "name": "Joe Dana", "age": 24, "hobby": "tennis" } }
+{ "ds2": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" }, "ds1": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" } }
+{ "ds2": { "id": "8", "name": "Mat Steve", "age": 45, "hobby": "tennis" }, "ds1": { "id": "8", "name": "Mat Steve", "age": 45, "hobby": "tennis" } }
+{ "ds2": { "id": "9", "name": "Sandra Pec", "age": 36, "hobby": "hiking" }, "ds1": { "id": "9", "name": "Sandra Pec", "age": 36, "hobby": "hiking" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.14.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.14.adm
new file mode 100644
index 0000000..99fd8f1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/dataset-with-meta/dataset-with-meta.14.adm
@@ -0,0 +1,2 @@
+{ "ds1_meta_id": "5", "ds2": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" }, "ds1": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" } }
+{ "ds1_meta_id": "7", "ds2": { "id": "7", "name": "Watson Jordon", "age": 28, "hobby": "basketball" }, "ds1": { "id": "5", "name": "Sandy Donald", "age": 35, "hobby": "soccer" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/meta/meta_in_with_clause/meta_in_with_clause.6.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/meta/meta_in_with_clause/meta_in_with_clause.6.adm
index 7bffc6d..1cc10ea 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/meta/meta_in_with_clause/meta_in_with_clause.6.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/meta/meta_in_with_clause/meta_in_with_clause.6.adm
@@ -5,4 +5,4 @@
 { "age": 24, "aid": 6, "total": 8, "hobby": "tennis" }
 { "age": 28, "aid": 7, "total": 8, "hobby": "basketball" }
 { "age": 45, "aid": 8, "total": 8, "hobby": "tennis" }
-{ "age": 36, "aid": 9, "total": 8, "hobby": "hiking" }
+{ "age": 36, "aid": 9, "total": 8, "hobby": "hiking" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 30ac1e3..c6146f9 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -5499,6 +5499,11 @@
         <output-dir compare="Text">disjunctive-predicate-1</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="index-selection">
+      <compilation-unit name="dataset-with-meta">
+        <output-dir compare="Text">dataset-with-meta</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="inverted-index-join">
     <test-case FilePath="inverted-index-join">
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ReplicaIdentifier.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ReplicaIdentifier.java
index 01ffba6..f68ad09 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ReplicaIdentifier.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ReplicaIdentifier.java
@@ -29,7 +29,7 @@
     private ReplicaIdentifier(int partition, InetSocketAddress location) {
         this.partition = partition;
         this.location = location;
-        id = partition + "@" + location.toString();
+        id = partition + "@" + location.getHostString() + ":" + location.getPort();
     }
 
     public static ReplicaIdentifier of(int partition, InetSocketAddress location) {
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtil.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtil.java
index d4b54f8..4b7d359 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtil.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtil.java
@@ -173,6 +173,18 @@
         return btreeFields;
     }
 
+    /**
+     * Returns the primary key source indicators of the {@code dataset} or {@code null} if the dataset does not have
+     * primary key source indicators (e.g. external datasets)
+     */
+    public static List<Integer> getKeySourceIndicators(Dataset dataset) {
+        IDatasetDetails datasetDetails = dataset.getDatasetDetails();
+        if (datasetDetails.getDatasetType() == DatasetType.INTERNAL) {
+            return ((InternalDatasetDetails) datasetDetails).getKeySourceIndicator();
+        }
+        return null;
+    }
+
     public static int getPositionOfPartitioningKeyField(Dataset dataset, List<String> fieldExpr,
             boolean fieldFromMeta) {
         List<Integer> keySourceIndicator = null;
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/cluster/NodeManager.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/cluster/NodeManager.java
index 3e72942..9007628 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/cluster/NodeManager.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/cluster/NodeManager.java
@@ -206,8 +206,19 @@
         nodeRegistry.forEach(nodeFunction::apply);
     }
 
-    private void removeNodeFromIpAddressMap(String nodeId, NodeControllerState ncState) throws HyracksException {
-        InetAddress ipAddress = getIpAddress(ncState);
+    private void removeNodeFromIpAddressMap(String nodeId, NodeControllerState ncState) {
+        InetAddress ipAddress;
+        try {
+            ipAddress = getIpAddress(ncState);
+        } catch (Exception e) {
+            LOGGER.warn("failed to get ip address of node {}; attempting to find it on existing nodes lists", nodeId,
+                    e);
+            ipAddress = findNodeIpById(nodeId);
+        }
+        if (ipAddress == null) {
+            LOGGER.warn("failed to get ip address of node {}", nodeId);
+            return;
+        }
         Set<String> nodes = ipAddressNodeNameMap.get(ipAddress);
         if (nodes != null) {
             nodes.remove(nodeId);
@@ -243,4 +254,13 @@
             }
         });
     }
+
+    private InetAddress findNodeIpById(String nodeId) {
+        for (Map.Entry<InetAddress, Set<String>> ipToNodesEntry : ipAddressNodeNameMap.entrySet()) {
+            if (ipToNodesEntry.getValue().contains(nodeId)) {
+                return ipToNodesEntry.getKey();
+            }
+        }
+        return null;
+    }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-net/src/main/java/org/apache/hyracks/net/protocols/muxdemux/FullFrameChannelReadInterface.java b/hyracks-fullstack/hyracks/hyracks-net/src/main/java/org/apache/hyracks/net/protocols/muxdemux/FullFrameChannelReadInterface.java
index 5a23fb3..f32e6bf 100644
--- a/hyracks-fullstack/hyracks/hyracks-net/src/main/java/org/apache/hyracks/net/protocols/muxdemux/FullFrameChannelReadInterface.java
+++ b/hyracks-fullstack/hyracks/hyracks-net/src/main/java/org/apache/hyracks/net/protocols/muxdemux/FullFrameChannelReadInterface.java
@@ -41,7 +41,6 @@
         this.ccb = ccb;
         riEmptyStack = new ArrayDeque<>();
         credits = 0;
-
         emptyBufferAcceptor = buffer -> {
             final int delta = buffer.remaining();
             synchronized (bufferRecycleLock) {