Steven Jacobs has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/367

Change subject: Convert comparisons with current-datetime, current-date, and 
current-time to applicable index searches as though they were constants
......................................................................

Convert comparisons with current-datetime, current-date, and current-time to 
applicable index searches as though they were constants

Change-Id: Ied64276873afcfbdd31dac313009e47429d8f9b0
---
M 
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
M 
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
M 
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
M 
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
M 
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
M 
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
M 
asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java
A 
asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-01.aql
A 
asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-02.aql
A 
asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-03.aql
A 
asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-01.plan
A 
asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-02.plan
A 
asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-03.plan
M asterix-runtime/pom.xml
14 files changed, 280 insertions(+), 36 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/67/367/1

diff --git 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
index a8863ed..5d65047 100644
--- 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
+++ 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
@@ -15,6 +15,8 @@
 package org.apache.asterix.optimizer.rules;
 
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.optimizer.rules.am.AccessMethodUtils;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.rewriter.rules.InlineVariablesRule;
 
 public class AsterixInlineVariablesRule extends InlineVariablesRule {
@@ -35,4 +37,10 @@
         doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_POLYGON);
         doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_RECTANGLE);
     }
+
+    @Override
+    protected boolean createException(ILogicalExpression expr) {
+        return AccessMethodUtils.exprCreatesConstant(expr).first;
+    }
+
 }
diff --git 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
index 166fdf2..61cf45a 100644
--- 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
+++ 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
@@ -21,8 +21,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.lang3.mutable.Mutable;
-
 import org.apache.asterix.common.config.DatasetConfig.IndexType;
 import org.apache.asterix.dataflow.data.common.AqlExpressionTypeComputer;
 import org.apache.asterix.metadata.api.IMetadataEntity;
@@ -40,6 +38,7 @@
 import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import 
