>From Preetham Poluparthi <[email protected]>:

Preetham Poluparthi has submitted this change. ( 
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20282?usp=email )

Change subject: [ASTERIXDB-3632] Fix NPEs in Index Advisor and add error 
handling for missing samples
......................................................................

[ASTERIXDB-3632] Fix NPEs in Index Advisor and add error handling for missing 
samples

- user model changes: no
- storage format changes: no
- interface changes: no

Ext-ref: MB-66492

Details:
This patch addresses several corner cases in the Index Advisor:

- Fixes null pointer exceptions that occur in scenarios such as:
  - Collections with secondary primary indexes
  - Cases where CBO bails out
- Adds proper error handling when an `ADVISE` query is issued without CBO 
enabled
- Introduces error reporting for collections that have no samples, suggesting 
the use of ANALYSE SAMPLE before issuing advise

Change-Id: I346728dd634934416d7115a06ab15572b5a98854
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20282
Reviewed-by: Ali Alsuliman <[email protected]>
Integration-Tests: Jenkins <[email protected]>
Reviewed-by: Preetham Poluparthi <[email protected]>
Tested-by: Preetham Poluparthi <[email protected]>
---
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceJoinAccessMethodRule.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceSelectAccessMethodRule.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdvisorConditionParser.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
M 
hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java
M 
hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
M 
hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
10 files changed, 116 insertions(+), 42 deletions(-)

Approvals:
  Ali Alsuliman: Looks good to me, approved
  Preetham Poluparthi: Looks good to me, but someone else must approve; Verified
  Jenkins: Verified




diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceJoinAccessMethodRule.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceJoinAccessMethodRule.java
index 5bc1e90..09cf843 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceJoinAccessMethodRule.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceJoinAccessMethodRule.java
@@ -123,7 +123,7 @@
             throws AlgebricksException {
         clear();
         boolean adviseIndex = context.getIndexAdvisor().getAdvise();
-        if (adviseIndex) {
+        if (adviseIndex && context.getIndexAdvisor().getFakeIndexProvider() != 
null) {
             setMetadataIndexDeclarations(context, (IIndexProvider) 
context.getIndexAdvisor().getFakeIndexProvider());
         } else {
             setMetadataIndexDeclarations(context, (IIndexProvider) 
context.getMetadataProvider());
diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceSelectAccessMethodRule.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceSelectAccessMethodRule.java
index 56ee034..df9fb2c 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceSelectAccessMethodRule.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IntroduceSelectAccessMethodRule.java
@@ -138,7 +138,7 @@
         clear();

         boolean adviseIndex = context.getIndexAdvisor().getAdvise();
-        if (adviseIndex) {
+        if (adviseIndex && context.getIndexAdvisor().getFakeIndexProvider() != 
null) {
             setMetadataIndexDeclarations(context, (IIndexProvider) 
context.getIndexAdvisor().getFakeIndexProvider());
         } else {
             setMetadataIndexDeclarations(context, (IIndexProvider) 
context.getMetadataProvider());
diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
index 6e4208d..b02301f 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/EnumerateJoinsRule.java
@@ -28,6 +28,8 @@

 import org.apache.asterix.common.annotations.IndexedNLJoinExpressionAnnotation;
 import 
org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
+import org.apache.asterix.common.metadata.DatasetFullyQualifiedName;
+import org.apache.asterix.metadata.declared.DatasetDataSource;
 import org.apache.asterix.metadata.declared.IIndexProvider;
 import org.apache.asterix.metadata.entities.Index;
 import org.apache.asterix.optimizer.rules.cbo.indexadvisor.AdvisorPlanParser;
@@ -71,6 +73,7 @@
 import 
org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
 import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 import 
org.apache.hyracks.algebricks.core.rewriter.base.PhysicalOptimizationConfig;
+import org.apache.hyracks.api.exceptions.ErrorCode;
 import org.apache.hyracks.api.exceptions.IWarningCollector;
 import org.apache.hyracks.api.exceptions.Warning;
 import org.apache.logging.log4j.LogManager;
@@ -140,8 +143,8 @@
     public boolean rewritePre(Mutable<ILogicalOperator> opRef, 
IOptimizationContext context)
             throws AlgebricksException {

-        boolean cboMode = this.getCBOMode(context);
-        boolean cboTestMode = this.getCBOTestMode(context);
+        boolean cboMode = getCBOMode(context);
+        boolean cboTestMode = getCBOTestMode(context);

         if (!(cboMode || cboTestMode)) {
             return false;
@@ -215,6 +218,9 @@
             joinEnum.stats = new Stats(context, joinEnum);
             if (cboMode) {
                 if (!doAllDataSourcesHaveSamples(leafInputs, context)) {
+                    if (adviseIndex) {
+                        errorOutIndexAdvisorSamplesNotFound(leafInputs, 
context);
+                    }
                     return cleanUp();
                 }
             }
@@ -278,6 +284,9 @@
                 fakeLeafInputsMap, context, indexProvider);
         if (cboMode) {
             if (!doAllDataSourcesHaveSamples(leafInputs, context)) {
+                if (adviseIndex) {
+                    errorOutIndexAdvisorSamplesNotFound(leafInputs, context);
+                }
                 return cleanUp();
             }
         }
@@ -768,12 +777,12 @@
         }
     }

-    private boolean getCBOMode(IOptimizationContext context) {
+    public static boolean getCBOMode(IOptimizationContext context) {
         PhysicalOptimizationConfig physOptConfig = 
context.getPhysicalOptimizationConfig();
         return physOptConfig.getCBOMode();
     }

-    private boolean getCBOTestMode(IOptimizationContext context) {
+    public static boolean getCBOTestMode(IOptimizationContext context) {
         PhysicalOptimizationConfig physOptConfig = 
context.getPhysicalOptimizationConfig();
         return physOptConfig.getCBOTestMode();
     }
@@ -1521,4 +1530,37 @@
         }
         return (leafInputs.size() == n);
     }
+
+    private void errorOutIndexAdvisorSamplesNotFound(List<ILogicalOperator> 
leafInputs, IOptimizationContext context)
+            throws AlgebricksException {
+        for (ILogicalOperator li : leafInputs) {
+            DataSourceScanOperator scanOp = 
joinEnum.findDataSourceScanOperator(li);
+            if (scanOp == null) {
+                // Scan Operator not found
+                continue;
+            }
+            Stats handle = joinEnum.getStatsHandle();
+            if (handle == null) {
+                continue;
+            }
+            Index index = handle.findSampleIndex(scanOp, context);
+            if (index == null) {
+                errorOutIndexAdvisorSampleNotFound(scanOp, context);
+            }
+        }
+    }
+
+    private void errorOutIndexAdvisorSampleNotFound(DataSourceScanOperator 
scanOperator, IOptimizationContext context) throws AlgebricksException {
+        if (!(scanOperator.getDataSource() instanceof DatasetDataSource 
dataSource)) {
+            return;
+        }
+        DatasetFullyQualifiedName fullyQualifiedName = 
dataSource.getDataset().getDatasetFullyQualifiedName();
+        throw new 
AlgebricksException(ErrorCode.INDEX_ADVISOR_SAMPLE_NOT_FOUND, 
createSampleStatement(fullyQualifiedName));
+    }
+
+    private static String createSampleStatement(DatasetFullyQualifiedName dqn) 
{
+        return "ANALYZE COLLECTION `" + dqn.getDatabaseName() + "`.`" + 
dqn.getDataverseName() + "`.`"
+                + dqn.getDatasetName() + "`;";
+    }
+
 }
diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java
index 9a7fbdd..7e34d25 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdviseIndexRule.java
@@ -121,7 +121,16 @@
             DataverseName dataverse = jobGenParams.getDataverseName();
             String datasetName = jobGenParams.getDatasetName();

+            if(fakeIndexProvider == null) {
+                // Case when CBO can't parse the plan correctly and the fake 
index provider is not set.
+                return;
+            }
             Index fakeIndex = fakeIndexProvider.getIndex(databaseName, 
dataverse, datasetName, indexName);
+            if (fakeIndex == null || !(fakeIndex.getIndexDetails() instanceof 
Index.ValueIndexDetails)) {
+                // skips secondary primary index like
+                // create primary index sec_primary_idx on A;
+                return;
+            }
             Index actualIndex = lookupIndex(databaseName, dataverse, 
datasetName,
                     ((Index.ValueIndexDetails) 
fakeIndex.getIndexDetails()).getKeyFieldNames(), actualIndexProvider);

diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdvisorConditionParser.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdvisorConditionParser.java
index a86b1b5..05039aa 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdvisorConditionParser.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/AdvisorConditionParser.java
@@ -47,11 +47,27 @@

 public class AdvisorConditionParser {

+    private static class ExprRef {
+        private final ILogicalExpression expr;
+        private final ILogicalOperator op;
+
+        public ExprRef(Mutable<ILogicalExpression> expr, ILogicalOperator op) {
+            this.expr = expr.getValue().cloneExpression();
+            this.op = op;
+        }
+
+        public ILogicalExpression getExpr() {
+            return expr;
+        }
+
+        public ILogicalOperator getOp() {
+            return op;
+        }
+    }
+
     public static ScanFilter parseScanNode(ILogicalOperator op, 
IOptimizationContext context)
             throws AlgebricksException {
-
-        List<Mutable<ILogicalExpression>> filterExprs = new ArrayList<>();
-        IVariableTypeEnvironment typeEnv = PushdownUtil.getTypeEnv(op, 
context);
+        List<ExprRef> filterExprRefs = new ArrayList<>();
         ILogicalOperator tempOp = op;
         do {
             if (tempOp.getOperatorTag() == LogicalOperatorTag.SELECT) {
@@ -59,35 +75,33 @@
                 ILogicalExpression condition = 
selectOp.getCondition().getValue();
                 List<Mutable<ILogicalExpression>> conjs = new ArrayList<>();
                 if (condition.splitIntoConjuncts(conjs)) {
-                    filterExprs.addAll(conjs);
+                    filterExprRefs.addAll(conjs.stream().map(expr -> new 
ExprRef(expr, selectOp)).toList());
                 } else {
-                    filterExprs.add(selectOp.getCondition());
+                    filterExprRefs.add(new ExprRef(selectOp.getCondition(), 
selectOp));
                 }
             }
             tempOp = tempOp.getInputs().getFirst().getValue();
         } while (tempOp.hasInputs());

-        filterExprs = OperatorManipulationUtil.cloneExpressions(filterExprs);
-
-        filterExprs.removeIf(expr -> !(expr.getValue() instanceof 
AbstractFunctionCallExpression));
+        filterExprRefs.removeIf(exprRef -> !(exprRef.getExpr() instanceof 
AbstractFunctionCallExpression));

         tempOp = op;
         do {
             if (tempOp.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
-                replaceExprsWithAssign((AssignOperator) tempOp, filterExprs);
+                replaceExprsWithAssign((AssignOperator) tempOp, 
filterExprRefs);
             }
             tempOp = tempOp.getInputs().getFirst().getValue();
         } while (tempOp.hasInputs());

         List<ScanFilterCondition> filterConditions = new ArrayList<>();

-        for (Mutable<ILogicalExpression> filterExpr : filterExprs) {
-            ScanFilterCondition filterCondition = 
parseCondition(filterExpr.getValue(), typeEnv);
+        for (ExprRef exprRef : filterExprRefs) {
+            IVariableTypeEnvironment typeEnv = 
PushdownUtil.getTypeEnv(exprRef.getOp(), context);
+            ScanFilterCondition filterCondition = 
parseCondition(exprRef.getExpr(), typeEnv);
             if (filterCondition != null) {
                 filterConditions.add(filterCondition);
             }
         }
-
         return new ScanFilter(filterConditions);
     }

@@ -96,9 +110,7 @@
         if (!(logicalExpression instanceof AbstractFunctionCallExpression 
expr)) {
             return null;
         }
-
         FunctionIdentifier fi = expr.getFunctionIdentifier();
-
         if (!BTreeAccessMethod.INSTANCE.getOptimizableFunctions().contains(new 
Pair<>(fi, false))) {
             return null;
         }
@@ -137,6 +149,9 @@

             expr = functionCallExpr.getArguments().getFirst().getValue();
         }
+        if (fieldNames.isEmpty()) {
+            return null;
+        }

         VariableReferenceExpression varRef = (VariableReferenceExpression) 
expr;
         LogicalVariable var = varRef.getVariableReference();
@@ -145,23 +160,21 @@

     public static JoinFilter parseJoinNode(AbstractBinaryJoinOperator joinOp, 
IOptimizationContext context)
             throws AlgebricksException {
-        List<Mutable<ILogicalExpression>> joinExprs = new ArrayList<>();
-        IVariableTypeEnvironment typeEnv = PushdownUtil.getTypeEnv(joinOp, 
context);
-
+        List<ExprRef> joinExprs = new ArrayList<>();
         ILogicalExpression joinExpression = joinOp.getCondition().getValue();
         List<Mutable<ILogicalExpression>> conjs = new ArrayList<>();
         if (joinExpression.splitIntoConjuncts(conjs)) {
-            joinExprs.addAll(conjs);
+            joinExprs.addAll(conjs.stream().map(expr -> new ExprRef(expr, 
joinOp)).toList());
         } else {
-            joinExprs.add(joinOp.getCondition());
+            joinExprs.add(new ExprRef(joinOp.getCondition(), joinOp));
         }
-        joinExprs = OperatorManipulationUtil.cloneExpressions(joinExprs);
-        traverseAndReplace(joinOp, joinExprs);

+        traverseAndReplace(joinOp, joinExprs);
         List<JoinFilterCondition> joinConditions = new ArrayList<>();

-        for (Mutable<ILogicalExpression> joinExpr : joinExprs) {
-            JoinFilterCondition joinCondition = 
parseJoinCondition(joinExpr.getValue(), typeEnv);
+        for (ExprRef joinExprRef : joinExprs) {
+            IVariableTypeEnvironment typeEnv = 
PushdownUtil.getTypeEnv(joinExprRef.getOp(), context);
+            JoinFilterCondition joinCondition = 
parseJoinCondition(joinExprRef.getExpr(), typeEnv);
             if (joinCondition != null) {
                 joinConditions.add(joinCondition);
             }
@@ -170,25 +183,22 @@
         return new JoinFilter(joinConditions);
     }

-    private static void traverseAndReplace(AbstractLogicalOperator op, 
List<Mutable<ILogicalExpression>> exprs) {
-
+    private static void traverseAndReplace(AbstractLogicalOperator op, 
List<ExprRef> exprs) {
         if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
             replaceExprsWithAssign((AssignOperator) op, exprs);
         }
-
         for (Mutable<ILogicalOperator> input : op.getInputs()) {
             traverseAndReplace((AbstractLogicalOperator) input.getValue(), 
exprs);
         }
-
     }

-    public static void replaceExprsWithAssign(AssignOperator assignOp, 
List<Mutable<ILogicalExpression>> exprs) {
-        for (Mutable<ILogicalExpression> filterExpr : exprs) {
-            if (filterExpr.getValue().getExpressionTag() == 
LogicalExpressionTag.CONSTANT) {
+    private static void replaceExprsWithAssign(AssignOperator assignOp, 
List<ExprRef> exprRefs) {
+        for (ExprRef exprRef : exprRefs) {
+            if (exprRef.getExpr().getExpressionTag() == 
LogicalExpressionTag.CONSTANT) {
                 continue;
             }
             for (int i = 0; i < assignOp.getVariables().size(); i++) {
-                
OperatorManipulationUtil.replaceVarWithExpr((AbstractFunctionCallExpression) 
filterExpr.getValue(),
+                
OperatorManipulationUtil.replaceVarWithExpr((AbstractFunctionCallExpression) 
exprRef.getExpr(),
                         assignOp.getVariables().get(i), 
assignOp.getExpressions().get(i).getValue());
             }
         }
diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java
index ee487dd..1b33096 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/indexadvisor/FakeIndexProvider.java
@@ -20,6 +20,7 @@

 import static java.util.UUID.randomUUID;

+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -131,6 +132,9 @@
         for (Map.Entry<DatasetFullyQualifiedName, Set<List<String>>> entry : 
joinDataSourceFieldNamesMap.entrySet()) {
             DatasetFullyQualifiedName qualifiedName = entry.getKey();
             Set<List<String>> fieldNames = entry.getValue();
+            if (fieldNames.isEmpty()) {
+                continue;
+            }

             joinIndexEnumerator.init(fieldNames);
             Iterator<List<List<String>>> itr = 
joinIndexEnumerator.getIterator();
@@ -169,8 +173,8 @@
     @Override
     public List<Index> getDatasetIndexes(String database, DataverseName 
dataverseName, String datasetName)
             throws AlgebricksException {
-        return filterIndexesMap.get(new DatasetFullyQualifiedName(database, 
dataverseName, datasetName)).values()
-                .stream().toList();
+        return filterIndexesMap.getOrDefault(new 
DatasetFullyQualifiedName(database, dataverseName, datasetName),
+                Collections.emptyMap()).values().stream().toList();
     }

 }
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
index 59e6dc2..aff7850 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
@@ -312,6 +312,14 @@
             
builder.setNormalizedKeyComputerFactoryProvider(format.getNormalizedKeyComputerFactoryProvider());

             IndexAdvisor indexAdvisor = new IndexAdvisor(isAdviceOnly);
+
+            if (isAdviceOnly) {
+                if (!physOptConf.getCBOMode() && 
!physOptConf.getCBOTestMode()) {
+                    throw new CompilationException(ErrorCode.COMPILATION_ERROR,
+                            "Index advise cannot be used without CBO mode.");
+                }
+            }
+
             IRuleSetKind ruleSetKind = isAdviceOnly ? LOGICAL_ADVISOR : QUERY;
             ICompiler compiler = compilerFactory.createCompiler(plan, 
metadataProvider, t.getVarCounter(), ruleSetKind,
                     indexAdvisor);
diff --git 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java
 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java
index d381afa..1ba74ca 100644
--- 
a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java
+++ 
b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/base/IndexAdvisor.java
@@ -130,7 +130,6 @@
         }

         public String getCreateIndexClause() {
-
             return "CREATE INDEX " + indexName + " ON `" + databaseName + 
"`.`" + dataverseName + "`.`" + datasetName
                     + "`" + getKeyFieldNamesClause() + ";";
         }
diff --git 
a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
 
b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
index d7abf4c..d83270f 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
@@ -174,7 +174,8 @@
     INAPPLICABLE_HINT(10006),
     CROSS_PRODUCT_JOIN(10007),
     GROUP_ALL_DECOR(10008),
-    EXPRESSION_CANNOT_BE_CONSTANT(10009);
+    EXPRESSION_CANNOT_BE_CONSTANT(10009),
+    INDEX_ADVISOR_SAMPLE_NOT_FOUND(10010);

     private static final String RESOURCE_PATH = "errormsg/en.properties";
     public static final String HYRACKS = "HYR";
diff --git 
a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
 
b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
index e9569be..8e16262 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
+++ 
b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
@@ -163,4 +163,5 @@
 10006 = Could not apply %1$s hint: %2$s
 10007 = Encountered a cross product join
 10008 = Inappropriate use of group by all with decor variables
-10009 = '%1$s' expression cannot be a constant
\ No newline at end of file
+10009 = '%1$s' expression cannot be a constant
+10010 = No samples found for the collections in this query. Create samples 
with: '%1$s'
\ No newline at end of file

--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20282?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://asterix-gerrit.ics.uci.edu/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I346728dd634934416d7115a06ab15572b5a98854
Gerrit-Change-Number: 20282
Gerrit-PatchSet: 6
Gerrit-Owner: Preetham Poluparthi <[email protected]>
Gerrit-Reviewer: Ali Alsuliman <[email protected]>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <[email protected]>
Gerrit-Reviewer: Preetham Poluparthi <[email protected]>

Reply via email to