fix issue 166
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_stabilization_printerfix@955 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
index 830e33b..0bfa5c4 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
@@ -29,6 +29,7 @@
import edu.uci.ics.asterix.optimizer.rules.FuzzyJoinRule;
import edu.uci.ics.asterix.optimizer.rules.IfElseToSwitchCaseFunctionRule;
import edu.uci.ics.asterix.optimizer.rules.IntroduceDynamicTypeCastRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceEnforcedTypeRule;
import edu.uci.ics.asterix.optimizer.rules.IntroduceSecondaryIndexInsertDeleteRule;
import edu.uci.ics.asterix.optimizer.rules.IntroduceStaticTypeCastRule;
import edu.uci.ics.asterix.optimizer.rules.LoadRecordFieldsRule;
@@ -104,14 +105,15 @@
normalization.add(new BreakSelectIntoConjunctsRule());
normalization.add(new ExtractGbyExpressionsRule());
normalization.add(new ExtractDistinctByExpressionsRule());
- normalization.add(new ExtractOrderExpressionsRule());
+ normalization.add(new ExtractOrderExpressionsRule());
normalization.add(new ExtractCommonExpressionsRule());
-
+
// IntroduceStaticTypeCastRule should go before
// IntroduceDynamicTypeCastRule to
// avoid unnecessary dynamic casting
normalization.add(new IntroduceStaticTypeCastRule());
normalization.add(new IntroduceDynamicTypeCastRule());
+ normalization.add(new IntroduceEnforcedTypeRule());
normalization.add(new ConstantFoldingRule());
normalization.add(new UnnestToDataScanRule());
normalization.add(new IfElseToSwitchCaseFunctionRule());
@@ -122,7 +124,7 @@
public final static List<IAlgebraicRewriteRule> buildCondPushDownAndJoinInferenceRuleCollection() {
List<IAlgebraicRewriteRule> condPushDownAndJoinInference = new LinkedList<IAlgebraicRewriteRule>();
-
+
condPushDownAndJoinInference.add(new PushSelectDownRule());
condPushDownAndJoinInference.add(new PushDieUpRule());
condPushDownAndJoinInference.add(new RemoveRedundantListifyRule());
@@ -136,17 +138,17 @@
condPushDownAndJoinInference.add(new IntroduceGroupByForSubplanRule());
condPushDownAndJoinInference.add(new SubplanOutOfGroupRule());
condPushDownAndJoinInference.add(new InsertOuterJoinRule());
-
+
condPushDownAndJoinInference.add(new RemoveRedundantVariablesRule());
condPushDownAndJoinInference.add(new AsterixInlineVariablesRule());
condPushDownAndJoinInference.add(new RemoveUnusedAssignAndAggregateRule());
-
+
condPushDownAndJoinInference.add(new FactorRedundantGroupAndDecorVarsRule());
condPushDownAndJoinInference.add(new PushAggregateIntoGroupbyRule());
condPushDownAndJoinInference.add(new EliminateSubplanRule());
condPushDownAndJoinInference.add(new PushProperJoinThroughProduct());
condPushDownAndJoinInference.add(new PushGroupByThroughProduct());
- condPushDownAndJoinInference.add(new NestGroupByRule());
+ condPushDownAndJoinInference.add(new NestGroupByRule());
return condPushDownAndJoinInference;
}
@@ -162,7 +164,7 @@
fieldLoads.add(new RemoveUnusedAssignAndAggregateRule());
fieldLoads.add(new ConstantFoldingRule());
fieldLoads.add(new FeedScanCollectionToUnnest());
- fieldLoads.add(new ComplexJoinInferenceRule());
+ fieldLoads.add(new ComplexJoinInferenceRule());
return fieldLoads;
}
@@ -185,17 +187,17 @@
consolidation.add(new RemoveRedundantGroupByDecorVars());
return consolidation;
}
-
+
public final static List<IAlgebraicRewriteRule> buildAccessMethodRuleCollection() {
List<IAlgebraicRewriteRule> accessMethod = new LinkedList<IAlgebraicRewriteRule>();
accessMethod.add(new IntroduceSelectAccessMethodRule());
accessMethod.add(new IntroduceJoinAccessMethodRule());
- accessMethod.add(new IntroduceSecondaryIndexInsertDeleteRule());
+ accessMethod.add(new IntroduceSecondaryIndexInsertDeleteRule());
return accessMethod;
}
public final static List<IAlgebraicRewriteRule> buildPlanCleanupRuleCollection() {
- List<IAlgebraicRewriteRule> planCleanupRules = new LinkedList<IAlgebraicRewriteRule>();
+ List<IAlgebraicRewriteRule> planCleanupRules = new LinkedList<IAlgebraicRewriteRule>();
planCleanupRules.add(new PushAssignBelowUnionAllRule());
planCleanupRules.add(new ExtractCommonExpressionsRule());
planCleanupRules.add(new PushProjectDownRule());
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java
index 7b311d3..4a1f1fa 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/ConstantFoldingRule.java
@@ -174,7 +174,8 @@
if (expr.getFunctionIdentifier().equals(AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR)
|| expr.getFunctionIdentifier().equals(AsterixBuiltinFunctions.ORDERED_LIST_CONSTRUCTOR)) {
AbstractCollectionType listType = (AbstractCollectionType) TypeComputerUtilities.getRequiredType(expr);
- if (listType != null && listType.getItemType().getTypeTag() == ATypeTag.ANY) {
+ if (listType != null
+ && (listType.getItemType().getTypeTag() == ATypeTag.ANY || listType.getItemType() instanceof AbstractCollectionType)) {
return new Pair<Boolean, ILogicalExpression>(false, null);
}
}
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceEnforcedTypeRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceEnforcedTypeRule.java
new file mode 100644
index 0000000..5077c4b
--- /dev/null
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceEnforcedTypeRule.java
@@ -0,0 +1,71 @@
+package edu.uci.ics.asterix.optimizer.rules;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.optimizer.rules.typecast.StaticTypeCastUtil;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractAssignOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestOperator;
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+
+public class IntroduceEnforcedTypeRule implements IAlgebraicRewriteRule {
+
+ @Override
+ public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+ return false;
+ }
+
+ @Override
+ public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+ throws AlgebricksException {
+ if (context.checkIfInDontApplySet(this, opRef.getValue()))
+ return false;
+ AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
+ context.addToDontApplySet(this, opRef.getValue());
+ boolean changed = false;
+ if (op1.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
+ AbstractAssignOperator assignOp = (AbstractAssignOperator) op1;
+ List<Mutable<ILogicalExpression>> expressions = assignOp.getExpressions();
+ IVariableTypeEnvironment env = assignOp.computeOutputTypeEnvironment(context);
+ changed = rewriteExpressions(expressions, env);
+ }
+ if (op1.getOperatorTag() == LogicalOperatorTag.UNNEST) {
+ AbstractUnnestOperator unnestOp = (AbstractUnnestOperator) op1;
+ List<Mutable<ILogicalExpression>> expressions = Collections.singletonList(unnestOp.getExpressionRef());
+ IVariableTypeEnvironment env = unnestOp.computeOutputTypeEnvironment(context);
+ changed = rewriteExpressions(expressions, env);
+ }
+ return changed;
+ }
+
+ private boolean rewriteExpressions(List<Mutable<ILogicalExpression>> expressions, IVariableTypeEnvironment env)
+ throws AlgebricksException {
+ boolean changed = false;
+ for (Mutable<ILogicalExpression> exprRef : expressions) {
+ ILogicalExpression expr = exprRef.getValue();
+ if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ AbstractFunctionCallExpression argFuncExpr = (AbstractFunctionCallExpression) expr;
+ if (argFuncExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.ORDERED_LIST_CONSTRUCTOR
+ || argFuncExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
+ IAType exprType = (IAType) env.getType(argFuncExpr);
+ changed = changed || StaticTypeCastUtil.rewriteFuncExpr(argFuncExpr, exprType, exprType, env);
+ }
+ }
+ }
+ return changed;
+ }
+
+}
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
index 6c0b1d6..c128d5a 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
@@ -30,23 +30,47 @@
public class StaticTypeCastUtil {
- public static void rewriteFuncExpr(AbstractFunctionCallExpression funcExpr, IAType reqType, IAType inputType,
+ public static boolean rewriteFuncExpr(AbstractFunctionCallExpression funcExpr, IAType reqType, IAType inputType,
IVariableTypeEnvironment env) throws AlgebricksException {
if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.UNORDERED_LIST_CONSTRUCTOR) {
if (reqType.equals(BuiltinType.ANY)) {
reqType = DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
}
- rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
+ //else {
+ // AbstractCollectionType listType = (AbstractCollectionType) reqType;
+ // if (listType.getItemType() instanceof AbstractCollectionType)
+ // reqType = DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
+ //}
+ return rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType,
+ env);
} else if (funcExpr.getFunctionIdentifier() == AsterixBuiltinFunctions.ORDERED_LIST_CONSTRUCTOR) {
if (reqType.equals(BuiltinType.ANY)) {
reqType = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
}
- rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType, env);
+ //else {
+ // AbstractCollectionType listType = (AbstractCollectionType) reqType;
+ // if (listType.getItemType() instanceof AbstractCollectionType)
+ // reqType = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
+ //}
+ return rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType,
+ env);
} else if (inputType.getTypeTag().equals(ATypeTag.RECORD)) {
if (reqType.equals(BuiltinType.ANY)) {
reqType = DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
}
- rewriteRecordFuncExpr(funcExpr, (ARecordType) reqType, (ARecordType) inputType, env);
+ return rewriteRecordFuncExpr(funcExpr, (ARecordType) reqType, (ARecordType) inputType, env);
+ } else {
+ List<Mutable<ILogicalExpression>> args = funcExpr.getArguments();
+ boolean changed = false;
+ for (Mutable<ILogicalExpression> arg : args) {
+ ILogicalExpression argExpr = arg.getValue();
+ if (argExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ AbstractFunctionCallExpression argFuncExpr = (AbstractFunctionCallExpression) argExpr;
+ IAType exprType = (IAType) env.getType(argFuncExpr);
+ changed = changed || rewriteFuncExpr(argFuncExpr, exprType, exprType, env);
+ }
+ }
+ return changed;
}
}
@@ -62,13 +86,15 @@
* type environment
* @throws AlgebricksException
*/
- private static void rewriteRecordFuncExpr(AbstractFunctionCallExpression funcExpr, ARecordType requiredRecordType,
- ARecordType inputRecordType, IVariableTypeEnvironment env) throws AlgebricksException {
+ private static boolean rewriteRecordFuncExpr(AbstractFunctionCallExpression funcExpr,
+ ARecordType requiredRecordType, ARecordType inputRecordType, IVariableTypeEnvironment env)
+ throws AlgebricksException {
// if already rewritten, the required type is not null
if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
- return;
+ return false;
TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredRecordType, inputRecordType);
staticRecordTypeCast(funcExpr, requiredRecordType, inputRecordType, env);
+ return true;
}
/**
@@ -83,11 +109,11 @@
* type environment
* @throws AlgebricksException
*/
- private static void rewriteListFuncExpr(AbstractFunctionCallExpression funcExpr,
+ private static boolean rewriteListFuncExpr(AbstractFunctionCallExpression funcExpr,
AbstractCollectionType requiredListType, AbstractCollectionType inputListType, IVariableTypeEnvironment env)
throws AlgebricksException {
if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
- return;
+ return false;
TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredListType, inputListType);
List<Mutable<ILogicalExpression>> args = funcExpr.getArguments();
@@ -107,6 +133,7 @@
}
}
}
+ return true;
}
private static void staticRecordTypeCast(AbstractFunctionCallExpression func, ARecordType reqType,
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue166.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue166.aql
new file mode 100644
index 0000000..b01bfe1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue166.aql
@@ -0,0 +1,4 @@
+write output to nc1:"rttest/open-closed_query-issue166.adm";
+
+let $a := [[1,2,3],[4,5,6,7]]
+return $a[1]
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/query-issue166.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/query-issue166.adm
new file mode 100644
index 0000000..b5897af
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/query-issue166.adm
@@ -0,0 +1 @@
+[ 4, 5, 6, 7 ]
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 3235a6d..b80c499 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -2314,6 +2314,11 @@
<output-file compare="Text">query-issue55-1.adm</output-file>
</compilation-unit>
</test-case>
+ <test-case FilePath="open-closed">
+ <compilation-unit name="query-issue166">
+ <output-file compare="Text">query-issue166.adm</output-file>
+ </compilation-unit>
+ </test-case>
<!--
<test-case FilePath="open-closed">
<compilation-unit name="open-closed-15">