org.apache.asterix.optimizer.rules.am.OptimizableOperatorSubTree.DataSourceType;
+import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.utils.Pair;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
@@ -220,8 +219,19 @@
                             indexedTypes.add(optFuncExpr.getFieldType(j));
                     //add constants in case of select
                     if (indexedTypes.size() < 2 && 
optFuncExpr.getNumLogicalVars() == 1) {
-                        indexedTypes.add((IAType) 
AqlExpressionTypeComputer.INSTANCE.getType(new ConstantExpression(
-                                optFuncExpr.getConstantVal(0)), null, null));
+                        if (optFuncExpr.getConstantVal(0) == null) {
+                            //add type to indexTypes from current-*, if 
applicable
+                            IAType constantType = 
optFuncExpr.getConstantType(0);
+                            if (constantType != null) {
+                                indexedTypes.add(constantType);
+                                optFuncExpr.setConstType(0, constantType);
+                            }
+
+                        } else {
+                            //We are looking at an actual constant. Just add 
the type.
+                            indexedTypes.add((IAType) 
AqlExpressionTypeComputer.INSTANCE.getType(
+                                    new 
ConstantExpression(optFuncExpr.getConstantVal(0)), null, null));
+                        }
                     }
                     //infer type of logicalExpr based on index keyType
                     indexedTypes.add((IAType) 
AqlExpressionTypeComputer.INSTANCE.getType(
diff --git 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
index 016e214..83e1bbb 100644
--- 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
+++ 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
@@ -17,10 +17,8 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
-
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.commons.lang3.mutable.MutableObject;
 
 import 
org.apache.asterix.algebra.operators.physical.ExternalDataLookupPOperator;
 import org.apache.asterix.aql.util.FunctionUtils;
@@ -40,9 +38,12 @@
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.asterix.om.util.NonTaggedFormatUtil;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
 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;
@@ -120,30 +121,55 @@
     public static boolean 
analyzeFuncExprArgsForOneConstAndVar(AbstractFunctionCallExpression funcExpr,
             AccessMethodAnalysisContext analysisCtx) {
         IAlgebricksConstantValue constFilterVal = null;
+        IAType constValType = null;
         LogicalVariable fieldVar = null;
+        ILogicalExpression constValExpr = null;
         ILogicalExpression arg1 = funcExpr.getArguments().get(0).getValue();
         ILogicalExpression arg2 = funcExpr.getArguments().get(1).getValue();
         // One of the args must be a constant, and the other arg must be a 
variable.
-        if (arg1.getExpressionTag() == LogicalExpressionTag.CONSTANT
-                && arg2.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+        if (arg2.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
             // The arguments of contains() function are asymmetrical, we can 
only use index if it is on the first argument
             if (funcExpr.getFunctionIdentifier() == 
AsterixBuiltinFunctions.CONTAINS) {
                 return false;
             }
-            ConstantExpression constExpr = (ConstantExpression) arg1;
-            constFilterVal = constExpr.getValue();
+            Pair<Boolean, IAType> recursiveTypes = exprCreatesConstant(arg1);
+            if (!recursiveTypes.first) {
+                return false;
+            }
+            ConstantExpression constExpr = new ConstantExpression(null);
+            if (arg1.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
+                constExpr = (ConstantExpression) arg1;
+                constFilterVal = constExpr.getValue();
+            } else {
+                //we are looking at a current-* so there isn't a constantvalue 
but we know the type
+                constFilterVal = null;
+                constValType = recursiveTypes.second;
+                constValExpr = arg1;
+            }
             VariableReferenceExpression varExpr = 
(VariableReferenceExpression) arg2;
             fieldVar = varExpr.getVariableReference();
-        } else if (arg1.getExpressionTag() == LogicalExpressionTag.VARIABLE
-                && arg2.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
-            ConstantExpression constExpr = (ConstantExpression) arg2;
-            constFilterVal = constExpr.getValue();
+        } else if (arg1.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+            Pair<Boolean, IAType> recursiveTypes = exprCreatesConstant(arg2);
+            if (!recursiveTypes.first) {
+                return false;
+            }
+            ConstantExpression constExpr = new ConstantExpression(null);
+            if (arg2.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
+                constExpr = (ConstantExpression) arg2;
+                constFilterVal = constExpr.getValue();
+            } else {
+                //we are looking at a current-* so there isn't a constantvalue 
but we know the type
+                constFilterVal = null;
+                constValType = recursiveTypes.second;
+                constValExpr = arg2;
+            }
             VariableReferenceExpression varExpr = 
(VariableReferenceExpression) arg1;
             fieldVar = varExpr.getVariableReference();
         } else {
             return false;
         }
-        OptimizableFuncExpr newOptFuncExpr = new OptimizableFuncExpr(funcExpr, 
fieldVar, constFilterVal);
+        OptimizableFuncExpr newOptFuncExpr = new OptimizableFuncExpr(funcExpr, 
fieldVar, constFilterVal, constValType,
+                constValExpr);
         for (IOptimizableFuncExpr optFuncExpr : analysisCtx.matchedFuncExprs) {
             //avoid additional optFuncExpressions in case of a join
             if (optFuncExpr.getFuncExpr().equals(funcExpr))
@@ -167,7 +193,7 @@
             return false;
         }
         OptimizableFuncExpr newOptFuncExpr = new OptimizableFuncExpr(funcExpr, 
new LogicalVariable[] { fieldVar1,
-                fieldVar2 }, null);
+                fieldVar2 }, null, null, null);
         for (IOptimizableFuncExpr optFuncExpr : analysisCtx.matchedFuncExprs) {
             //avoid additional optFuncExpressions in case of a join
             if (optFuncExpr.getFuncExpr().equals(funcExpr))
@@ -304,7 +330,7 @@
      * Returns the search key expression which feeds a secondary-index search. 
If we are optimizing a selection query then this method returns
      * the a ConstantExpression from the first constant value in the 
optimizable function expression.
      * If we are optimizing a join, then this method returns the 
VariableReferenceExpression that should feed the secondary index probe.
-     *
+     * 
      * @throws AlgebricksException
      */
     public static Pair<ILogicalExpression, Boolean> 
createSearchKeyExpr(IOptimizableFuncExpr optFuncExpr,
@@ -314,8 +340,17 @@
             // We are optimizing a selection query. Search key is a constant.
             // Type Checking and type promotion is done here
             IAType fieldType = optFuncExpr.getFieldType(0);
-            IAObject constantObj = ((AsterixConstantValue) 
optFuncExpr.getConstantVal(0)).getObject();
-            ATypeTag constantValueTag = constantObj.getType().getTypeTag();
+
+            IAObject constantObj = null;
+            ATypeTag constantValueTag = null;
+
+            if (optFuncExpr.getConstantVal(0) == null) {
+                constantValueTag = optFuncExpr.getConstantType(0).getTypeTag();
+            } else {
+                constantObj = ((AsterixConstantValue) 
optFuncExpr.getConstantVal(0)).getObject();
+                constantValueTag = constantObj.getType().getTypeTag();
+            }
+
             // type casting applied?
             boolean typeCastingApplied = false;
             // type casting happened from real (FLOAT, DOUBLE) value -> INT 
value?
@@ -354,8 +389,12 @@
                 return new Pair<ILogicalExpression, Boolean>(new 
ConstantExpression(replacedConstantValue),
                         realTypeConvertedToIntegerType);
             } else {
-                return new Pair<ILogicalExpression, Boolean>(new 
ConstantExpression(optFuncExpr.getConstantVal(0)),
-                        false);
+                if (constantObj != null) {
+                    return new Pair<ILogicalExpression, Boolean>(new 
ConstantExpression(optFuncExpr.getConstantVal(0)),
+                            false);
+                } else {
+                    return new Pair<ILogicalExpression, 
Boolean>(optFuncExpr.getConstantExpr(0), false);
+                }
             }
         } else {
             // We are optimizing a join query. Determine which variable feeds 
the secondary index.
@@ -606,4 +645,43 @@
                 secondaryIndex, primaryKeyVars, false, retainInput, 
retainNull));
         return externalLookupOp;
     }
