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 <[email protected]>
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 <[email protected]>
Integration-Tests: Jenkins <[email protected]>
Reviewed-by: Ali Alsuliman <[email protected]>
---
.../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;
+ }
}