This is an automated email from the ASF dual-hosted git repository. alsuliman pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb.git
The following commit(s) were added to refs/heads/master by this push: new 79f39fd [NO ISSUE][COMP] Extension to InjectTypeCastForFunctionArgumentsRule 79f39fd is described below commit 79f39fdac0719cf1a03ce5e59f95b1b6574b812c Author: Ali Alsuliman <ali.al.solai...@gmail.com> AuthorDate: Tue Nov 26 20:11:32 2019 -0800 [NO ISSUE][COMP] Extension to InjectTypeCastForFunctionArgumentsRule - user model changes: no - storage format changes: no - interface changes: no Details: Extend InjectTypeCastForFunctionArgumentsRule for functions that need arguments casting. Change-Id: I68c264e7885e4f7d51a90fc615891a832a69e785 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/4163 Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Integration-Tests: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Reviewed-by: Ali Alsuliman <ali.al.solai...@gmail.com> --- .../InjectTypeCastForFunctionArgumentsRule.java | 49 ++++++++-------------- .../om/typecomputer/impl/SwitchCaseComputer.java | 18 ++++++-- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectTypeCastForFunctionArgumentsRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectTypeCastForFunctionArgumentsRule.java index 9531e94..6c8ad3a 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectTypeCastForFunctionArgumentsRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectTypeCastForFunctionArgumentsRule.java @@ -24,15 +24,12 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.IntBinaryOperator; -import java.util.function.IntPredicate; import org.apache.asterix.dataflow.data.common.TypeResolverUtil; import org.apache.asterix.lang.common.util.FunctionUtil; import org.apache.asterix.om.functions.BuiltinFunctions; import org.apache.asterix.om.typecomputer.base.TypeCastUtils; import org.apache.asterix.om.typecomputer.impl.TypeComputeUtils; -import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.IAType; import org.apache.commons.lang3.mutable.Mutable; import org.apache.commons.lang3.mutable.MutableObject; @@ -56,9 +53,10 @@ import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule; */ public class InjectTypeCastForFunctionArgumentsRule implements IAlgebraicRewriteRule { - private static final Map<FunctionIdentifier, IntPredicate> FUN_TO_ARG_CHECKER = new HashMap<>(); + private static final Map<FunctionIdentifier, BiIntPredicate> FUN_TO_ARG_CHECKER = new HashMap<>(); static { + addFunctionAndArgChecker(BuiltinFunctions.SWITCH_CASE, InjectTypeCastForFunctionArgumentsRule::switchResultArg); addFunctionAndArgChecker(BuiltinFunctions.IF_MISSING, null); addFunctionAndArgChecker(BuiltinFunctions.IF_NULL, null); addFunctionAndArgChecker(BuiltinFunctions.IF_MISSING_OR_NULL, null); @@ -66,7 +64,7 @@ public class InjectTypeCastForFunctionArgumentsRule implements IAlgebraicRewrite } // allows the rule to check other functions in addition to the ones specified here - public static void addFunctionAndArgChecker(FunctionIdentifier function, IntPredicate argChecker) { + public static void addFunctionAndArgChecker(FunctionIdentifier function, BiIntPredicate argChecker) { FUN_TO_ARG_CHECKER.put(function, argChecker); } @@ -89,7 +87,7 @@ public class InjectTypeCastForFunctionArgumentsRule implements IAlgebraicRewrite // Injects type casts to cast return expressions' return types to a generalized type that conforms to every // return type. - private boolean injectTypeCast(ILogicalOperator op, Mutable<ILogicalExpression> exprRef, + private static boolean injectTypeCast(ILogicalOperator op, Mutable<ILogicalExpression> exprRef, IOptimizationContext context) throws AlgebricksException { ILogicalExpression expr = exprRef.getValue(); if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) { @@ -105,36 +103,29 @@ public class InjectTypeCastForFunctionArgumentsRule implements IAlgebraicRewrite } } FunctionIdentifier funcId = func.getFunctionIdentifier(); - if (funcId.equals(BuiltinFunctions.SWITCH_CASE)) { - rewritten |= rewriteFunction(op, func, null, context, 2, - InjectTypeCastForFunctionArgumentsRule::switchIncrement); - } else if (FUN_TO_ARG_CHECKER.containsKey(funcId)) { - rewritten |= rewriteFunction(op, func, FUN_TO_ARG_CHECKER.get(funcId), context, 0, - InjectTypeCastForFunctionArgumentsRule::increment); + if (FUN_TO_ARG_CHECKER.containsKey(funcId)) { + rewritten |= rewriteFunction(op, func, FUN_TO_ARG_CHECKER.get(funcId), context); } return rewritten; } // Injects casts that cast types for all function parameters - private boolean rewriteFunction(ILogicalOperator op, AbstractFunctionCallExpression func, IntPredicate argChecker, - IOptimizationContext context, int argStartIdx, IntBinaryOperator increment) throws AlgebricksException { + private static boolean rewriteFunction(ILogicalOperator op, AbstractFunctionCallExpression func, + BiIntPredicate argChecker, IOptimizationContext context) throws AlgebricksException { IVariableTypeEnvironment env = op.computeInputTypeEnvironment(context); IAType producedType = (IAType) env.getType(func); - if (!argumentsNeedCasting(producedType)) { - return false; - } List<Mutable<ILogicalExpression>> argRefs = func.getArguments(); int argSize = argRefs.size(); boolean rewritten = false; - for (int argIndex = argStartIdx; argIndex < argSize; argIndex += increment.applyAsInt(argIndex, argSize)) { - if (argChecker == null || argChecker.test(argIndex)) { + for (int argIndex = 0; argIndex < argSize; argIndex++) { + if (argChecker == null || argChecker.test(argIndex, argSize)) { rewritten |= rewriteFunctionArgument(argRefs.get(argIndex), producedType, env); } } return rewritten; } - private boolean rewriteFunctionArgument(Mutable<ILogicalExpression> argRef, IAType funcOutputType, + private static boolean rewriteFunctionArgument(Mutable<ILogicalExpression> argRef, IAType funcOutputType, IVariableTypeEnvironment env) throws AlgebricksException { ILogicalExpression argExpr = argRef.getValue(); IAType type = (IAType) env.getType(argExpr); @@ -152,17 +143,13 @@ public class InjectTypeCastForFunctionArgumentsRule implements IAlgebraicRewrite return false; } - private static boolean argumentsNeedCasting(IAType functionProducedType) { - ATypeTag functionProducedTag = TypeComputeUtils.getActualType(functionProducedType).getTypeTag(); - return functionProducedTag == ATypeTag.ANY || functionProducedTag.isDerivedType(); - } - - private static int switchIncrement(int currentArgIndex, int numArguments) { - return currentArgIndex + 2 == numArguments ? 1 : 2; + public static boolean switchResultArg(int argIdx, int numArguments) { + // e.g. switch(cond, exp1, res1, exp2, res2, def_res) + return argIdx > 1 && (argIdx % 2 == 0 || argIdx == numArguments - 1); } - @SuppressWarnings("squid:S1172") // unused parameter - private static int increment(int currentArgIndex, int numArguments) { - return 1; + @FunctionalInterface + public interface BiIntPredicate { + boolean test(int argIndex, int numArguments); } -} +} \ No newline at end of file diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java index 59bfddf..db43bc7 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java @@ -18,6 +18,8 @@ */ package org.apache.asterix.om.typecomputer.impl; +import static org.apache.asterix.om.types.BuiltinType.ANULL; + import java.util.ArrayList; import java.util.List; @@ -45,12 +47,11 @@ public class SwitchCaseComputer implements IResultTypeComputer { AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression; String funcName = fce.getFunctionIdentifier().getName(); - int argNumber = fce.getArguments().size(); - if (argNumber < 3) { + int argSize = fce.getArguments().size(); + if (argSize < 3) { throw new CompilationException(ErrorCode.COMPILATION_INVALID_PARAMETER_NUMBER, fce.getSourceLocation(), - funcName, argNumber); + funcName, argSize); } - int argSize = fce.getArguments().size(); List<IAType> types = new ArrayList<>(); // Collects different branches' return types. // The last return expression is from the ELSE branch and it is optional. @@ -58,6 +59,15 @@ public class SwitchCaseComputer implements IResultTypeComputer { IAType type = (IAType) env.getType(fce.getArguments().get(argIndex).getValue()); types.add(type); } + // TODO(ali): investigate if needed for CASE. assumption seems to be that CASE is always rewritten with default + if (addDefaultNull(argSize)) { + types.add(ANULL); + } return TypeResolverUtil.resolve(types); } + + private boolean addDefaultNull(int argSize) { + // null is the default value for odd arg size (e.g. fun(cond_exp, exp1, res1)) + return argSize % 2 != 0; + } }