+
+    public static Pair<Boolean, IAType> exprCreatesConstant(ILogicalExpression 
expr) {
+        Pair<Boolean, List<IAType>> allTypes = exprCreatesConstantList(expr);
+        if (allTypes.second == null || allTypes.second.size() > 1) {
+            return new Pair<Boolean, IAType>(false, null);
+        } else if (allTypes.second.size() == 0) {
+            return new Pair<Boolean, IAType>(true, null);
+        }
+        return new Pair<Boolean, IAType>(true, allTypes.second.get(0));
+    }
+
+    public static Pair<Boolean, List<IAType>> 
exprCreatesConstantList(ILogicalExpression expr) {
+        if (expr instanceof AbstractFunctionCallExpression) {
+            if (((AbstractFunctionCallExpression) 
expr).getFunctionIdentifier() == AsterixBuiltinFunctions.CURRENT_DATE) {
+                return new Pair<Boolean, List<IAType>>(true, new 
ArrayList<IAType>(Arrays.asList(BuiltinType.ADATE)));
+            } else if (((AbstractFunctionCallExpression) 
expr).getFunctionIdentifier() == AsterixBuiltinFunctions.CURRENT_TIME) {
+                return new Pair<Boolean, List<IAType>>(true, new 
ArrayList<IAType>(Arrays.asList(BuiltinType.ATIME)));
+            } else if (((AbstractFunctionCallExpression) 
expr).getFunctionIdentifier() == AsterixBuiltinFunctions.CURRENT_DATETIME) {
+                return new Pair<Boolean, List<IAType>>(true,
+                        new 
ArrayList<IAType>(Arrays.asList(BuiltinType.ADATETIME)));
+            } else {
+                List<IAType> subTypes = new ArrayList<IAType>();
+                for (Mutable<ILogicalExpression> subExpr : 
((AbstractFunctionCallExpression) expr).getArguments()) {
+                    Pair<Boolean, List<IAType>> recursiveTypes = 
exprCreatesConstantList(subExpr.getValue());
+                    if (recursiveTypes.first == false) {
+                        return new Pair<Boolean, List<IAType>>(false, null);
+                    } else {
+                        subTypes.addAll(recursiveTypes.second);
+                    }
+                }
+                return new Pair<Boolean, List<IAType>>(true, subTypes);
+            }
+        } else if (expr instanceof ConstantExpression) {
+            return new Pair<Boolean, List<IAType>>(true, new 
ArrayList<IAType>());
+        } else {
+            return new Pair<Boolean, List<IAType>>(false, null);
+        }
+    }
+
 }
diff --git 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
index 641250c..a9c8c3b 100644
--- 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
+++ 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
@@ -24,9 +24,6 @@
 import java.util.List;
 import java.util.Set;
 
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.commons.lang3.mutable.MutableObject;
-
 import org.apache.asterix.aql.util.FunctionUtils;
 import 
org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
 import org.apache.asterix.common.config.DatasetConfig.DatasetType;
@@ -35,6 +32,8 @@
 import org.apache.asterix.metadata.entities.Index;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.optimizer.rules.util.EquivalenceClassUtils;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
 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;
@@ -43,6 +42,7 @@
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.IndexedNLJoinExpressionAnnotation;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
@@ -230,6 +230,8 @@
         LimitType[] highKeyLimits = new LimitType[numSecondaryKeys];
         boolean[] lowKeyInclusive = new boolean[numSecondaryKeys];
         boolean[] highKeyInclusive = new boolean[numSecondaryKeys];
+        ILogicalExpression[] constExpressions = new 
ILogicalExpression[numSecondaryKeys];
+        LogicalVariable[] constExprVars = new 
LogicalVariable[numSecondaryKeys];
 
         // TODO: For now we don't do any sophisticated analysis of the func 
exprs to come up with "the best" range predicate.
         // If we can't figure out how to integrate a certain funcExpr into the 
current predicate, we just bail by setting this flag.
@@ -263,6 +265,13 @@
             Pair<ILogicalExpression, Boolean> returnedSearchKeyExpr = 
AccessMethodUtils.createSearchKeyExpr(
                     optFuncExpr, indexSubTree, probeSubTree);
             ILogicalExpression searchKeyExpr = returnedSearchKeyExpr.first;
+            if (!(searchKeyExpr instanceof ConstantExpression)
+                    && !(searchKeyExpr instanceof 
VariableReferenceExpression)) {
+                constExpressions[keyPos] = searchKeyExpr;
+                constExprVars[keyPos] = context.newVar();
+                searchKeyExpr = new 
VariableReferenceExpression(constExprVars[keyPos]);
+
+            }
             realTypeConvertedToIntegerType = returnedSearchKeyExpr.second;
 
             LimitType limit = getLimitType(optFuncExpr, probeSubTree);
@@ -442,9 +451,9 @@
         ArrayList<LogicalVariable> assignKeyVarList = new 
ArrayList<LogicalVariable>();
         ArrayList<Mutable<ILogicalExpression>> assignKeyExprList = new 
ArrayList<Mutable<ILogicalExpression>>();
         int numLowKeys = createKeyVarsAndExprs(numSecondaryKeys, lowKeyLimits, 
lowKeyExprs, assignKeyVarList,
-                assignKeyExprList, keyVarList, context);
+                assignKeyExprList, keyVarList, context, constExpressions, 
constExprVars);
         int numHighKeys = createKeyVarsAndExprs(numSecondaryKeys, 
highKeyLimits, highKeyExprs, assignKeyVarList,
-                assignKeyExprList, keyVarList, context);
+                assignKeyExprList, keyVarList, context, constExpressions, 
constExprVars);
 
         BTreeJobGenParams jobGenParams = new 
BTreeJobGenParams(chosenIndex.getIndexName(), IndexType.BTREE,
                 dataset.getDataverseName(), dataset.getDatasetName(), 
retainInput, retainNull, requiresBroadcast);
@@ -522,12 +531,14 @@
 
     private int createKeyVarsAndExprs(int numKeys, LimitType[] keyLimits, 
ILogicalExpression[] searchKeyExprs,
             ArrayList<LogicalVariable> assignKeyVarList, 
ArrayList<Mutable<ILogicalExpression>> assignKeyExprList,
-            ArrayList<LogicalVariable> keyVarList, IOptimizationContext 
context) {
+            ArrayList<LogicalVariable> keyVarList, IOptimizationContext 
context, ILogicalExpression[] constExpressions,
+            LogicalVariable[] constExprVars) {
         if (keyLimits[0] == null) {
             return 0;
         }
         for (int i = 0; i < numKeys; i++) {
             ILogicalExpression searchKeyExpr = searchKeyExprs[i];
+            ILogicalExpression constExpression = constExpressions[i];
             LogicalVariable keyVar = null;
             if (searchKeyExpr.getExpressionTag() == 
LogicalExpressionTag.CONSTANT) {
                 keyVar = context.newVar();
@@ -535,6 +546,10 @@
                 assignKeyVarList.add(keyVar);
             } else {
                 keyVar = ((VariableReferenceExpression) 
searchKeyExpr).getVariableReference();
+                if (constExpression != null) {
+                    assignKeyExprList.add(new 
MutableObject<ILogicalExpression>(constExpression));
+                    assignKeyVarList.add(constExprVars[i]);
+                }
             }
             keyVarList.add(keyVar);
         }
diff --git 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
index b6d188a..db58241 100644
--- 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
+++ 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/IOptimizableFuncExpr.java
@@ -67,4 +67,12 @@
     public void setSourceVar(int index, LogicalVariable var);
 
     public LogicalVariable getSourceVar(int index);
+
+    void setConstType(int index, IAType fieldType);
+
+    IAType getConstantType(int index);
+
+    ILogicalExpression getConstantExpr(int index);
+
+    void setConstExpr(int index, ILogicalExpression expr);
 }
diff --git 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
index 783fa11..76f1fe4 100644
--- 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
+++ 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
@@ -20,9 +20,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.commons.lang3.mutable.MutableObject;
-
 import org.apache.asterix.algebra.base.LogicalOperatorDeepCopyVisitor;
 import org.apache.asterix.aql.util.FunctionUtils;
 import 
org.apache.asterix.common.annotations.SkipSecondaryIndexSearchExpressionAnnotation;
@@ -43,6 +40,8 @@
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.utils.Triple;
 import org.apache.hyracks.algebricks.core.algebra.base.Counter;
@@ -245,7 +244,7 @@
             return false;
         }
         OptimizableFuncExpr newOptFuncExpr = new OptimizableFuncExpr(funcExpr, 
new LogicalVariable[] { fieldVarExpr1,
-                fieldVarExpr2 }, new IAlgebricksConstantValue[] { 
constThreshVal });
+                fieldVarExpr2 }, new IAlgebricksConstantValue[] { 
constThreshVal }, null, null);
         for (IOptimizableFuncExpr optFuncExpr : analysisCtx.matchedFuncExprs) {
             //avoid additional optFuncExpressions in case of a join
             if (optFuncExpr.getFuncExpr().equals(funcExpr)) {
@@ -295,7 +294,7 @@
             return false;
         }
         OptimizableFuncExpr newOptFuncExpr = new OptimizableFuncExpr(funcExpr, 
new LogicalVariable[] { fieldVarExpr },
-                new IAlgebricksConstantValue[] { constFilterVal, 
constThreshVal });
+                new IAlgebricksConstantValue[] { constFilterVal, 
constThreshVal }, null, null);
         for (IOptimizableFuncExpr optFuncExpr : analysisCtx.matchedFuncExprs) {
             //avoid additional optFuncExpressions in case of a join
             if (optFuncExpr.getFuncExpr().equals(funcExpr))
diff --git 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java
 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java
index f284b2a..b433016 100644
--- 
a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java
+++ 
b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableFuncExpr.java
@@ -37,15 +37,20 @@
     protected final IAType[] fieldTypes;
     protected final OptimizableOperatorSubTree[] subTrees;
     protected final IAlgebricksConstantValue[] constantVals;
+    protected final IAType[] constantExpressionTypes;
+    protected final ILogicalExpression[] constantExpressions;
     protected boolean partialField;
 
     public OptimizableFuncExpr(AbstractFunctionCallExpression funcExpr, 
LogicalVariable[] logicalVars,
-            IAlgebricksConstantValue[] constantVals) {
+            IAlgebricksConstantValue[] constantVals, IAType[] 
constantExpressionTypes,
+            ILogicalExpression[] constantExpressions) {
         this.funcExpr = funcExpr;
         this.logicalVars = logicalVars;
         this.sourceVars = new LogicalVariable[logicalVars.length];
         this.logicalExprs = new ILogicalExpression[logicalVars.length];
         this.constantVals = constantVals;
+        this.constantExpressionTypes = constantExpressionTypes;
+        this.constantExpressions = constantExpressions;
         this.fieldNames = new ArrayList<List<String>>();
         for (int i = 0; i < logicalVars.length; i++) {
             fieldNames.add(new ArrayList<String>());
@@ -62,12 +67,14 @@
 
     // Special, more convenient c'tor for simple binary functions.
     public OptimizableFuncExpr(AbstractFunctionCallExpression funcExpr, 
LogicalVariable logicalVar,
-            IAlgebricksConstantValue constantVal) {
+            IAlgebricksConstantValue constantVal, IAType 
constantExpressionType, ILogicalExpression constantExpression) {
         this.funcExpr = funcExpr;
         this.logicalVars = new LogicalVariable[] { logicalVar };
         this.sourceVars = new LogicalVariable[1];
         this.logicalExprs = new ILogicalExpression[1];
         this.constantVals = new IAlgebricksConstantValue[] { constantVal };
+        this.constantExpressionTypes = new IAType[] { constantExpressionType };
+        this.constantExpressions = new ILogicalExpression[] { 
constantExpression };
         this.fieldNames = new ArrayList<List<String>>();
         for (int i = 0; i < logicalVars.length; i++) {
             fieldNames.add(new ArrayList<String>());
@@ -137,6 +144,26 @@
     }
 
     @Override
+    public void setConstType(int index, IAType fieldType) {
+        constantExpressionTypes[index] = fieldType;
+    }
+
+    @Override
+    public IAType getConstantType(int index) {
+        return constantExpressionTypes[index];
+    }
+
+    @Override
+    public void setConstExpr(int index, ILogicalExpression expr) {
+        constantExpressions[index] = expr;
+    }
+
+    @Override
+    public ILogicalExpression getConstantExpr(int index) {
+        return constantExpressions[index];
+    }
+
+    @Override
     public int findLogicalVar(LogicalVariable var) {
         for (int i = 0; i < logicalVars.length; i++) {
             if (var == logicalVars[i]) {
diff --git 
a/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-01.aql
 
b/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-01.aql
new file mode 100644
index 0000000..f387ecf
--- /dev/null
+++ 
b/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-01.aql
@@ -0,0 +1,25 @@
+/*
+ *  Description     : This test is intended to verify that the primary BTree 
index is used 
+ *                  : for an invocation of current-datetime()
+ *  Expected Result : Success
+ *  Date            : 27th Aug 2015
+ *     Author                  : Steven Jacobs
+ */
+
+drop dataverse emergencyTest if exists;
+create dataverse emergencyTest;
+use dataverse emergencyTest;
+create type CHPReport as {
+        "id":int,
+       "timestamp":datetime,
+        "title":string,
+        "message":string
+}
+create dataset CHPReports(CHPReport)
+primary key timestamp;
+
+for $emergency in dataset CHPReports
+where $emergency.timestamp >= current-datetime() - day-time-duration("PT10H")
+and $emergency.title = "ghost"
+return $emergency.message;
+
diff --git 
a/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-02.aql
 
b/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-02.aql
new file mode 100644
index 0000000..b4ec845
--- /dev/null
+++ 
b/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-02.aql
@@ -0,0 +1,24 @@
+/*
+ *  Description     : This test is intended to verify that the primary BTree 
index is used 
+ *                  : for an invocation of current-datetime()
+ *  Expected Result : Success
+ *  Date            : 27th Aug 2015
+ *     Author                  : Steven Jacobs
+ */
+
+drop dataverse emergencyTest if exists;
+create dataverse emergencyTest;
+use dataverse emergencyTest;
+create type CHPReport as {
+        "id":int,
+       "timestamp":datetime,
+        "title":string,
+        "message":string
+}
+create dataset CHPReports(CHPReport)
+primary key timestamp;
+
+for $emergency in dataset CHPReports
+let $time := current-datetime() - day-time-duration("PT10H")
+where $emergency.timestamp >= $time
+return $emergency;
\ No newline at end of file
diff --git 
a/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-03.aql
 
b/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-03.aql
new file mode 100644
index 0000000..56714e5
--- /dev/null
+++ 
b/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-datetime-03.aql
@@ -0,0 +1,23 @@
+/*
+ *  Description     : This test is intended to verify that the primary BTree 
index is used 
+ *                  : for an invocation of current-datetime()
+ *  Expected Result : Success
+ *  Date            : 27th Aug 2015
+ *     Author                  : Steven Jacobs
+ */
+
+drop dataverse emergencyTest if exists;
+create dataverse emergencyTest;
+use dataverse emergencyTest;
+create type CHPReport as {
+        "id":int,
+       "timestamp":datetime,
+        "title":string,
+        "message":string
+}
+create dataset CHPReports(CHPReport)
+primary key timestamp;
+
+for $emergency in dataset CHPReports
+where $emergency.timestamp >= current-datetime() 
+return $emergency;
\ No newline at end of file
diff --git 
a/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-01.plan
 
b/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-01.plan
new file mode 100644
index 0000000..9b5e82c
--- /dev/null
+++ 
b/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-01.plan
@@ -0,0 +1,11 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- STREAM_SELECT  |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/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-02.plan
 
b/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-02.plan
new file mode 100644
index 0000000..a9e223a
--- /dev/null
+++ 
b/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-02.plan
@@ -0,0 +1,8 @@
+-- DISTRIBUTE_RESULT  |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/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-03.plan
 
b/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-03.plan
new file mode 100644
index 0000000..a9e223a
--- /dev/null
+++ 
b/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-datetime-03.plan
@@ -0,0 +1,8 @@
+-- DISTRIBUTE_RESULT  |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/asterix-runtime/pom.xml b/asterix-runtime/pom.xml
index 2dffa3f..f08eb4f 100644
--- a/asterix-runtime/pom.xml
+++ b/asterix-runtime/pom.xml
@@ -49,7 +49,7 @@
                        <version>0.8.7-SNAPSHOT</version>
                        <configuration>
                                
<grammarFile>src/main/resources/adm.grammar</grammarFile>
-                               
<outputDir>${project.build.directory}/generated-sources/org.apache/asterix/runtime/operators/file/adm</outputDir>
+                               
<outputDir>${project.build.directory}/generated-sources/org/apache/asterix/runtime/operators/file/adm</outputDir>
                        </configuration>
                        <executions>
                                <execution>

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/367
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ied64276873afcfbdd31dac313009e47429d8f9b0
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Steven Jacobs <[email protected]>

Reply via email to