Support CASE expression in SQL++.
- support both simple CASE expression and searched CASE expression;
- support heterogenous return types of a CASE expression;
- remove IfElseExpression in SQL++;
- remove IfElseToSwitchCaseFunctionRule.java since the plan pattern it tries to identify is no longer right;
- unify CastRecordDescriptor and CastListDescriptor into CastTypeDescriptor;
- fix IS NULL for the case that the input is MISSING;
- let CastTypeDescriptor have a generated runtime so as to handle NULL/MISSING correctly.
Change-Id: Id9de7c3df70be43456e38a61ce767cc14f09e661
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1015
Reviewed-by: Till Westmann <tillw@apache.org>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
index 683d722..0fba9da 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
@@ -36,7 +36,7 @@
import org.apache.asterix.optimizer.rules.ExtractOrderExpressionsRule;
import org.apache.asterix.optimizer.rules.FeedScanCollectionToUnnest;
import org.apache.asterix.optimizer.rules.FuzzyEqRule;
-import org.apache.asterix.optimizer.rules.IfElseToSwitchCaseFunctionRule;
+import org.apache.asterix.optimizer.rules.InjectToAnyTypeCastRule;
import org.apache.asterix.optimizer.rules.InlineUnnestFunctionRule;
import org.apache.asterix.optimizer.rules.IntroduceAutogenerateIDRule;
import org.apache.asterix.optimizer.rules.IntroduceDynamicTypeCastForExternalFunctionRule;
@@ -173,7 +173,6 @@
normalization.add(new RemoveRedundantSelectRule());
normalization.add(new UnnestToDataScanRule());
normalization.add(new MetaFunctionToMetaVariableRule());
- normalization.add(new IfElseToSwitchCaseFunctionRule());
normalization.add(new FuzzyEqRule());
normalization.add(new SimilarityCheckRule());
return normalization;
@@ -282,6 +281,7 @@
planCleanupRules.add(new IntroduceDynamicTypeCastForExternalFunctionRule());
planCleanupRules.add(new RemoveUnusedAssignAndAggregateRule());
planCleanupRules.add(new RemoveCartesianProductWithEmptyBranchRule());
+ planCleanupRules.add(new InjectToAnyTypeCastRule());
return planCleanupRules;
}
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
index 5486e64..74640a6 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/AsterixInlineVariablesRule.java
@@ -31,7 +31,7 @@
doNotInlineFuncs.add(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX);
doNotInlineFuncs.add(AsterixBuiltinFunctions.CLOSED_RECORD_CONSTRUCTOR);
doNotInlineFuncs.add(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR);
- doNotInlineFuncs.add(AsterixBuiltinFunctions.CAST_RECORD);
+ doNotInlineFuncs.add(AsterixBuiltinFunctions.CAST_TYPE);
doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_CIRCLE);
doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_LINE);
doNotInlineFuncs.add(AsterixBuiltinFunctions.CREATE_MBR);
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
index b29f110..9d9dda0 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
@@ -83,13 +83,13 @@
// Function Identifier sets that the ConstantFolding rule should skip to apply.
// Most of them are record-related functions.
- private static final ImmutableSet<FunctionIdentifier> FUNC_ID_SET_THAT_SHOULD_NOT_BE_APPLIED = ImmutableSet.of(
- AsterixBuiltinFunctions.RECORD_MERGE, AsterixBuiltinFunctions.ADD_FIELDS,
- AsterixBuiltinFunctions.REMOVE_FIELDS, AsterixBuiltinFunctions.GET_RECORD_FIELDS,
- AsterixBuiltinFunctions.GET_RECORD_FIELD_VALUE, AsterixBuiltinFunctions.FIELD_ACCESS_NESTED,
- AsterixBuiltinFunctions.GET_ITEM, AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR,
- AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX, AsterixBuiltinFunctions.CAST_RECORD,
- AsterixBuiltinFunctions.CAST_LIST, AsterixBuiltinFunctions.META, AsterixBuiltinFunctions.META_KEY);
+ private static final ImmutableSet<FunctionIdentifier> FUNC_ID_SET_THAT_SHOULD_NOT_BE_APPLIED =
+ ImmutableSet.of(AsterixBuiltinFunctions.RECORD_MERGE, AsterixBuiltinFunctions.ADD_FIELDS,
+ AsterixBuiltinFunctions.REMOVE_FIELDS, AsterixBuiltinFunctions.GET_RECORD_FIELDS,
+ AsterixBuiltinFunctions.GET_RECORD_FIELD_VALUE, AsterixBuiltinFunctions.FIELD_ACCESS_NESTED,
+ AsterixBuiltinFunctions.GET_ITEM, AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR,
+ AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX, AsterixBuiltinFunctions.CAST_TYPE,
+ AsterixBuiltinFunctions.META, AsterixBuiltinFunctions.META_KEY);
/** Throws exceptions in substituiteProducedVariable, setVarType, and one getVarType method. */
private static final IVariableTypeEnvironment _emptyTypeEnv = new IVariableTypeEnvironment() {
@@ -204,8 +204,9 @@
}
if (expr.getFunctionIdentifier().equals(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME)) {
ARecordType rt = (ARecordType) _emptyTypeEnv.getType(expr.getArguments().get(0).getValue());
- String str = ((AString) ((AsterixConstantValue) ((ConstantExpression) expr.getArguments().get(1)
- .getValue()).getValue()).getObject()).getStringValue();
+ String str =
+ ((AString) ((AsterixConstantValue) ((ConstantExpression) expr.getArguments().get(1).getValue())
+ .getValue()).getObject()).getStringValue();
int k = rt.getFieldIndex(str);
if (k >= 0) {
// wait for the ByNameToByIndex rule to apply
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IfElseToSwitchCaseFunctionRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IfElseToSwitchCaseFunctionRule.java
deleted file mode 100644
index 76d4a47..0000000
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IfElseToSwitchCaseFunctionRule.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.asterix.optimizer.rules;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.asterix.lang.common.util.FunctionUtil;
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-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.core.algebra.base.ILogicalExpression;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
-import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
-import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
-import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
-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.ScalarFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
-import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
-
-public class IfElseToSwitchCaseFunctionRule 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 {
- AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
- if (op1.getOperatorTag() != LogicalOperatorTag.ASSIGN)
- return false;
-
- AssignOperator assignOp = (AssignOperator) op1;
- List<Mutable<ILogicalExpression>> assignExprs = assignOp.getExpressions();
- if (assignExprs.size() > 1)
- return false;
- ILogicalExpression expr = assignExprs.get(0).getValue();
- if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
- AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
- if (!funcExpr.getFunctionIdentifier().equals(AsterixBuiltinFunctions.CONCAT_NON_NULL))
- return false;
- }
-
- AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
- if (op2.getOperatorTag() != LogicalOperatorTag.SUBPLAN)
- return false;
-
- SubplanOperator subplan = (SubplanOperator) op2;
- List<ILogicalPlan> subPlans = subplan.getNestedPlans();
- List<Mutable<ILogicalExpression>> arguments = new ArrayList<Mutable<ILogicalExpression>>();
- for (ILogicalPlan plan : subPlans) {
- List<Mutable<ILogicalOperator>> roots = plan.getRoots();
-
- AbstractLogicalOperator nestedRoot = (AbstractLogicalOperator) roots.get(0).getValue();
- if (nestedRoot.getOperatorTag() != LogicalOperatorTag.SELECT)
- return false;
- SelectOperator selectOp = (SelectOperator) nestedRoot;
-
- AbstractLogicalOperator nestedNextOp = (AbstractLogicalOperator) nestedRoot.getInputs().get(0).getValue();
- if (nestedNextOp.getOperatorTag() != LogicalOperatorTag.ASSIGN)
- return false;
- AssignOperator assignRoot = (AssignOperator) nestedNextOp;
- Mutable<ILogicalExpression> actionExprRef = assignRoot.getExpressions().get(0);
-
- arguments.add(selectOp.getCondition());
- arguments.add(actionExprRef);
- AbstractLogicalOperator nestedBottomOp = (AbstractLogicalOperator) assignRoot.getInputs().get(0).getValue();
-
- if (nestedBottomOp.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE)
- return false;
- }
-
- AbstractLogicalOperator op3 = (AbstractLogicalOperator) op2.getInputs().get(0).getValue();
- if (op3.getOperatorTag() != LogicalOperatorTag.ASSIGN)
- return false;
-
- AssignOperator bottomAssign = (AssignOperator) op3;
- LogicalVariable conditionVar = bottomAssign.getVariables().get(0);
- Mutable<ILogicalExpression> switchCondition = new MutableObject<ILogicalExpression>(
- new VariableReferenceExpression(conditionVar));
- List<Mutable<ILogicalExpression>> argumentRefs = new ArrayList<Mutable<ILogicalExpression>>();
- argumentRefs.add(switchCondition);
- argumentRefs.addAll(arguments);
-
- /** replace the branch conditions */
- for (int i = 0; i < arguments.size(); i += 2) {
- if (arguments.get(i).getValue().equals(switchCondition.getValue())) {
- arguments.get(i).setValue(ConstantExpression.TRUE);
- } else {
- arguments.get(i).setValue(ConstantExpression.FALSE);
- }
- }
-
- ILogicalExpression callExpr = new ScalarFunctionCallExpression(
- FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.SWITCH_CASE), argumentRefs);
-
- assignOp.getInputs().get(0).setValue(op3);
- assignOp.getExpressions().get(0).setValue(callExpr);
- context.computeAndSetTypeEnvironmentForOperator(assignOp);
- return true;
- }
-}
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectToAnyTypeCastRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectToAnyTypeCastRule.java
new file mode 100644
index 0000000..075c1f0
--- /dev/null
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/InjectToAnyTypeCastRule.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.optimizer.rules;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.asterix.lang.common.util.FunctionUtil;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.typecomputer.base.TypeCastUtils;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+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.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+
+/**
+ * This rule injects cast functions for "THEN" and "ELSE" branches of a switch-case function if
+ * different "THEN" and "ELSE" branches have heterogeneous return types.
+ */
+public class InjectToAnyTypeCastRule implements IAlgebraicRewriteRule {
+
+ @Override
+ public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+ throws AlgebricksException {
+ ILogicalOperator op = opRef.getValue();
+ if (op.getInputs().isEmpty()) {
+ return false;
+ }
+ // Populates the latest type information.
+ context.computeAndSetTypeEnvironmentForOperator(op);
+ if (op.acceptExpressionTransform(exprRef -> injectToAnyTypeCast(op, exprRef, context))) {
+ // Generates the up-to-date type information.
+ context.computeAndSetTypeEnvironmentForOperator(op);
+ return true;
+ }
+ return false;
+ }
+
+ // Injects type casts to cast return expressions' return types to ANY.
+ private boolean injectToAnyTypeCast(ILogicalOperator op, Mutable<ILogicalExpression> exprRef,
+ IOptimizationContext context) throws AlgebricksException {
+ ILogicalExpression expr = exprRef.getValue();
+ if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
+ return false;
+ }
+ boolean rewritten = false;
+ AbstractFunctionCallExpression func = (AbstractFunctionCallExpression) expr;
+ for (Mutable<ILogicalExpression> argRef : func.getArguments()) {
+ // Recursively rewrites arguments.
+ if (injectToAnyTypeCast(op, argRef, context)) {
+ context.computeAndSetTypeEnvironmentForOperator(op);
+ rewritten = true;
+ }
+ }
+ if (!func.getFunctionIdentifier().equals(AsterixBuiltinFunctions.SWITCH_CASE)) {
+ return rewritten;
+ }
+ return rewriteSwitchCase(op, func, context);
+ }
+
+ // Injects casts that cast types to ANY for different "THEN" and "ELSE" branches.
+ private boolean rewriteSwitchCase(ILogicalOperator op, AbstractFunctionCallExpression func,
+ IOptimizationContext context) throws AlgebricksException {
+ IVariableTypeEnvironment env = context.getOutputTypeEnvironment(op.getInputs().get(0).getValue());
+ if (!this.isHeterogenous(func, env)) {
+ return false;
+ }
+ List<Mutable<ILogicalExpression>> argRefs = func.getArguments();
+ int argSize = argRefs.size();
+ boolean rewritten = false;
+ for (int argIndex = 2; argIndex < argSize; argIndex += (argIndex + 2 == argSize) ? 1 : 2) {
+ Mutable<ILogicalExpression> argRef = argRefs.get(argIndex);
+ IAType type = (IAType) env.getType(argRefs.get(argIndex).getValue());
+ ATypeTag tag = type.getTypeTag();
+ // Casts are only needed when the original return type is a complex type.
+ // (In the runtime, there is already a type tag for scalar types.)
+ if (tag == ATypeTag.RECORD || tag == ATypeTag.UNORDEREDLIST || tag == ATypeTag.ORDEREDLIST) {
+ ILogicalExpression argExpr = argRef.getValue();
+ // Injects a cast call to cast the data type to ANY.
+ ScalarFunctionCallExpression castFunc = new ScalarFunctionCallExpression(
+ FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.CAST_TYPE),
+ new ArrayList<>(Collections.singletonList(new MutableObject<>(argExpr))));
+ TypeCastUtils.setRequiredAndInputTypes(castFunc, BuiltinType.ANY, type);
+ argRef.setValue(castFunc);
+ rewritten = true;
+ }
+ }
+ return rewritten;
+ }
+
+ // Checks whether "THEN" and "ELSE" branches return the heterogeneous types.
+ private boolean isHeterogenous(AbstractFunctionCallExpression func, IVariableTypeEnvironment env)
+ throws AlgebricksException {
+ List<Mutable<ILogicalExpression>> argRefs = func.getArguments();
+ int argSize = argRefs.size();
+ IAType currentType = null;
+ boolean heterogenous = false;
+ for (int argIndex = 2; argIndex < argSize; argIndex += (argIndex + 2 == argSize) ? 1 : 2) {
+ IAType type = (IAType) env.getType(argRefs.get(argIndex).getValue());
+ ATypeTag typeTag = type.getTypeTag();
+ // Null and missing are not considered as heterogeneous with other types.
+ if (typeTag != ATypeTag.NULL && typeTag != ATypeTag.MISSING) {
+ if (typeTag == ATypeTag.UNION) {
+ type = ((AUnionType) type).getActualType();
+ }
+ if (currentType != null && !type.equals(currentType)) {
+ heterogenous = true;
+ break;
+ }
+ currentType = type;
+ }
+ }
+ return heterogenous;
+ }
+
+}
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java
index 0fb5b0b..946ec39 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastForExternalFunctionRule.java
@@ -22,14 +22,13 @@
import java.util.ArrayList;
import java.util.List;
-import org.apache.commons.lang3.mutable.Mutable;
-
import org.apache.asterix.metadata.functions.AsterixExternalScalarFunctionInfo;
import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
import org.apache.asterix.om.types.ARecordType;
import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.om.util.NonTaggedFormatUtil;
+import org.apache.commons.lang3.mutable.Mutable;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
@@ -52,7 +51,8 @@
public class IntroduceDynamicTypeCastForExternalFunctionRule implements IAlgebraicRewriteRule {
@Override
- public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
+ public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+ throws AlgebricksException {
return false;
}
@@ -64,17 +64,21 @@
* resulting plan: distribute_result - project - assign (external function call) - assign (cast-record) - assign(open_record_constructor)
*/
AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
- if (op1.getOperatorTag() != LogicalOperatorTag.DISTRIBUTE_RESULT)
+ if (op1.getOperatorTag() != LogicalOperatorTag.DISTRIBUTE_RESULT) {
return false;
+ }
AbstractLogicalOperator op2 = (AbstractLogicalOperator) op1.getInputs().get(0).getValue();
- if (op2.getOperatorTag() != LogicalOperatorTag.PROJECT)
+ if (op2.getOperatorTag() != LogicalOperatorTag.PROJECT) {
return false;
+ }
AbstractLogicalOperator op3 = (AbstractLogicalOperator) op2.getInputs().get(0).getValue();
- if (op3.getOperatorTag() != LogicalOperatorTag.ASSIGN)
+ if (op3.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
return false;
+ }
AbstractLogicalOperator op4 = (AbstractLogicalOperator) op3.getInputs().get(0).getValue();
- if (op4.getOperatorTag() != LogicalOperatorTag.ASSIGN)
+ if (op4.getOperatorTag() != LogicalOperatorTag.ASSIGN) {
return false;
+ }
// Op1 : assign (external function call), Op2 : assign (open_record_constructor)
AssignOperator assignOp1 = (AssignOperator) op3;
@@ -84,8 +88,8 @@
FunctionIdentifier fid = null;
ILogicalExpression assignExpr = assignOp2.getExpressions().get(0).getValue();
if (assignExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
- ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) assignOp2.getExpressions().get(0)
- .getValue();
+ ScalarFunctionCallExpression funcExpr =
+ (ScalarFunctionCallExpression) assignOp2.getExpressions().get(0).getValue();
fid = funcExpr.getFunctionIdentifier();
if (fid != AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR) {
@@ -137,7 +141,7 @@
}
if (cast) {
IntroduceDynamicTypeCastRule.addWrapperFunction(requiredRecordType, recordVar.get(0), assignOp1, context,
- AsterixBuiltinFunctions.CAST_RECORD);
+ AsterixBuiltinFunctions.CAST_TYPE);
}
return cast || checkUnknown;
}
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
index e692678..f6cd015 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceDynamicTypeCastRule.java
@@ -173,7 +173,7 @@
AsterixBuiltinFunctions.CHECK_UNKNOWN);
}
if (cast) {
- addWrapperFunction(requiredRecordType, recordVar, op, context, AsterixBuiltinFunctions.CAST_RECORD);
+ addWrapperFunction(requiredRecordType, recordVar, op, context, AsterixBuiltinFunctions.CAST_TYPE);
}
return cast || checkUnknown;
}
@@ -210,15 +210,15 @@
if (var.equals(recordVar)) {
/** insert an assign operator to call the function on-top-of the variable */
IAType actualType = (IAType) env.getVarType(var);
- AbstractFunctionCallExpression cast = new ScalarFunctionCallExpression(
- FunctionUtil.getFunctionInfo(fd));
+ AbstractFunctionCallExpression cast =
+ new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(fd));
cast.getArguments()
.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(var)));
/** enforce the required record type */
TypeCastUtils.setRequiredAndInputTypes(cast, requiredRecordType, actualType);
LogicalVariable newAssignVar = context.newVar();
- AssignOperator newAssignOperator = new AssignOperator(newAssignVar,
- new MutableObject<ILogicalExpression>(cast));
+ AssignOperator newAssignOperator =
+ new AssignOperator(newAssignVar, new MutableObject<ILogicalExpression>(cast));
newAssignOperator.getInputs().add(new MutableObject<ILogicalOperator>(op));
opRef.setValue(newAssignOperator);
context.computeAndSetTypeEnvironmentForOperator(newAssignOperator);
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
index ae69093..c64258f 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceSecondaryIndexInsertDeleteRule.java
@@ -255,7 +255,7 @@
context.addNotToBeInlinedVar(castedRecVar);
//introduce casting to enforced type
AbstractFunctionCallExpression castFunc = new ScalarFunctionCallExpression(
- FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.CAST_RECORD));
+ FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.CAST_TYPE));
// The first argument is the record
castFunc.getArguments()
.add(new MutableObject<ILogicalExpression>(insertOp.getPayloadExpression().getValue()));
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
index eaf9484..eac35cd 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
@@ -49,7 +49,6 @@
import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
/**
@@ -455,24 +454,25 @@
if (argExpr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL
|| argExpr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
IAType reqFieldType = inputFieldType;
- FunctionIdentifier fi = null;
// do not enforce nested type in the case of no-used variables
switch (inputFieldType.getTypeTag()) {
case RECORD:
reqFieldType = DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
- fi = AsterixBuiltinFunctions.CAST_RECORD;
break;
case ORDEREDLIST:
reqFieldType = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
- fi = AsterixBuiltinFunctions.CAST_LIST;
break;
case UNORDEREDLIST:
reqFieldType = DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
- fi = AsterixBuiltinFunctions.CAST_LIST;
+ break;
+ default:
+ break;
}
- if (fi != null && !inputFieldType.equals(reqFieldType) && parameterVars.size() > 0) {
+ // do not enforce nested type in the case of no-used variables
+ if (!inputFieldType.equals(reqFieldType) && !parameterVars.isEmpty()) {
//inject dynamic type casting
- injectCastFunction(FunctionUtil.getFunctionInfo(fi), reqFieldType, inputFieldType, expRef, argExpr);
+ injectCastFunction(FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.CAST_TYPE), reqFieldType,
+ inputFieldType, expRef, argExpr);
castInjected = true;
}
//recursively rewrite function arguments
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
index 1894cc3..136dd5e 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
@@ -870,9 +870,9 @@
new MutableObject<>(new VariableReferenceExpression(varCond)), ifexpr.getThenExpr());
// Creates a subplan for the "else" branch.
- AbstractFunctionCallExpression notVarCond =
- new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(AlgebricksBuiltinFunctions.NOT),
- Collections.singletonList(new MutableObject<>(new VariableReferenceExpression(varCond))));
+ AbstractFunctionCallExpression notVarCond = new ScalarFunctionCallExpression(
+ FunctionUtil.getFunctionInfo(AlgebricksBuiltinFunctions.NOT),
+ Collections.singletonList(generateAndNotIsUnknownWrap(new VariableReferenceExpression(varCond))));
Pair<ILogicalOperator, LogicalVariable> opAndVarForElse = constructSubplanOperatorForBranch(
opAndVarForThen.first, new MutableObject<>(notVarCond), ifexpr.getElseExpr());
@@ -882,7 +882,6 @@
arguments.add(new MutableObject<>(new VariableReferenceExpression(varCond)));
arguments.add(new MutableObject<>(ConstantExpression.TRUE));
arguments.add(new MutableObject<>(new VariableReferenceExpression(opAndVarForThen.second)));
- arguments.add(new MutableObject<>(ConstantExpression.FALSE));
arguments.add(new MutableObject<>(new VariableReferenceExpression(opAndVarForElse.second)));
AbstractFunctionCallExpression swithCaseExpr = new ScalarFunctionCallExpression(
FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.SWITCH_CASE), arguments);
@@ -1364,10 +1363,14 @@
protected boolean expressionNeedsNoNesting(Expression expr) {
Kind k = expr.getKind();
- return k == Kind.LITERAL_EXPRESSION || k == Kind.LIST_CONSTRUCTOR_EXPRESSION
- || k == Kind.RECORD_CONSTRUCTOR_EXPRESSION || k == Kind.VARIABLE_EXPRESSION || k == Kind.CALL_EXPRESSION
- || k == Kind.OP_EXPRESSION || k == Kind.FIELD_ACCESSOR_EXPRESSION || k == Kind.INDEX_ACCESSOR_EXPRESSION
- || k == Kind.UNARY_EXPRESSION || k == Kind.IF_EXPRESSION || k == Kind.INDEPENDENT_SUBQUERY;
+ boolean noNesting = k == Kind.LITERAL_EXPRESSION || k == Kind.LIST_CONSTRUCTOR_EXPRESSION
+ || k == Kind.RECORD_CONSTRUCTOR_EXPRESSION || k == Kind.VARIABLE_EXPRESSION;
+ noNesting = noNesting || k == Kind.CALL_EXPRESSION || k == Kind.OP_EXPRESSION
+ || k == Kind.FIELD_ACCESSOR_EXPRESSION;
+ noNesting = noNesting || k == Kind.INDEX_ACCESSOR_EXPRESSION || k == Kind.UNARY_EXPRESSION
+ || k == Kind.IF_EXPRESSION;
+ return noNesting || k == Kind.INDEPENDENT_SUBQUERY || k == Kind.CASE_EXPRESSION;
+
}
protected <T> List<T> mkSingletonArrayList(T item) {
@@ -1519,7 +1522,7 @@
* @return a pair of the constructed subplan operator and the output variable for the branch.
* @throws AsterixException
*/
- private Pair<ILogicalOperator, LogicalVariable> constructSubplanOperatorForBranch(ILogicalOperator inputOp,
+ protected Pair<ILogicalOperator, LogicalVariable> constructSubplanOperatorForBranch(ILogicalOperator inputOp,
Mutable<ILogicalExpression> selectExpr, Expression branchExpression) throws AsterixException {
context.enterSubplan();
SubplanOperator subplanOp = new SubplanOperator();
@@ -1555,4 +1558,34 @@
.add(new MutableObject<>(new ConstantExpression(new AsterixConstantValue(new AInt64(0L)))));
return new AssignOperator(v1, new MutableObject<>(comparison));
}
+
+ // Generates the filter condition for whether a conditional branch should be executed.
+ protected Mutable<ILogicalExpression> generateNoMatchedPrecedingWhenBranchesFilter(
+ List<ILogicalExpression> inputBooleanExprs) {
+ List<Mutable<ILogicalExpression>> arguments = new ArrayList<>();
+ for (ILogicalExpression inputBooleanExpr : inputBooleanExprs) {
+ // A NULL/MISSING valued WHEN expression does not lead to the corresponding THEN execution.
+ // Therefore, we should check a previous WHEN boolean condition is not unknown.
+ arguments.add(generateAndNotIsUnknownWrap(inputBooleanExpr));
+ }
+ Mutable<ILogicalExpression> hasBeenExecutedExprRef = new MutableObject<>(
+ new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.OR), arguments));
+ return new MutableObject<>(
+ new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.NOT),
+ new ArrayList<>(Collections.singletonList(hasBeenExecutedExprRef))));
+ }
+
+ // For an input expression `expr`, return `expr AND expr IS NOT UNKOWN`.
+ protected Mutable<ILogicalExpression> generateAndNotIsUnknownWrap(ILogicalExpression logicalExpr) {
+ List<Mutable<ILogicalExpression>> arguments = new ArrayList<>();
+ arguments.add(new MutableObject<>(logicalExpr));
+ Mutable<ILogicalExpression> expr = new MutableObject<>(
+ new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.IS_UNKOWN),
+ new ArrayList<>(Collections.singletonList(new MutableObject<>(logicalExpr)))));
+ arguments.add(new MutableObject<>(
+ new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.NOT),
+ new ArrayList<>(Collections.singletonList(expr)))));
+ return new MutableObject<>(
+ new ScalarFunctionCallExpression(FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.AND), arguments));
+ }
}
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
index b7ed988..e40de4b 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
@@ -20,6 +20,7 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Deque;
import java.util.List;
@@ -51,12 +52,14 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.optype.JoinType;
import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
import org.apache.asterix.metadata.declared.AqlMetadataProvider;
+import org.apache.asterix.om.base.ABoolean;
import org.apache.asterix.om.base.AInt32;
import org.apache.asterix.om.base.AString;
import org.apache.asterix.om.constants.AsterixConstantValue;
@@ -72,9 +75,11 @@
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
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.AggregateFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestNonMapOperator;
@@ -142,8 +147,8 @@
currentOpRef = new MutableObject<>(letClause.accept(this, currentOpRef).first);
}
}
- Pair<ILogicalOperator, LogicalVariable> select = selectExpression.getSelectSetOperation().accept(this,
- currentOpRef);
+ Pair<ILogicalOperator, LogicalVariable> select =
+ selectExpression.getSelectSetOperation().accept(this, currentOpRef);
currentOpRef = new MutableObject<>(select.first);
if (selectExpression.hasOrderby()) {
currentOpRef = new MutableObject<>(selectExpression.getOrderbyClause().accept(this, currentOpRef).first);
@@ -151,8 +156,8 @@
if (selectExpression.hasLimit()) {
currentOpRef = new MutableObject<>(selectExpression.getLimitClause().accept(this, currentOpRef).first);
}
- Pair<ILogicalOperator, LogicalVariable> result = produceSelectPlan(selectExpression.isSubquery(), currentOpRef,
- select.second);
+ Pair<ILogicalOperator, LogicalVariable> result =
+ produceSelectPlan(selectExpression.isSubquery(), currentOpRef, select.second);
if (selectExpression.isSubquery()) {
context.exitSubplan();
}
@@ -162,8 +167,8 @@
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(IndependentSubquery independentSubquery,
Mutable<ILogicalOperator> tupleSource) throws AsterixException {
- Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo = langExprToAlgExpression(independentSubquery.getExpr(),
- tupleSource);
+ Pair<ILogicalExpression, Mutable<ILogicalOperator>> eo =
+ langExprToAlgExpression(independentSubquery.getExpr(), tupleSource);
// Replaces nested tuple source with empty tuple source so that the subquery can be independent
// from its input operators.
replaceNtsWithEts(eo.second.getValue());
@@ -177,8 +182,8 @@
public Pair<ILogicalOperator, LogicalVariable> visit(SelectSetOperation selectSetOperation,
Mutable<ILogicalOperator> tupSource) throws AsterixException {
Mutable<ILogicalOperator> currentOpRef = tupSource;
- Pair<ILogicalOperator, LogicalVariable> currentResult = selectSetOperation.getLeftInput().accept(this,
- currentOpRef);
+ Pair<ILogicalOperator, LogicalVariable> currentResult =
+ selectSetOperation.getLeftInput().accept(this, currentOpRef);
if (selectSetOperation.hasRightInputs()) {
throw new NotImplementedException();
}
@@ -236,12 +241,12 @@
if (fromTerm.hasPositionalVariable()) {
LogicalVariable pVar = context.newVar(fromTerm.getPositionalVariable());
// We set the positional variable type as INT64 type.
- unnestOp = new UnnestOperator(fromVar,
- new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first)), pVar, BuiltinType.AINT64,
- new AqlPositionWriter());
+ unnestOp =
+ new UnnestOperator(fromVar, new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first)),
+ pVar, BuiltinType.AINT64, new AqlPositionWriter());
} else {
- unnestOp = new UnnestOperator(fromVar,
- new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first)));
+ unnestOp =
+ new UnnestOperator(fromVar, new MutableObject<ILogicalExpression>(makeUnnestExpression(eo.first)));
}
unnestOp.getInputs().add(eo.second);
@@ -267,41 +272,41 @@
throws AsterixException {
Mutable<ILogicalOperator> leftInputRef = uncorrelatedLeftBranchStack.pop();
if (joinClause.getJoinType() == JoinType.INNER) {
- Pair<ILogicalOperator, LogicalVariable> rightBranch = generateUnnestForBinaryCorrelateRightBranch(
- joinClause, inputRef, true);
+ Pair<ILogicalOperator, LogicalVariable> rightBranch =
+ generateUnnestForBinaryCorrelateRightBranch(joinClause, inputRef, true);
// A join operator with condition TRUE.
- AbstractBinaryJoinOperator joinOperator = new InnerJoinOperator(
- new MutableObject<ILogicalExpression>(ConstantExpression.TRUE), leftInputRef,
- new MutableObject<ILogicalOperator>(rightBranch.first));
+ AbstractBinaryJoinOperator joinOperator =
+ new InnerJoinOperator(new MutableObject<ILogicalExpression>(ConstantExpression.TRUE), leftInputRef,
+ new MutableObject<ILogicalOperator>(rightBranch.first));
Mutable<ILogicalOperator> joinOpRef = new MutableObject<>(joinOperator);
// Add an additional filter operator.
- Pair<ILogicalExpression, Mutable<ILogicalOperator>> conditionExprOpPair = langExprToAlgExpression(
- joinClause.getConditionExpression(), joinOpRef);
- SelectOperator filter = new SelectOperator(new MutableObject<ILogicalExpression>(conditionExprOpPair.first),
- false, null);
+ Pair<ILogicalExpression, Mutable<ILogicalOperator>> conditionExprOpPair =
+ langExprToAlgExpression(joinClause.getConditionExpression(), joinOpRef);
+ SelectOperator filter =
+ new SelectOperator(new MutableObject<ILogicalExpression>(conditionExprOpPair.first), false, null);
filter.getInputs().add(conditionExprOpPair.second);
return new Pair<>(filter, rightBranch.second);
} else {
// Creates a subplan operator.
SubplanOperator subplanOp = new SubplanOperator();
- Mutable<ILogicalOperator> ntsRef = new MutableObject<>(
- new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(subplanOp)));
+ Mutable<ILogicalOperator> ntsRef =
+ new MutableObject<>(new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(subplanOp)));
subplanOp.getInputs().add(leftInputRef);
// Enters the translation for a subplan.
context.enterSubplan();
// Adds an unnest operator to unnest to right expression.
- Pair<ILogicalOperator, LogicalVariable> rightBranch = generateUnnestForBinaryCorrelateRightBranch(
- joinClause, ntsRef, true);
+ Pair<ILogicalOperator, LogicalVariable> rightBranch =
+ generateUnnestForBinaryCorrelateRightBranch(joinClause, ntsRef, true);
AbstractUnnestNonMapOperator rightUnnestOp = (AbstractUnnestNonMapOperator) rightBranch.first;
// Adds an additional filter operator for the join condition.
Pair<ILogicalExpression, Mutable<ILogicalOperator>> conditionExprOpPair = langExprToAlgExpression(
joinClause.getConditionExpression(), new MutableObject<ILogicalOperator>(rightUnnestOp));
- SelectOperator filter = new SelectOperator(new MutableObject<ILogicalExpression>(conditionExprOpPair.first),
- false, null);
+ SelectOperator filter =
+ new SelectOperator(new MutableObject<ILogicalExpression>(conditionExprOpPair.first), false, null);
filter.getInputs().add(conditionExprOpPair.second);
ILogicalOperator currentTopOp = filter;
@@ -327,8 +332,8 @@
// Assigns the record constructor function to a record variable.
LogicalVariable recordVar = context.newVar();
- AssignOperator assignOp = new AssignOperator(recordVar,
- new MutableObject<ILogicalExpression>(recordCreationFunc));
+ AssignOperator assignOp =
+ new AssignOperator(recordVar, new MutableObject<ILogicalExpression>(recordCreationFunc));
assignOp.getInputs().add(new MutableObject<ILogicalOperator>(currentTopOp));
// Sets currentTopOp and varToListify for later usages.
@@ -357,8 +362,8 @@
// Outer unnest the aggregated var from the subplan.
LogicalVariable outerUnnestVar = context.newVar();
- LeftOuterUnnestOperator outerUnnestOp = new LeftOuterUnnestOperator(outerUnnestVar,
- new MutableObject<ILogicalExpression>(
+ LeftOuterUnnestOperator outerUnnestOp =
+ new LeftOuterUnnestOperator(outerUnnestVar, new MutableObject<ILogicalExpression>(
makeUnnestExpression(new VariableReferenceExpression(aggVar))));
outerUnnestOp.getInputs().add(new MutableObject<ILogicalOperator>(subplanOp));
currentTopOp = outerUnnestOp;
@@ -423,8 +428,8 @@
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(HavingClause havingClause, Mutable<ILogicalOperator> tupSource)
throws AsterixException {
- Pair<ILogicalExpression, Mutable<ILogicalOperator>> p = langExprToAlgExpression(
- havingClause.getFilterExpression(), tupSource);
+ Pair<ILogicalExpression, Mutable<ILogicalOperator>> p =
+ langExprToAlgExpression(havingClause.getFilterExpression(), tupSource);
SelectOperator s = new SelectOperator(new MutableObject<ILogicalExpression>(p.first), false, null);
s.getInputs().add(p.second);
return new Pair<>(s, null);
@@ -477,6 +482,86 @@
throw new UnsupportedOperationException(ERR_MSG);
}
+ @Override
+ public Pair<ILogicalOperator, LogicalVariable> visit(CaseExpression caseExpression,
+ Mutable<ILogicalOperator> tupSource) throws AsterixException {
+ //Creates a series of subplan operators, one for each branch.
+ Mutable<ILogicalOperator> currentOpRef = tupSource;
+ ILogicalOperator currentOperator = null;
+ List<Expression> whenExprList = caseExpression.getWhenExprs();
+ List<Expression> thenExprList = caseExpression.getThenExprs();
+ List<ILogicalExpression> branchCondVarReferences = new ArrayList<>();
+ List<ILogicalExpression> allVarReferences = new ArrayList<>();
+ for (int index = 0; index < whenExprList.size(); ++index) {
+ Pair<ILogicalOperator, LogicalVariable> whenExprResult = whenExprList.get(index).accept(this, currentOpRef);
+ currentOperator = whenExprResult.first;
+ // Variable whenConditionVar is corresponds to the current "WHEN" condition.
+ LogicalVariable whenConditionVar = whenExprResult.second;
+ Mutable<ILogicalExpression> branchEntraceConditionExprRef =
+ new MutableObject<>(new VariableReferenceExpression(whenConditionVar));
+
+ // Constructs an expression that filters data based on preceding "WHEN" conditions
+ // and the current "WHEN" condition. Note that only one "THEN" expression can be run
+ // even though multiple "WHEN" conditions can be satisfied.
+ if (!branchCondVarReferences.isEmpty()) {
+ // The additional filter generated here makes sure the the tuple has not
+ // entered other matched "WHEN...THEN" case.
+ List<Mutable<ILogicalExpression>> andArgs = new ArrayList<>();
+ andArgs.add(generateNoMatchedPrecedingWhenBranchesFilter(branchCondVarReferences));
+ andArgs.add(branchEntraceConditionExprRef);
+
+ // A "THEN" branch can be entered only when the tuple has not enter any other preceding
+ // branches and the current "WHEN" condition is TRUE.
+ branchEntraceConditionExprRef = new MutableObject<>(new ScalarFunctionCallExpression(
+ FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.AND), andArgs));
+ }
+
+ // Translates the corresponding "THEN" expression.
+ Pair<ILogicalOperator, LogicalVariable> opAndVarForThen = constructSubplanOperatorForBranch(currentOperator,
+ branchEntraceConditionExprRef, thenExprList.get(index));
+
+ branchCondVarReferences.add(new VariableReferenceExpression(whenConditionVar));
+ allVarReferences.add(new VariableReferenceExpression(whenConditionVar));
+ allVarReferences.add(new VariableReferenceExpression(opAndVarForThen.second));
+ currentOperator = opAndVarForThen.first;
+ currentOpRef = new MutableObject<>(currentOperator);
+ }
+
+ // Creates a subplan for the "ELSE" branch.
+ Mutable<ILogicalExpression> elseCondExprRef =
+ generateNoMatchedPrecedingWhenBranchesFilter(branchCondVarReferences);
+ Pair<ILogicalOperator, LogicalVariable> opAndVarForElse =
+ constructSubplanOperatorForBranch(currentOperator, elseCondExprRef, caseExpression.getElseExpr());
+
+ // Uses switch-case function to select the results of two branches.
+ LogicalVariable selectVar = context.newVar();
+ List<Mutable<ILogicalExpression>> arguments = new ArrayList<>();
+ arguments.add(new MutableObject<>(new ConstantExpression(new AsterixConstantValue(ABoolean.TRUE))));
+ for (ILogicalExpression argVar : allVarReferences) {
+ arguments.add(new MutableObject<>(argVar));
+ }
+ arguments.add(new MutableObject<>(new VariableReferenceExpression(opAndVarForElse.second)));
+ AbstractFunctionCallExpression swithCaseExpr = new ScalarFunctionCallExpression(
+ FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.SWITCH_CASE), arguments);
+ AssignOperator assignOp = new AssignOperator(selectVar, new MutableObject<>(swithCaseExpr));
+ assignOp.getInputs().add(new MutableObject<>(opAndVarForElse.first));
+
+ // Unnests the selected (a "THEN" or "ELSE" branch) result.
+ LogicalVariable unnestVar = context.newVar();
+ UnnestOperator unnestOp = new UnnestOperator(unnestVar,
+ new MutableObject<>(new UnnestingFunctionCallExpression(
+ FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.SCAN_COLLECTION), Collections
+ .singletonList(new MutableObject<>(new VariableReferenceExpression(selectVar))))));
+ unnestOp.getInputs().add(new MutableObject<>(assignOp));
+
+ // Produces the final assign operator.
+ LogicalVariable resultVar = context.newVar();
+ AssignOperator finalAssignOp =
+ new AssignOperator(resultVar, new MutableObject<>(new VariableReferenceExpression(unnestVar)));
+ finalAssignOp.getInputs().add(new MutableObject<>(unnestOp));
+ return new Pair<>(finalAssignOp, resultVar);
+ }
+
private Pair<ILogicalOperator, LogicalVariable> produceSelectPlan(boolean isSubquery,
Mutable<ILogicalOperator> returnOpRef, LogicalVariable resVar) {
if (isSubquery) {
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
index 24ddaf6..2c0aef4 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
@@ -131,8 +131,7 @@
import org.apache.asterix.runtime.evaluators.constructors.OpenRecordConstructorDescriptor;
import org.apache.asterix.runtime.evaluators.functions.AndDescriptor;
import org.apache.asterix.runtime.evaluators.functions.AnyCollectionMemberDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.CastListDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.CastRecordDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.CastTypeDescriptor;
import org.apache.asterix.runtime.evaluators.functions.CheckUnknownDescriptor;
import org.apache.asterix.runtime.evaluators.functions.CodePointToStringDescriptor;
import org.apache.asterix.runtime.evaluators.functions.CountHashedGramTokensDescriptor;
@@ -374,10 +373,8 @@
temp.add(OrderedListConstructorDescriptor.FACTORY);
temp.add(UnorderedListConstructorDescriptor.FACTORY);
- // Cast functions
+ // Inject failure function
temp.add(InjectFailureDescriptor.FACTORY);
- temp.add(CastListDescriptor.FACTORY);
- temp.add(CastRecordDescriptor.FACTORY);
// Switch case
temp.add(SwitchCaseDescriptor.FACTORY);
@@ -612,6 +609,9 @@
functionsToInjectUnkownHandling.add(GetOverlappingIntervalDescriptor.FACTORY);
functionsToInjectUnkownHandling.add(DurationFromIntervalDescriptor.FACTORY);
+ // Cast function
+ functionsToInjectUnkownHandling.add(CastTypeDescriptor.FACTORY);
+
List<IFunctionDescriptorFactory> generatedFactories = new ArrayList<>();
for (IFunctionDescriptorFactory factory : functionsToInjectUnkownHandling) {
generatedFactories
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryBTreeOperationsHelper.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryBTreeOperationsHelper.java
index 15ea2f8..9e2e0b0 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryBTreeOperationsHelper.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryBTreeOperationsHelper.java
@@ -95,8 +95,8 @@
secondaryComparatorFactories, secondaryBloomFilterKeyFields, false, dataset.getDatasetId(),
mergePolicyFactory, mergePolicyFactoryProperties, filterTypeTraits, filterCmpFactories,
secondaryBTreeFields, secondaryFilterFields);
- localResourceFactoryProvider = new PersistentLocalResourceFactoryProvider(localResourceMetadata,
- LocalResource.LSMBTreeResource);
+ localResourceFactoryProvider =
+ new PersistentLocalResourceFactoryProvider(localResourceMetadata, LocalResource.LSMBTreeResource);
indexDataflowHelperFactory = new LSMBTreeDataflowHelperFactory(
new AsterixVirtualBufferCacheProvider(dataset.getDatasetId()), mergePolicyFactory,
mergePolicyFactoryProperties, new SecondaryIndexOperationTrackerProvider(dataset.getDatasetId()),
@@ -146,12 +146,12 @@
// Assign op.
AbstractOperatorDescriptor sourceOp = primaryScanOp;
- if (isEnforcingKeyTypes) {
+ if (isEnforcingKeyTypes && !enforcedItemType.equals(itemType)) {
sourceOp = createCastOp(spec, dataset.getDatasetType());
spec.connect(new OneToOneConnectorDescriptor(spec), primaryScanOp, 0, sourceOp, 0);
}
- AlgebricksMetaOperatorDescriptor asterixAssignOp = createExternalAssignOp(spec, numSecondaryKeys,
- secondaryRecDesc);
+ AlgebricksMetaOperatorDescriptor asterixAssignOp =
+ createExternalAssignOp(spec, numSecondaryKeys, secondaryRecDesc);
// If any of the secondary fields are nullable, then add a select op that filters nulls.
AlgebricksMetaOperatorDescriptor selectOp = null;
@@ -165,13 +165,13 @@
AsterixStorageProperties storageProperties = propertiesProvider.getStorageProperties();
// Create secondary BTree bulk load op.
AbstractTreeIndexOperatorDescriptor secondaryBulkLoadOp;
- ExternalBTreeWithBuddyDataflowHelperFactory dataflowHelperFactory = new ExternalBTreeWithBuddyDataflowHelperFactory(
- mergePolicyFactory, mergePolicyFactoryProperties,
- new SecondaryIndexOperationTrackerProvider(dataset.getDatasetId()),
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
- LSMBTreeWithBuddyIOOperationCallbackFactory.INSTANCE,
- storageProperties.getBloomFilterFalsePositiveRate(), new int[] { numSecondaryKeys },
- ExternalDatasetsRegistry.INSTANCE.getDatasetVersion(dataset), true);
+ ExternalBTreeWithBuddyDataflowHelperFactory dataflowHelperFactory =
+ new ExternalBTreeWithBuddyDataflowHelperFactory(mergePolicyFactory, mergePolicyFactoryProperties,
+ new SecondaryIndexOperationTrackerProvider(dataset.getDatasetId()),
+ AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
+ LSMBTreeWithBuddyIOOperationCallbackFactory.INSTANCE,
+ storageProperties.getBloomFilterFalsePositiveRate(), new int[] { numSecondaryKeys },
+ ExternalDatasetsRegistry.INSTANCE.getDatasetVersion(dataset), true);
IOperatorDescriptor root;
if (externalFiles != null) {
// Transaction load
@@ -208,12 +208,12 @@
// Assign op.
AbstractOperatorDescriptor sourceOp = primaryScanOp;
- if (isEnforcingKeyTypes) {
+ if (isEnforcingKeyTypes && !enforcedItemType.equals(itemType)) {
sourceOp = createCastOp(spec, dataset.getDatasetType());
spec.connect(new OneToOneConnectorDescriptor(spec), primaryScanOp, 0, sourceOp, 0);
}
- AlgebricksMetaOperatorDescriptor asterixAssignOp = createAssignOp(spec, sourceOp, numSecondaryKeys,
- secondaryRecDesc);
+ AlgebricksMetaOperatorDescriptor asterixAssignOp =
+ createAssignOp(spec, sourceOp, numSecondaryKeys, secondaryRecDesc);
// If any of the secondary fields are nullable, then add a select op that filters nulls.
AlgebricksMetaOperatorDescriptor selectOp = null;
@@ -311,17 +311,17 @@
secondaryFieldAccessEvalFactories = new IScalarEvaluatorFactory[numSecondaryKeys + numFilterFields];
secondaryComparatorFactories = new IBinaryComparatorFactory[numSecondaryKeys + numPrimaryKeys];
secondaryBloomFilterKeyFields = new int[numSecondaryKeys];
- ISerializerDeserializer[] secondaryRecFields = new ISerializerDeserializer[numPrimaryKeys + numSecondaryKeys
- + numFilterFields];
- ISerializerDeserializer[] enforcedRecFields = new ISerializerDeserializer[1 + numPrimaryKeys
- + (dataset.hasMetaPart() ? 1 : 0) + numFilterFields];
- ITypeTraits[] enforcedTypeTraits = new ITypeTraits[1 + numPrimaryKeys + (dataset.hasMetaPart() ? 1 : 0)
- + numFilterFields];
+ ISerializerDeserializer[] secondaryRecFields =
+ new ISerializerDeserializer[numPrimaryKeys + numSecondaryKeys + numFilterFields];
+ ISerializerDeserializer[] enforcedRecFields =
+ new ISerializerDeserializer[1 + numPrimaryKeys + (dataset.hasMetaPart() ? 1 : 0) + numFilterFields];
+ ITypeTraits[] enforcedTypeTraits =
+ new ITypeTraits[1 + numPrimaryKeys + (dataset.hasMetaPart() ? 1 : 0) + numFilterFields];
secondaryTypeTraits = new ITypeTraits[numSecondaryKeys + numPrimaryKeys];
ISerializerDeserializerProvider serdeProvider = metadataProvider.getFormat().getSerdeProvider();
ITypeTraitProvider typeTraitProvider = metadataProvider.getFormat().getTypeTraitProvider();
- IBinaryComparatorFactoryProvider comparatorFactoryProvider = metadataProvider.getFormat()
- .getBinaryComparatorFactoryProvider();
+ IBinaryComparatorFactoryProvider comparatorFactoryProvider =
+ metadataProvider.getFormat().getBinaryComparatorFactoryProvider();
// Record column is 0 for external datasets, numPrimaryKeys for internal ones
int recordColumn = dataset.getDatasetType() == DatasetType.INTERNAL ? numPrimaryKeys : 0;
for (int i = 0; i < numSecondaryKeys; i++) {
@@ -336,8 +336,8 @@
}
secondaryFieldAccessEvalFactories[i] = metadataProvider.getFormat().getFieldAccessEvaluatorFactory(
isEnforcingKeyTypes ? enforcedItemType : sourceType, secondaryKeyFields.get(i), sourceColumn);
- Pair<IAType, Boolean> keyTypePair = Index.getNonNullableOpenFieldType(secondaryKeyTypes.get(i),
- secondaryKeyFields.get(i), sourceType);
+ Pair<IAType, Boolean> keyTypePair =
+ Index.getNonNullableOpenFieldType(secondaryKeyTypes.get(i), secondaryKeyFields.get(i), sourceType);
IAType keyType = keyTypePair.first;
anySecondaryKeyIsNullable = anySecondaryKeyIsNullable || keyTypePair.second;
ISerializerDeserializer keySerde = serdeProvider.getSerializerDeserializer(keyType);
@@ -380,8 +380,8 @@
ISerializerDeserializer serde = serdeProvider.getSerializerDeserializer(type);
secondaryRecFields[numPrimaryKeys + numSecondaryKeys] = serde;
enforcedRecFields[numPrimaryKeys + 1 + (dataset.hasMetaPart() ? 1 : 0)] = serde;
- enforcedTypeTraits[numPrimaryKeys + 1 + (dataset.hasMetaPart() ? 1 : 0)] = typeTraitProvider
- .getTypeTrait(type);
+ enforcedTypeTraits[numPrimaryKeys + 1 + (dataset.hasMetaPart() ? 1 : 0)] =
+ typeTraitProvider.getTypeTrait(type);
}
secondaryRecDesc = new RecordDescriptor(secondaryRecFields, secondaryTypeTraits);
enforcedRecDesc = new RecordDescriptor(enforcedRecFields, enforcedTypeTraits);
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryIndexOperationsHelper.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryIndexOperationsHelper.java
index e677f54..8ebe246 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryIndexOperationsHelper.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryIndexOperationsHelper.java
@@ -53,7 +53,7 @@
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.om.util.AsterixAppContextInfo;
import org.apache.asterix.runtime.evaluators.functions.AndDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.CastRecordDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.CastTypeDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IsUnknownDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NotDescriptor;
import org.apache.asterix.runtime.job.listener.JobEventListenerFactory;
@@ -173,8 +173,8 @@
case SINGLE_PARTITION_NGRAM_INVIX:
case LENGTH_PARTITIONED_WORD_INVIX:
case LENGTH_PARTITIONED_NGRAM_INVIX: {
- indexOperationsHelper = new SecondaryInvertedIndexOperationsHelper(physOptConf,
- asterixPropertiesProvider);
+ indexOperationsHelper =
+ new SecondaryInvertedIndexOperationsHelper(physOptConf, asterixPropertiesProvider);
break;
}
default: {
@@ -240,8 +240,8 @@
setSecondaryRecDescAndComparators(indexType, secondaryKeyFields, secondaryKeyTypes, gramLength,
metadataProvider);
numElementsHint = metadataProvider.getCardinalityPerPartitionHint(dataset);
- Pair<ILSMMergePolicyFactory, Map<String, String>> compactionInfo = DatasetUtils.getMergePolicyFactory(dataset,
- metadataProvider.getMetadataTxnContext());
+ Pair<ILSMMergePolicyFactory, Map<String, String>> compactionInfo =
+ DatasetUtils.getMergePolicyFactory(dataset, metadataProvider.getMetadataTxnContext());
mergePolicyFactory = compactionInfo.first;
mergePolicyFactoryProperties = compactionInfo.second;
@@ -276,8 +276,8 @@
protected void setPrimaryRecDescAndComparators() throws AlgebricksException {
List<List<String>> partitioningKeys = DatasetUtils.getPartitioningKeys(dataset);
int numPrimaryKeys = partitioningKeys.size();
- ISerializerDeserializer[] primaryRecFields = new ISerializerDeserializer[numPrimaryKeys + 1
- + (dataset.hasMetaPart() ? 1 : 0)];
+ ISerializerDeserializer[] primaryRecFields =
+ new ISerializerDeserializer[numPrimaryKeys + 1 + (dataset.hasMetaPart() ? 1 : 0)];
ITypeTraits[] primaryTypeTraits = new ITypeTraits[numPrimaryKeys + 1 + (dataset.hasMetaPart() ? 1 : 0)];
primaryComparatorFactories = new IBinaryComparatorFactory[numPrimaryKeys];
primaryBloomFilterKeyFields = new int[numPrimaryKeys];
@@ -287,12 +287,12 @@
indicators = ((InternalDatasetDetails) dataset.getDatasetDetails()).getKeySourceIndicator();
}
for (int i = 0; i < numPrimaryKeys; i++) {
- IAType keyType = (indicators == null || indicators.get(i) == 0)
- ? itemType.getSubFieldType(partitioningKeys.get(i))
- : metaType.getSubFieldType(partitioningKeys.get(i));
+ IAType keyType =
+ (indicators == null || indicators.get(i) == 0) ? itemType.getSubFieldType(partitioningKeys.get(i))
+ : metaType.getSubFieldType(partitioningKeys.get(i));
primaryRecFields[i] = serdeProvider.getSerializerDeserializer(keyType);
- primaryComparatorFactories[i] = AqlBinaryComparatorFactoryProvider.INSTANCE
- .getBinaryComparatorFactory(keyType, true);
+ primaryComparatorFactories[i] =
+ AqlBinaryComparatorFactoryProvider.INSTANCE.getBinaryComparatorFactory(keyType, true);
primaryTypeTraits[i] = AqlTypeTraitProvider.INSTANCE.getTypeTrait(keyType);
primaryBloomFilterKeyFields[i] = i;
}
@@ -398,8 +398,7 @@
}
protected AlgebricksMetaOperatorDescriptor createCastOp(JobSpecification spec, DatasetType dsType) {
- CastRecordDescriptor castFuncDesc = (CastRecordDescriptor) CastRecordDescriptor.FACTORY
- .createFunctionDescriptor();
+ CastTypeDescriptor castFuncDesc = (CastTypeDescriptor) CastTypeDescriptor.FACTORY.createFunctionDescriptor();
castFuncDesc.reset(enforcedItemType, itemType);
int[] outColumns = new int[1];
@@ -419,8 +418,8 @@
if (dataset.hasMetaPart()) {
projectionList[numPrimaryKeys + 1] = numPrimaryKeys + 1;
}
- IScalarEvaluatorFactory[] castEvalFact = new IScalarEvaluatorFactory[] {
- new ColumnAccessEvalFactory(recordIdx) };
+ IScalarEvaluatorFactory[] castEvalFact =
+ new IScalarEvaluatorFactory[] { new ColumnAccessEvalFactory(recordIdx) };
IScalarEvaluatorFactory[] sefs = new IScalarEvaluatorFactory[1];
sefs[0] = castFuncDesc.createEvaluatorFactory(castEvalFact);
AssignRuntimeFactory castAssign = new AssignRuntimeFactory(outColumns, sefs, projectionList);
@@ -463,10 +462,10 @@
for (int i = 0; i < numSecondaryKeyFields; i++) {
// Access column i, and apply 'is not null'.
ColumnAccessEvalFactory columnAccessEvalFactory = new ColumnAccessEvalFactory(i);
- IScalarEvaluatorFactory isUnknownEvalFactory = isUnknownDesc
- .createEvaluatorFactory(new IScalarEvaluatorFactory[] { columnAccessEvalFactory });
- IScalarEvaluatorFactory notEvalFactory = notDesc
- .createEvaluatorFactory(new IScalarEvaluatorFactory[] { isUnknownEvalFactory });
+ IScalarEvaluatorFactory isUnknownEvalFactory =
+ isUnknownDesc.createEvaluatorFactory(new IScalarEvaluatorFactory[] { columnAccessEvalFactory });
+ IScalarEvaluatorFactory notEvalFactory =
+ notDesc.createEvaluatorFactory(new IScalarEvaluatorFactory[] { isUnknownEvalFactory });
andArgsEvalFactories[i] = notEvalFactory;
}
IScalarEvaluatorFactory selectCond = null;
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryInvertedIndexOperationsHelper.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryInvertedIndexOperationsHelper.java
index 7044205..c2d2f7c 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryInvertedIndexOperationsHelper.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryInvertedIndexOperationsHelper.java
@@ -113,8 +113,8 @@
// Prepare record descriptor used in the assign op, and the optional
// select op.
secondaryFieldAccessEvalFactories = new IScalarEvaluatorFactory[numSecondaryKeys + numFilterFields];
- ISerializerDeserializer[] secondaryRecFields = new ISerializerDeserializer[numPrimaryKeys + numSecondaryKeys
- + numFilterFields];
+ ISerializerDeserializer[] secondaryRecFields =
+ new ISerializerDeserializer[numPrimaryKeys + numSecondaryKeys + numFilterFields];
ISerializerDeserializer[] enforcedRecFields = new ISerializerDeserializer[1 + numPrimaryKeys + numFilterFields];
secondaryTypeTraits = new ITypeTraits[numSecondaryKeys + numPrimaryKeys];
ITypeTraits[] enforcedTypeTraits = new ITypeTraits[1 + numPrimaryKeys];
@@ -123,8 +123,8 @@
if (numSecondaryKeys > 0) {
secondaryFieldAccessEvalFactories[0] = FormatUtils.getDefaultFormat().getFieldAccessEvaluatorFactory(
isEnforcingKeyTypes ? enforcedItemType : itemType, secondaryKeyFields.get(0), numPrimaryKeys);
- Pair<IAType, Boolean> keyTypePair = Index.getNonNullableOpenFieldType(secondaryKeyTypes.get(0),
- secondaryKeyFields.get(0), itemType);
+ Pair<IAType, Boolean> keyTypePair =
+ Index.getNonNullableOpenFieldType(secondaryKeyTypes.get(0), secondaryKeyFields.get(0), itemType);
secondaryKeyType = keyTypePair.first;
anySecondaryKeyIsNullable = anySecondaryKeyIsNullable || keyTypePair.second;
ISerializerDeserializer keySerde = serdeProvider.getSerializerDeserializer(secondaryKeyType);
@@ -154,8 +154,8 @@
// Set tokenizer factory.
// TODO: We might want to expose the hashing option at the AQL level,
// and add the choice to the index metadata.
- tokenizerFactory = NonTaggedFormatUtil.getBinaryTokenizerFactory(secondaryKeyType.getTypeTag(), indexType,
- gramLength);
+ tokenizerFactory =
+ NonTaggedFormatUtil.getBinaryTokenizerFactory(secondaryKeyType.getTypeTag(), indexType, gramLength);
// Type traits for inverted-list elements. Inverted lists contain
// primary keys.
invListsTypeTraits = new ITypeTraits[numPrimaryKeys];
@@ -169,8 +169,8 @@
// For tokenization, sorting and loading.
// One token (+ optional partitioning field) + primary keys.
numTokenKeyPairFields = (!isPartitioned) ? 1 + numPrimaryKeys : 2 + numPrimaryKeys;
- ISerializerDeserializer[] tokenKeyPairFields = new ISerializerDeserializer[numTokenKeyPairFields
- + numFilterFields];
+ ISerializerDeserializer[] tokenKeyPairFields =
+ new ISerializerDeserializer[numTokenKeyPairFields + numFilterFields];
ITypeTraits[] tokenKeyPairTypeTraits = new ITypeTraits[numTokenKeyPairFields];
tokenKeyPairComparatorFactories = new IBinaryComparatorFactory[numTokenKeyPairFields];
tokenKeyPairFields[0] = serdeProvider.getSerializerDeserializer(secondaryKeyType);
@@ -226,11 +226,11 @@
localResourceMetadata, LocalResource.LSMInvertedIndexResource);
IIndexDataflowHelperFactory dataflowHelperFactory = createDataflowHelperFactory();
- LSMInvertedIndexCreateOperatorDescriptor invIndexCreateOp = new LSMInvertedIndexCreateOperatorDescriptor(spec,
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, secondaryFileSplitProvider,
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, tokenTypeTraits, tokenComparatorFactories,
- invListsTypeTraits, primaryComparatorFactories, tokenizerFactory, dataflowHelperFactory,
- localResourceFactoryProvider, NoOpOperationCallbackFactory.INSTANCE);
+ LSMInvertedIndexCreateOperatorDescriptor invIndexCreateOp =
+ new LSMInvertedIndexCreateOperatorDescriptor(spec, AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
+ secondaryFileSplitProvider, AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, tokenTypeTraits,
+ tokenComparatorFactories, invListsTypeTraits, primaryComparatorFactories, tokenizerFactory,
+ dataflowHelperFactory, localResourceFactoryProvider, NoOpOperationCallbackFactory.INSTANCE);
AlgebricksPartitionConstraintHelper.setPartitionConstraintInJobSpec(spec, invIndexCreateOp,
secondaryPartitionConstraint);
spec.addRoot(invIndexCreateOp);
@@ -249,12 +249,12 @@
BTreeSearchOperatorDescriptor primaryScanOp = createPrimaryIndexScanOp(spec);
AbstractOperatorDescriptor sourceOp = primaryScanOp;
- if (isEnforcingKeyTypes) {
+ if (isEnforcingKeyTypes && !enforcedItemType.equals(itemType)) {
sourceOp = createCastOp(spec, dataset.getDatasetType());
spec.connect(new OneToOneConnectorDescriptor(spec), primaryScanOp, 0, sourceOp, 0);
}
- AlgebricksMetaOperatorDescriptor asterixAssignOp = createAssignOp(spec, sourceOp, numSecondaryKeys,
- secondaryRecDesc);
+ AlgebricksMetaOperatorDescriptor asterixAssignOp =
+ createAssignOp(spec, sourceOp, numSecondaryKeys, secondaryRecDesc);
// If any of the secondary fields are nullable, then add a select op
// that filters nulls.
@@ -267,8 +267,8 @@
AbstractOperatorDescriptor tokenizerOp = createTokenizerOp(spec);
// Sort by token + primary keys.
- ExternalSortOperatorDescriptor sortOp = createSortOp(spec, tokenKeyPairComparatorFactories,
- tokenKeyPairRecDesc);
+ ExternalSortOperatorDescriptor sortOp =
+ createSortOp(spec, tokenKeyPairComparatorFactories, tokenKeyPairRecDesc);
// Create secondary inverted index bulk load op.
LSMInvertedIndexBulkLoadOperatorDescriptor invIndexBulkLoadOp = createInvertedIndexBulkLoadOp(spec);
@@ -364,11 +364,11 @@
JobSpecification spec = JobSpecificationUtils.createJobSpecification();
IIndexDataflowHelperFactory dataflowHelperFactory = createDataflowHelperFactory();
- LSMInvertedIndexCompactOperator compactOp = new LSMInvertedIndexCompactOperator(spec,
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, secondaryFileSplitProvider,
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, tokenTypeTraits, tokenComparatorFactories,
- invListsTypeTraits, primaryComparatorFactories, tokenizerFactory, dataflowHelperFactory,
- NoOpOperationCallbackFactory.INSTANCE);
+ LSMInvertedIndexCompactOperator compactOp =
+ new LSMInvertedIndexCompactOperator(spec, AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
+ secondaryFileSplitProvider, AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, tokenTypeTraits,
+ tokenComparatorFactories, invListsTypeTraits, primaryComparatorFactories, tokenizerFactory,
+ dataflowHelperFactory, NoOpOperationCallbackFactory.INSTANCE);
AlgebricksPartitionConstraintHelper.setPartitionConstraintInJobSpec(spec, compactOp,
secondaryPartitionConstraint);
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryRTreeOperationsHelper.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryRTreeOperationsHelper.java
index 7c500cf..cc9675d 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryRTreeOperationsHelper.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/file/SecondaryRTreeOperationsHelper.java
@@ -112,8 +112,8 @@
AqlMetadataProvider.proposeLinearizer(keyType, secondaryComparatorFactories.length),
dataset.getDatasetId(), mergePolicyFactory, mergePolicyFactoryProperties, filterTypeTraits,
filterCmpFactories, rtreeFields, primaryKeyFields, secondaryFilterFields, isPointMBR);
- localResourceFactoryProvider = new PersistentLocalResourceFactoryProvider(localResourceMetadata,
- LocalResource.LSMRTreeResource);
+ localResourceFactoryProvider =
+ new PersistentLocalResourceFactoryProvider(localResourceMetadata, LocalResource.LSMRTreeResource);
indexDataflowHelperFactory = new LSMRTreeWithAntiMatterTuplesDataflowHelperFactory(valueProviderFactories,
RTreePolicyType.RTREE, btreeCompFactories,
new AsterixVirtualBufferCacheProvider(dataset.getDatasetId()), mergePolicyFactory,
@@ -181,8 +181,8 @@
throw new AsterixException("Cannot use " + numSecondaryKeys
+ " fields as a key for the R-tree index. There can be only one field as a key for the R-tree index.");
}
- Pair<IAType, Boolean> spatialTypePair = Index.getNonNullableOpenFieldType(secondaryKeyTypes.get(0),
- secondaryKeyFields.get(0), itemType);
+ Pair<IAType, Boolean> spatialTypePair =
+ Index.getNonNullableOpenFieldType(secondaryKeyTypes.get(0), secondaryKeyFields.get(0), itemType);
IAType spatialType = spatialTypePair.first;
anySecondaryKeyIsNullable = spatialTypePair.second;
if (spatialType == null) {
@@ -192,24 +192,24 @@
int numDimensions = NonTaggedFormatUtil.getNumDimensions(spatialType.getTypeTag());
numNestedSecondaryKeyFields = numDimensions * 2;
int recordColumn = dataset.getDatasetType() == DatasetType.INTERNAL ? numPrimaryKeys : 0;
- secondaryFieldAccessEvalFactories = metadata.getFormat().createMBRFactory(
- isEnforcingKeyTypes ? enforcedItemType : itemType, secondaryKeyFields.get(0), recordColumn,
- numDimensions, filterFieldName);
+ secondaryFieldAccessEvalFactories =
+ metadata.getFormat().createMBRFactory(isEnforcingKeyTypes ? enforcedItemType : itemType,
+ secondaryKeyFields.get(0), recordColumn, numDimensions, filterFieldName);
secondaryComparatorFactories = new IBinaryComparatorFactory[numNestedSecondaryKeyFields];
valueProviderFactories = new IPrimitiveValueProviderFactory[numNestedSecondaryKeyFields];
- ISerializerDeserializer[] secondaryRecFields = new ISerializerDeserializer[numPrimaryKeys
- + numNestedSecondaryKeyFields + numFilterFields];
+ ISerializerDeserializer[] secondaryRecFields =
+ new ISerializerDeserializer[numPrimaryKeys + numNestedSecondaryKeyFields + numFilterFields];
ISerializerDeserializer[] enforcedRecFields = new ISerializerDeserializer[1 + numPrimaryKeys + numFilterFields];
secondaryTypeTraits = new ITypeTraits[numNestedSecondaryKeyFields + numPrimaryKeys];
ITypeTraits[] enforcedTypeTraits = new ITypeTraits[1 + numPrimaryKeys];
IAType nestedKeyType = NonTaggedFormatUtil.getNestedSpatialType(spatialType.getTypeTag());
keyType = nestedKeyType.getTypeTag();
for (int i = 0; i < numNestedSecondaryKeyFields; i++) {
- ISerializerDeserializer keySerde = AqlSerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(nestedKeyType);
+ ISerializerDeserializer keySerde =
+ AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(nestedKeyType);
secondaryRecFields[i] = keySerde;
- secondaryComparatorFactories[i] = AqlBinaryComparatorFactoryProvider.INSTANCE
- .getBinaryComparatorFactory(nestedKeyType, true);
+ secondaryComparatorFactories[i] =
+ AqlBinaryComparatorFactoryProvider.INSTANCE.getBinaryComparatorFactory(nestedKeyType, true);
secondaryTypeTraits[i] = AqlTypeTraitProvider.INSTANCE.getTypeTrait(nestedKeyType);
valueProviderFactories[i] = AqlPrimitiveValueProviderFactory.INSTANCE;
@@ -230,8 +230,8 @@
enforcedTypeTraits[i] = IndexingConstants.getTypeTraits(i);
}
}
- enforcedRecFields[numPrimaryKeys] = AqlSerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(itemType);
+ enforcedRecFields[numPrimaryKeys] =
+ AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(itemType);
enforcedRecDesc = new RecordDescriptor(enforcedRecFields, enforcedTypeTraits);
if (numFilterFields > 0) {
rtreeFields = new int[numNestedSecondaryKeyFields + numPrimaryKeys];
@@ -282,10 +282,10 @@
JobSpecification spec = JobSpecificationUtils.createJobSpecification();
boolean temp = dataset.getDatasetDetails().isTemp();
int[] fieldPermutation = createFieldPermutationForBulkLoadOp(numNestedSecondaryKeyFields);
- int numNestedSecondaryKeFieldsConsideringPointMBR = isPointMBR ? numNestedSecondaryKeyFields / 2
- : numNestedSecondaryKeyFields;
- RecordDescriptor secondaryRecDescConsideringPointMBR = isPointMBR ? secondaryRecDescForPointMBR
- : secondaryRecDesc;
+ int numNestedSecondaryKeFieldsConsideringPointMBR =
+ isPointMBR ? numNestedSecondaryKeyFields / 2 : numNestedSecondaryKeyFields;
+ RecordDescriptor secondaryRecDescConsideringPointMBR =
+ isPointMBR ? secondaryRecDescForPointMBR : secondaryRecDesc;
if (dataset.getDatasetType() == DatasetType.INTERNAL) {
// Create dummy key provider for feeding the primary index scan.
AbstractOperatorDescriptor keyProviderOp = createDummyKeyProviderOp(spec);
@@ -295,7 +295,7 @@
// Assign op.
AbstractOperatorDescriptor sourceOp = primaryScanOp;
- if (isEnforcingKeyTypes) {
+ if (isEnforcingKeyTypes && !enforcedItemType.equals(itemType)) {
sourceOp = createCastOp(spec, dataset.getDatasetType());
spec.connect(new OneToOneConnectorDescriptor(spec), primaryScanOp, 0, sourceOp, 0);
}
@@ -310,10 +310,11 @@
}
// Sort by secondary keys.
- ExternalSortOperatorDescriptor sortOp = createSortOp(spec,
- new IBinaryComparatorFactory[] {
- AqlMetadataProvider.proposeLinearizer(keyType, secondaryComparatorFactories.length) },
- isPointMBR ? secondaryRecDescForPointMBR : secondaryRecDesc);
+ ExternalSortOperatorDescriptor sortOp =
+ createSortOp(spec,
+ new IBinaryComparatorFactory[] { AqlMetadataProvider.proposeLinearizer(keyType,
+ secondaryComparatorFactories.length) },
+ isPointMBR ? secondaryRecDescForPointMBR : secondaryRecDesc);
AsterixStorageProperties storageProperties = propertiesProvider.getStorageProperties();
@@ -327,8 +328,8 @@
filterTypeTraits, filterCmpFactories, secondaryFilterFields, !temp, isPointMBR);;
// Create secondary RTree bulk load op.
- TreeIndexBulkLoadOperatorDescriptor secondaryBulkLoadOp = createTreeIndexBulkLoadOp(spec, fieldPermutation,
- idff, GlobalConfig.DEFAULT_TREE_FILL_FACTOR);
+ TreeIndexBulkLoadOperatorDescriptor secondaryBulkLoadOp =
+ createTreeIndexBulkLoadOp(spec, fieldPermutation, idff, GlobalConfig.DEFAULT_TREE_FILL_FACTOR);
AlgebricksMetaOperatorDescriptor metaOp = new AlgebricksMetaOperatorDescriptor(spec, 1, 0,
new IPushRuntimeFactory[] { new SinkRuntimeFactory() }, new RecordDescriptor[] {});
// Connect the operators.
@@ -353,7 +354,7 @@
// Create external indexing scan operator
ExternalDataScanOperatorDescriptor primaryScanOp = createExternalIndexingOp(spec);
AbstractOperatorDescriptor sourceOp = primaryScanOp;
- if (isEnforcingKeyTypes) {
+ if (isEnforcingKeyTypes && !enforcedItemType.equals(itemType)) {
sourceOp = createCastOp(spec, dataset.getDatasetType());
spec.connect(new OneToOneConnectorDescriptor(spec), primaryScanOp, 0, sourceOp, 0);
}
@@ -369,10 +370,11 @@
}
// Sort by secondary keys.
- ExternalSortOperatorDescriptor sortOp = createSortOp(spec,
- new IBinaryComparatorFactory[] {
- AqlMetadataProvider.proposeLinearizer(keyType, secondaryComparatorFactories.length) },
- isPointMBR ? secondaryRecDescForPointMBR : secondaryRecDesc);
+ ExternalSortOperatorDescriptor sortOp =
+ createSortOp(spec,
+ new IBinaryComparatorFactory[] { AqlMetadataProvider.proposeLinearizer(keyType,
+ secondaryComparatorFactories.length) },
+ isPointMBR ? secondaryRecDescForPointMBR : secondaryRecDesc);
AsterixStorageProperties storageProperties = propertiesProvider.getStorageProperties();
// Create the dataflow helper factory
@@ -478,27 +480,27 @@
AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, LSMRTreeIOOperationCallbackFactory.INSTANCE,
AqlMetadataProvider.proposeLinearizer(keyType, secondaryComparatorFactories.length), rtreeFields,
filterTypeTraits, filterCmpFactories, secondaryFilterFields, !temp, isPointMBR);
- compactOp = new LSMTreeIndexCompactOperatorDescriptor(spec,
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, secondaryFileSplitProvider, secondaryTypeTraits,
- secondaryComparatorFactories, secondaryBloomFilterKeyFields, idff,
- NoOpOperationCallbackFactory.INSTANCE);
+ compactOp =
+ new LSMTreeIndexCompactOperatorDescriptor(spec, AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
+ AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, secondaryFileSplitProvider,
+ secondaryTypeTraits, secondaryComparatorFactories, secondaryBloomFilterKeyFields, idff,
+ NoOpOperationCallbackFactory.INSTANCE);
} else {
// External dataset
- compactOp = new LSMTreeIndexCompactOperatorDescriptor(spec,
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, secondaryFileSplitProvider, secondaryTypeTraits,
- secondaryComparatorFactories, secondaryBloomFilterKeyFields,
- new ExternalRTreeDataflowHelperFactory(valueProviderFactories, RTreePolicyType.RTREE,
- primaryComparatorFactories, mergePolicyFactory, mergePolicyFactoryProperties,
- new SecondaryIndexOperationTrackerProvider(dataset.getDatasetId()),
- AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
- LSMRTreeIOOperationCallbackFactory.INSTANCE,
- AqlMetadataProvider.proposeLinearizer(keyType, secondaryComparatorFactories.length),
- storageProperties.getBloomFilterFalsePositiveRate(),
- new int[] { numNestedSecondaryKeyFields },
- ExternalDatasetsRegistry.INSTANCE.getDatasetVersion(dataset), true, isPointMBR),
- NoOpOperationCallbackFactory.INSTANCE);
+ compactOp =
+ new LSMTreeIndexCompactOperatorDescriptor(spec, AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
+ AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER, secondaryFileSplitProvider,
+ secondaryTypeTraits, secondaryComparatorFactories, secondaryBloomFilterKeyFields,
+ new ExternalRTreeDataflowHelperFactory(valueProviderFactories, RTreePolicyType.RTREE,
+ primaryComparatorFactories, mergePolicyFactory, mergePolicyFactoryProperties,
+ new SecondaryIndexOperationTrackerProvider(dataset.getDatasetId()),
+ AsterixRuntimeComponentsProvider.RUNTIME_PROVIDER,
+ LSMRTreeIOOperationCallbackFactory.INSTANCE,
+ AqlMetadataProvider.proposeLinearizer(keyType, secondaryComparatorFactories.length),
+ storageProperties.getBloomFilterFalsePositiveRate(),
+ new int[] { numNestedSecondaryKeyFields },
+ ExternalDatasetsRegistry.INSTANCE.getDatasetVersion(dataset), true, isPointMBR),
+ NoOpOperationCallbackFactory.INSTANCE);
}
AlgebricksPartitionConstraintHelper.setPartitionConstraintInJobSpec(spec, compactOp,
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/NullMissingTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/NullMissingTest.java
index d4b50a4..d30ffd9 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/NullMissingTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/NullMissingTest.java
@@ -47,15 +47,15 @@
String className = func.getClass().getName();
// We test all generated functions except
// record functions, which requires type settings (we test them in runtime tests);
- if (className.contains("generated") && !className.contains("record")) {
+ if (className.contains("generated") && !className.contains("record") && !className.contains("Cast")) {
testFunction(func);
}
}
}
private void testFunction(IFunctionDescriptorFactory funcFactory) throws Exception {
- AbstractScalarFunctionDynamicDescriptor funcDesc = (AbstractScalarFunctionDynamicDescriptor) funcFactory
- .createFunctionDescriptor();
+ AbstractScalarFunctionDynamicDescriptor funcDesc =
+ (AbstractScalarFunctionDynamicDescriptor) funcFactory.createFunctionDescriptor();
int inputArity = funcDesc.getIdentifier().getArity();
Iterator<IScalarEvaluatorFactory[]> argEvalFactoryIterator = getArgCombinations(inputArity);
int index = 0;
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpch/q12_shipping.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpch/q12_shipping.sqlpp
new file mode 100644
index 0000000..b1a8cc1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpch/q12_shipping.sqlpp
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+DROP database tpch IF EXISTS;
+CREATE database tpch;
+
+USE tpch;
+
+
+CREATE TYPE LineItemType AS {
+ l_linenumber : int32
+}
+
+CREATE TYPE OrderType AS {
+ o_orderkey : int32
+}
+
+CREATE TABLE LineItem(LineItemType) PRIMARY KEY l_linenumber;
+
+CREATE TABLE Orders(OrderType) PRIMARY KEY o_orderkey;
+
+/** The plan tests that the expression for different switch-case branches are not extracted.*/
+SELECT l.l_shipmode,
+ sum(CASE
+ WHEN o.o_orderpriority = '1-URGENT' or o.o_orderpriority = '2-HIGH' THEN 1 + o.o_orderpriority * 0
+ ELSE 0 + o.o_orderpriority * 0
+ END) high_line_count,
+ sum(CASE o.o_orderpriority = '1-URGENT' or o.o_orderpriority = '2-HIGH'
+ WHEN true THEN 0 + o.o_orderpriority * 0
+ ELSE 1 + o.o_orderpriority * 0
+ END) low_line_count
+FROM LineItem l,
+ Orders o
+WHERE o.o_orderkey = l.l_orderkey AND l.l_commitdate < l.l_receiptdate AND
+ l.l_shipdate < l.l_commitdate AND l.l_receiptdate >= '1994-01-01' AND
+ l.l_receiptdate < '1995-01-01' AND (l.l_shipmode = 'MAIL' OR l.l_shipmode = 'SHIP')
+GROUP BY l.l_shipmode
+ORDER BY l.l_shipmode
+;
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1203.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1203.plan
index 9dc7a8a..b090c13 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1203.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1203.plan
@@ -16,7 +16,8 @@
-- ASSIGN |LOCAL|
-- ASSIGN |LOCAL|
-- STREAM_SELECT |LOCAL|
- -- NESTED_TUPLE_SOURCE |LOCAL|
+ -- ASSIGN |LOCAL|
+ -- NESTED_TUPLE_SOURCE |LOCAL|
}
-- SUBPLAN |PARTITIONED|
{
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-865.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-865.plan
index 6ff5cee..914a23b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-865.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-865.plan
@@ -17,7 +17,8 @@
-- UNNEST |LOCAL|
-- ASSIGN |LOCAL|
-- STREAM_SELECT |LOCAL|
- -- NESTED_TUPLE_SOURCE |LOCAL|
+ -- ASSIGN |LOCAL|
+ -- NESTED_TUPLE_SOURCE |LOCAL|
}
-- SUBPLAN |PARTITIONED|
{
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping.plan
new file mode 100644
index 0000000..7c1af83
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping.plan
@@ -0,0 +1,43 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- SORT_MERGE_EXCHANGE [$$3(ASC) ] |PARTITIONED|
+ -- PRE_CLUSTERED_GROUP_BY[$$94] |PARTITIONED|
+ {
+ -- AGGREGATE |LOCAL|
+ -- NESTED_TUPLE_SOURCE |LOCAL|
+ }
+ -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$94(ASC)] HASH:[$$94] |PARTITIONED|
+ -- SORT_GROUP_BY[$$76] |PARTITIONED|
+ {
+ -- AGGREGATE |LOCAL|
+ -- NESTED_TUPLE_SOURCE |LOCAL|
+ }
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$83][$$76] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$83] |PARTITIONED|
+ -- UNNEST |UNPARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |UNPARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$76] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$85][$$80] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$85] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- STREAM_SELECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/IfInFLOWGR.sqlpp b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/IfInFLOWGR.sqlpp
index 294730f..1945567 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/IfInFLOWGR.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/IfInFLOWGR.sqlpp
@@ -17,9 +17,10 @@
* under the License.
*/
-select element if ((i > j))
- then i
+select element
+ case when i > j then i
else j
+ end
from [1,2,30,40] as i,
{{4,5,6}} as j
;
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/IfThenElse.sqlpp b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/IfThenElse.sqlpp
index f346d1a..877c27a 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/IfThenElse.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/IfThenElse.sqlpp
@@ -17,6 +17,8 @@
* under the License.
*/
-select element if ((2 > 1))
- then 20
- else 10;
+select element
+ case 2 > 1
+ when true then 20
+ else 10
+ end;
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/functionDecl2.sqlpp b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/functionDecl2.sqlpp
index ddda48e..8c5e82a 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/functionDecl2.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/functionDecl2.sqlpp
@@ -18,7 +18,7 @@
*/
declare function GT(a,b) {
-if ((a > b))
- then true
+ case when a > b then true
else false
+ end
};
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/nestedFLWOGR1.sqlpp b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/nestedFLWOGR1.sqlpp
index 704f348..7449562 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/nestedFLWOGR1.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/nestedFLWOGR1.sqlpp
@@ -19,9 +19,10 @@
select element (
select element k
- from if ((i > j))
- then i
- else j as k
+ from case i > j
+ when true then i
+ else j
+ end as k
where (k < 10)
)
from [1,2,30,40] as i,
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/nestedFLWOGR2.sqlpp b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/nestedFLWOGR2.sqlpp
index 0abbf80..13e0259 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/nestedFLWOGR2.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/parserts/queries_sqlpp/nestedFLWOGR2.sqlpp
@@ -19,9 +19,11 @@
select element (
select element k
- from if ((i > j))
- then i
- else j as k
+ from case
+ when i > j then i
+ else j
+ end
+ as k
where (k < 10)
)
from [1,2,30,(
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/IfInFLOWGR.ast b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/IfInFLOWGR.ast
index 947c2d4..58fe98b 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/IfInFLOWGR.ast
+++ b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/IfInFLOWGR.ast
@@ -1,17 +1,17 @@
Query:
SELECT ELEMENT [
-IfExpr [
- Condition:
- OperatorExpr [
+CASE LiteralExpr [TRUE]
+
+WHEN OperatorExpr [
Variable [ Name=$i ]
>
Variable [ Name=$j ]
]
- Then:
- Variable [ Name=$i ]
- Else:
- Variable [ Name=$j ]
-]
+THEN Variable [ Name=$i ]
+
+ELSE Variable [ Name=$j ]
+
+END
]
FROM [ OrderedListConstructor [
LiteralExpr [LONG] [1]
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/IfThenElse.ast b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/IfThenElse.ast
index 8c3462e..cf95780 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/IfThenElse.ast
+++ b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/IfThenElse.ast
@@ -1,15 +1,15 @@
Query:
SELECT ELEMENT [
-IfExpr [
- Condition:
- OperatorExpr [
+CASE OperatorExpr [
LiteralExpr [LONG] [2]
>
LiteralExpr [LONG] [1]
]
- Then:
- LiteralExpr [LONG] [20]
- Else:
- LiteralExpr [LONG] [10]
-]
+
+WHEN LiteralExpr [TRUE]
+THEN LiteralExpr [LONG] [20]
+
+ELSE LiteralExpr [LONG] [10]
+
+END
]
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/functionDecl2.ast b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/functionDecl2.ast
index de37697..33b1f55 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/functionDecl2.ast
+++ b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/functionDecl2.ast
@@ -1,15 +1,15 @@
FunctionDecl GT([$a, $b]) {
- IfExpr [
- Condition:
- OperatorExpr [
+ CASE LiteralExpr [TRUE]
+
+ WHEN OperatorExpr [
Variable [ Name=$a ]
>
Variable [ Name=$b ]
]
- Then:
- LiteralExpr [TRUE]
- Else:
- LiteralExpr [FALSE]
- ]
+ THEN LiteralExpr [TRUE]
+
+ ELSE LiteralExpr [FALSE]
+
+ END
}
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/nestedFLWOGR1.ast b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/nestedFLWOGR1.ast
index 2af8be1..42831c4 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/nestedFLWOGR1.ast
+++ b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/nestedFLWOGR1.ast
@@ -4,18 +4,18 @@
SELECT ELEMENT [
Variable [ Name=$k ]
]
- FROM [ IfExpr [
- Condition:
- OperatorExpr [
+ FROM [ CASE OperatorExpr [
Variable [ Name=$i ]
>
Variable [ Name=$j ]
]
- Then:
- Variable [ Name=$i ]
- Else:
- Variable [ Name=$j ]
- ]
+
+ WHEN LiteralExpr [TRUE]
+ THEN Variable [ Name=$i ]
+
+ ELSE Variable [ Name=$j ]
+
+ END
AS Variable [ Name=$k ]
]
Where
diff --git a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/nestedFLWOGR2.ast b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/nestedFLWOGR2.ast
index 5e5ac9a..60f5465 100644
--- a/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/nestedFLWOGR2.ast
+++ b/asterixdb/asterix-app/src/test/resources/parserts/results_parser_sqlpp/nestedFLWOGR2.ast
@@ -4,18 +4,18 @@
SELECT ELEMENT [
Variable [ Name=$k ]
]
- FROM [ IfExpr [
- Condition:
- OperatorExpr [
+ FROM [ CASE LiteralExpr [TRUE]
+
+ WHEN OperatorExpr [
Variable [ Name=$i ]
>
Variable [ Name=$j ]
]
- Then:
- Variable [ Name=$i ]
- Else:
- Variable [ Name=$j ]
- ]
+ THEN Variable [ Name=$i ]
+
+ ELSE Variable [ Name=$j ]
+
+ END
AS Variable [ Name=$k ]
]
Where
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/misc/ifthenelse_02/ifthenelse_01.3.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/misc/ifthenelse_02/ifthenelse_01.3.query.aql
new file mode 100644
index 0000000..c7aad30
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/misc/ifthenelse_02/ifthenelse_01.3.query.aql
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+if (null=1) then
+ 20
+else
+ 10
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/misc/query-ASTERIXDB-819-2/query-ASTERIXDB-819-2.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/misc/query-ASTERIXDB-819-2/query-ASTERIXDB-819-2.1.query.aql
new file mode 100644
index 0000000..a8b3789
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/misc/query-ASTERIXDB-819-2/query-ASTERIXDB-819-2.1.query.aql
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+if (1!=1.0) then
+"result"
+else
+{ "type": "object" }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.query.aql
new file mode 100644
index 0000000..4f54f33
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.query.aql
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+if (true) then
+null
+else
+1
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp
new file mode 100644
index 0000000..c2a4cea
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_01/case_01.1.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SELECT
+ CASE t
+ WHEN 0 THEN 0.0
+ WHEN NULL THEN -1
+ WHEN MISSING THEN -2
+ ELSE 2.0/t
+ END
+FROM [0, 1, 2, 4, NULL, [0][-1]] t;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_02/case_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_02/case_02.1.query.sqlpp
new file mode 100644
index 0000000..ab19bcb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_02/case_02.1.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SELECT
+ CASE
+ WHEN t=0 THEN 0.0
+ WHEN t IS NULL THEN -1
+ WHEN t IS MISSING THEN -2
+ ELSE 2.0/t
+ END
+FROM [0, 1, 2, 4, NULL, [0][-1]] t;
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_03/case_03.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_03/case_03.1.query.sqlpp
new file mode 100644
index 0000000..7c3e566
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_03/case_03.1.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SELECT
+ CASE
+ WHEN t = 0 THEN (SELECT 0 AS r)
+ WHEN t IS NULL THEN (SELECT -1 AS r)
+ WHEN t IS MISSING THEN (SELECT -2 AS r)
+ ELSE (SELECT -3 AS r)
+ END
+FROM [0, 1, 2, 4, NULL, [0][-1]] t;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_04/case_04.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_04/case_04.1.query.sqlpp
new file mode 100644
index 0000000..154e611
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_04/case_04.1.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SELECT
+ CASE
+ WHEN t = 0 THEN [0]
+ WHEN t IS NULL THEN (SELECT -1)
+ WHEN t IS MISSING THEN (SELECT -2)
+ ELSE 2.0/t
+ END
+FROM [0, 1, 2, 4, NULL, [0][-1]] t;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_05/case_05.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_05/case_05.1.query.sqlpp
new file mode 100644
index 0000000..32030a7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_05/case_05.1.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SELECT
+ CASE
+ WHEN t = 0 THEN [0]
+ WHEN t IS NULL THEN (SELECT -1)
+ WHEN t IS MISSING THEN (SELECT -2)
+ WHEN t =1 THEN NULL
+ WHEN t=2 THEN MISSING
+ ELSE 2.0/t
+ END
+FROM [0, 1, 2, 4, NULL, [0][-1]] t;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_06/case_06.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_06/case_06.1.query.sqlpp
new file mode 100644
index 0000000..5bf2786
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_06/case_06.1.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SELECT
+ CASE
+ WHEN t = 0 THEN MISSING
+ ELSE NULL
+ END
+FROM [0, 1, 2, 4, NULL, [0][-1]] t;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_07/case_07.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_07/case_07.1.query.sqlpp
new file mode 100644
index 0000000..4850047
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/case_07/case_07.1.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SELECT
+ CASE
+ WHEN t = 0 THEN [0]
+ WHEN t IS NULL THEN (SELECT -1)
+ WHEN t IS MISSING THEN (SELECT -2)
+ WHEN t =1 THEN NULL
+ WHEN t=2 THEN MISSING
+ WHEN t IS UNKNOWN THEN (SELECT -3) // Should never enter this THEN branch.
+ ELSE 2.0/t
+ END
+FROM [0, 1, 2, 4, NULL, [0][-1]] t;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.query.sqlpp
index 609ec27..e96b458 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.query.sqlpp
@@ -17,9 +17,13 @@
* under the License.
*/
-use test;
+USE test;
-select element if ((2 > 1))
- then 20
- else 10;
+SELECT ELEMENT
+ CASE 2>1
+ WHEN TRUE THEN 20
+ ELSE 10
+ END
+;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/open-closed/query-issue258/query-issue258.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/open-closed/query-issue258/query-issue258.2.update.sqlpp
index b662786..2b009ae 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/open-closed/query-issue258/query-issue258.2.update.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/open-closed/query-issue258/query-issue258.2.update.sqlpp
@@ -23,14 +23,16 @@
* Date : 21 May 2013
*/
-use test;
+USE test;
-insert into ds1
-if ((coll_count((
+INSERT INTO ds1
+CASE
+ WHEN coll_count((
select element x
from ds2 as x
where (x.id = 10)
- )) <= 0))
-then {'id':10}
-else {'id':5};
+ )) <= 0
+ THEN {'id':10}
+ ELSE {'id':5}
+END;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.query.sqlpp
index 3c1a921..a8b4bac 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.query.sqlpp
@@ -21,7 +21,7 @@
select element {'year':year,'mkt_share':(tpch.coll_sum((
- select element tpch.`switch-case`((i.s_name = 'BRAZIL'),true,i.revenue,false,0.0)
+ select element case when i.s_name = 'BRAZIL' then i.revenue else 0.0 end
from t as i
)) / tpch.coll_sum((
select element i.revenue
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.query.sqlpp
index 879f936..c576c6c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.query.sqlpp
@@ -21,10 +21,16 @@
select element {'l_shipmode':l_shipmode,'high_line_count':tpch.coll_sum((
- select element tpch.`switch-case`(((i.o_orderpriority = '1-URGENT') or (i.o_orderpriority = '2-HIGH')),true,1,false,0)
+ select element case i.o_orderpriority = '1-URGENT' or i.o_orderpriority = '2-HIGH'
+ when true then 1
+ when false then 0
+ end
from o as i
)),'low_line_count':tpch.coll_sum((
- select element tpch.`switch-case`(((i.o_orderpriority = '1-URGENT') or (i.o_orderpriority = '2-HIGH')),true,0,false,1)
+ select element case i.o_orderpriority = '1-URGENT' or i.o_orderpriority = '2-HIGH'
+ when true then 0
+ when false then 1
+ end
from o as i
))}
from LineItem as l,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
index eb556b16..7a14b25 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
@@ -21,7 +21,10 @@
select element (100.0 * tpch.coll_sum((
- select element tpch.`switch-case`(i.p_type like 'PROMO%',true,(i.l_extendedprice * (1 - i.l_discount)),false,0.0)
+ select element case i.p_type like 'PROMO%'
+ when true then i.l_extendedprice * (1 - i.l_discount)
+ when false then 0.0
+ end
from lp as i
)) / tpch.coll_sum((
select element (i.l_extendedprice * (1 - i.l_discount))
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q08_national_market_share/q08_national_market_share.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q08_national_market_share/q08_national_market_share.3.query.sqlpp
index df23284..3c69b1c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q08_national_market_share/q08_national_market_share.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q08_national_market_share/q08_national_market_share.3.query.sqlpp
@@ -21,8 +21,7 @@
SELECT year,
- sum( `switch-case`(s_name = 'BRAZIL', true, revenue, false, 0.0) )
- / sum(revenue) AS mkt_share
+ SUM( CASE s_name = 'BRAZIL' WHEN true THEN revenue ELSE 0.0 END ) / SUM(revenue) AS mkt_share
FROM (
SELECT o_year AS year,
l_extendedprice * (1 - l_discount) AS revenue,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q12_shipping/q12_shipping.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q12_shipping/q12_shipping.3.query.sqlpp
index 0d778e4..5d0378a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q12_shipping/q12_shipping.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q12_shipping/q12_shipping.3.query.sqlpp
@@ -17,12 +17,12 @@
* under the License.
*/
-use tpch;
+USE tpch;
SELECT l_shipmode,
- sum(`switch-case`(o_orderpriority = '1-URGENT' or o_orderpriority = '2-HIGH',true,1,false,0)) high_line_count,
- sum(`switch-case`(o_orderpriority = '1-URGENT' or o_orderpriority = '2-HIGH',true,0,false,1)) low_line_count
+ sum(CASE WHEN o_orderpriority = '1-URGENT' or o_orderpriority = '2-HIGH' THEN 1 ELSE 0 END) high_line_count,
+ sum(CASE o_orderpriority = '1-URGENT' or o_orderpriority = '2-HIGH' WHEN true THEN 0 ELSE 1 END) low_line_count
FROM LineItem,
Orders
WHERE o_orderkey = l_orderkey AND l_commitdate < l_receiptdate AND
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
index 1c10baf..d359369 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
@@ -20,9 +20,9 @@
use tpch;
-select element 100.0 *
- sum(`switch-case`(p_type LIKE 'PROMO%',true, l_extendedprice * (1 - l_discount), false, 0.0))
- / sum(l_extendedprice * (1 - l_discount))
+SELECT ELEMENT 100.0 *
+ SUM( CASE WHEN p_type LIKE 'PROMO%' THEN l_extendedprice * (1 - l_discount) ELSE 0.0 END )
+ / SUM(l_extendedprice * (1 - l_discount))
FROM LineItem,
Part
WHERE l_partkey = p_partkey AND l_shipdate >= '1995-09-01' AND l_shipdate < '1995-10-01'
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q08_national_market_share/q08_national_market_share.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q08_national_market_share/q08_national_market_share.3.query.sqlpp
index 89afd7d..52fd1eb 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q08_national_market_share/q08_national_market_share.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q08_national_market_share/q08_national_market_share.3.query.sqlpp
@@ -21,7 +21,7 @@
SELECT year AS year,
- sum( `switch-case`(t.s_name = 'BRAZIL', true, t.revenue, false, 0.0) )
+ sum( case when t.s_name = 'BRAZIL' then t.revenue else 0.0 end )
/ sum(t.revenue) AS mkt_share
FROM (
SELECT o_year AS year,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q12_shipping/q12_shipping.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q12_shipping/q12_shipping.3.query.sqlpp
index 3be8e22..227a576 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q12_shipping/q12_shipping.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q12_shipping/q12_shipping.3.query.sqlpp
@@ -21,8 +21,8 @@
SELECT l_shipmode l_shipmode,
- sum(`switch-case`(o.o_orderpriority = '1-URGENT' or o.o_orderpriority = '2-HIGH',true,1,false,0)) high_line_count,
- sum(`switch-case`(o.o_orderpriority = '1-URGENT' or o.o_orderpriority = '2-HIGH',true,0,false,1)) low_line_count
+ sum(case when o.o_orderpriority = '1-URGENT' or o.o_orderpriority = '2-HIGH' then 1 else 0 end) high_line_count,
+ sum(case when o.o_orderpriority = '1-URGENT' or o.o_orderpriority = '2-HIGH' then 0 else 1 end) low_line_count
FROM LineItem l,
Orders o
WHERE o.o_orderkey = l.l_orderkey AND l.l_commitdate < l.l_receiptdate AND
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
index dc26e42..0d11017 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
@@ -21,7 +21,7 @@
select element 100.0 *
- sum(`switch-case`(p.p_type like 'PROMO%',true,(l.l_extendedprice * (1 - l.l_discount)),false,0.0))
+ sum( case when p.p_type like 'PROMO%' then l.l_extendedprice * (1 - l.l_discount) else 0.0 end)
/ sum(l.l_extendedprice * (1 - l.l_discount))
FROM LineItem l,
Part p
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q08_national_market_share/q08_national_market_share.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q08_national_market_share/q08_national_market_share.3.query.sqlpp
index 3c1a921..b9b739d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q08_national_market_share/q08_national_market_share.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q08_national_market_share/q08_national_market_share.3.query.sqlpp
@@ -21,7 +21,7 @@
select element {'year':year,'mkt_share':(tpch.coll_sum((
- select element tpch.`switch-case`((i.s_name = 'BRAZIL'),true,i.revenue,false,0.0)
+ select element case i.s_name = 'BRAZIL' when true then i.revenue when false then 0.0 end
from t as i
)) / tpch.coll_sum((
select element i.revenue
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q12_shipping/q12_shipping.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q12_shipping/q12_shipping.3.query.sqlpp
index 879f936..395279b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q12_shipping/q12_shipping.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q12_shipping/q12_shipping.3.query.sqlpp
@@ -21,10 +21,16 @@
select element {'l_shipmode':l_shipmode,'high_line_count':tpch.coll_sum((
- select element tpch.`switch-case`(((i.o_orderpriority = '1-URGENT') or (i.o_orderpriority = '2-HIGH')),true,1,false,0)
+ select element case
+ when i.o_orderpriority = '1-URGENT' or i.o_orderpriority = '2-HIGH' then 1
+ else 0
+ end
from o as i
)),'low_line_count':tpch.coll_sum((
- select element tpch.`switch-case`(((i.o_orderpriority = '1-URGENT') or (i.o_orderpriority = '2-HIGH')),true,0,false,1)
+ select element case
+ when i.o_orderpriority = '1-URGENT' or i.o_orderpriority = '2-HIGH' then 0
+ else 1
+ end
from o as i
))}
from LineItem as l,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
index eb556b16..5de0352 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-with-index/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
@@ -21,7 +21,10 @@
select element (100.0 * tpch.coll_sum((
- select element tpch.`switch-case`(i.p_type like 'PROMO%',true,(i.l_extendedprice * (1 - i.l_discount)),false,0.0)
+ select element case
+ when i.p_type like 'PROMO%' then i.l_extendedprice * (1 - i.l_discount)
+ else 0.0
+ end
from lp as i
)) / tpch.coll_sum((
select element (i.l_extendedprice * (1 - i.l_discount))
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.query.sqlpp
index aaef8e5..70b59e0 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.query.sqlpp
@@ -21,7 +21,7 @@
select element {'year':year,'mkt_share':(COLL_SUM((
- select element tpch.`switch-case`((i.s_name = 'BRAZIL'),true,i.revenue,false,0.0)
+ select element case i.s_name = 'BRAZIL' when true then i.revenue when false then 0.0 end
from t as i
)) / COLL_SUM((
select element i.revenue
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q12_shipping/q12_shipping.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q12_shipping/q12_shipping.3.query.sqlpp
index c089f72..58d0c9e 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q12_shipping/q12_shipping.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q12_shipping/q12_shipping.3.query.sqlpp
@@ -21,10 +21,11 @@
select element {'l_shipmode':l_shipmode,'high_line_count':COLL_SUM((
- select element tpch.`switch-case`(((i.o_orderpriority = '1-URGENT') or (i.o_orderpriority = '2-HIGH')),true,1,false,0)
+ select element
+ CASE i.o_orderpriority = '1-URGENT' OR i.o_orderpriority = '2-HIGH' WHEN true THEN 1 WHEN false THEN 0 END
from o as i
)),'low_line_count':COLL_SUM((
- select element tpch.`switch-case`(((i.o_orderpriority = '1-URGENT') or (i.o_orderpriority = '2-HIGH')),true,0,false,1)
+ select element case when i.o_orderpriority = '1-URGENT' OR i.o_orderpriority = '2-HIGH' then 0 else 1 end
from o as i
))}
from LineItem as l,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
index ba7de7d..32ab76a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.query.sqlpp
@@ -21,7 +21,7 @@
select element (100.0 * COLL_SUM((
- select element tpch.`switch-case`(i.p_type like 'PROMO%',true,(i.l_extendedprice * (1 - i.l_discount)),false,0.0)
+ select element case i.p_type like 'PROMO%' when true then i.l_extendedprice * (1 - i.l_discount) else 0.0 end
from lp as i
)) / COLL_SUM((
select element (i.l_extendedprice * (1 - i.l_discount))
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/user-defined-functions/query-issue218-2/query-issue218-2.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/user-defined-functions/query-issue218-2/query-issue218-2.1.ddl.sqlpp
index f535ffe..6942fc8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/user-defined-functions/query-issue218-2/query-issue218-2.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/user-defined-functions/query-issue218-2/query-issue218-2.1.ddl.sqlpp
@@ -28,8 +28,8 @@
create function test.computeBonus(pbcRating,salary)
{
- if (pbcRating = 1) then
- salary * 0.25
- else
- salary * 0.10
+ CASE
+ WHEN pbcRating = 1 THEN salary * 0.25
+ ELSE salary * 0.10
+ END
}
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/user-defined-functions/query-issue218/query-issue218.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/user-defined-functions/query-issue218/query-issue218.1.ddl.sqlpp
index bc22967..28f84bf 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/user-defined-functions/query-issue218/query-issue218.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/user-defined-functions/query-issue218/query-issue218.1.ddl.sqlpp
@@ -28,8 +28,8 @@
create function test.computeBonus(pbcRating, salary)
{
- if (pbcRating = 1) then
- salary * 0.25
- else
- salary * 0.10
+ CASE
+ WHEN pbcRating = 1 THEN salary * 0.25
+ ELSE salary * 0.10
+ END
}
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_01/case_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_01/case_01.1.adm
new file mode 100644
index 0000000..f433f2f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_01/case_01.1.adm
@@ -0,0 +1,6 @@
+{ "$1": 0.0 }
+{ "$1": 2.0 }
+{ "$1": 1.0 }
+{ "$1": 0.5 }
+{ "$1": null }
+{ }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_02/case_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_02/case_02.1.adm
new file mode 100644
index 0000000..7c61d7b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_02/case_02.1.adm
@@ -0,0 +1,6 @@
+{ "$1": 0.0 }
+{ "$1": 2.0 }
+{ "$1": 1.0 }
+{ "$1": 0.5 }
+{ "$1": -1 }
+{ "$1": -2 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_03/case_03.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_03/case_03.1.adm
new file mode 100644
index 0000000..bcced75
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_03/case_03.1.adm
@@ -0,0 +1,6 @@
+{ "$1": [ { "r": 0 } ] }
+{ "$1": [ { "r": -3 } ] }
+{ "$1": [ { "r": -3 } ] }
+{ "$1": [ { "r": -3 } ] }
+{ "$1": [ { "r": -1 } ] }
+{ "$1": [ { "r": -2 } ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_04/case_04.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_04/case_04.1.adm
new file mode 100644
index 0000000..f2a1ae7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_04/case_04.1.adm
@@ -0,0 +1,6 @@
+{ "$1": [ 0 ] }
+{ "$1": 2.0 }
+{ "$1": 1.0 }
+{ "$1": 0.5 }
+{ "$1": [ { "$2": -1 } ] }
+{ "$1": [ { "$3": -2 } ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_05/case_05.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_05/case_05.1.adm
new file mode 100644
index 0000000..5d37fcc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_05/case_05.1.adm
@@ -0,0 +1,6 @@
+{ "$1": [ 0 ] }
+{ "$1": null }
+{ }
+{ "$1": 0.5 }
+{ "$1": [ { "$2": -1 } ] }
+{ "$1": [ { "$3": -2 } ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_06/case_06.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_06/case_06.1.adm
new file mode 100644
index 0000000..69e44e4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/case_06/case_06.1.adm
@@ -0,0 +1,6 @@
+{ }
+{ "$1": null }
+{ "$1": null }
+{ "$1": null }
+{ "$1": null }
+{ "$1": null }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/ifthenelse_02/ifthenelse_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/ifthenelse_02/ifthenelse_02.1.adm
new file mode 100644
index 0000000..f599e28
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/ifthenelse_02/ifthenelse_02.1.adm
@@ -0,0 +1 @@
+10
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819-2/query-ASTERIXDB-819-2.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819-2/query-ASTERIXDB-819-2.1.adm
new file mode 100644
index 0000000..bba55dc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819-2/query-ASTERIXDB-819-2.1.adm
@@ -0,0 +1 @@
+{ "type": "object" }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.adm
new file mode 100644
index 0000000..19765bd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.adm
@@ -0,0 +1 @@
+null
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/null-missing/is/is.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/null-missing/is/is.1.adm
index 79a9c5c..38de473 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/null-missing/is/is.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/null-missing/is/is.1.adm
@@ -1 +1 @@
-{ "1": true, "2": false, "3": false, "4": false, "5": true, "6": true, "7": false, "8": true, "9": false, "10": true, "11": false, "12": true, "13": true, "14": true, "15": false, "16": false, "17": false, "18": true }
+{ "1": true, "3": false, "4": false, "6": true, "7": false, "8": true, "9": false, "10": true, "11": false, "12": true, "13": true, "14": true, "15": false, "16": false, "17": false, "18": true }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.ast
index 2223305..f16c720 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.ast
@@ -1,16 +1,16 @@
DataverseUse test
Query:
SELECT ELEMENT [
-IfExpr [
- Condition:
- OperatorExpr [
+CASE OperatorExpr [
LiteralExpr [LONG] [2]
>
LiteralExpr [LONG] [1]
]
- Then:
- LiteralExpr [LONG] [20]
- Else:
- LiteralExpr [LONG] [10]
-]
+
+WHEN LiteralExpr [TRUE]
+THEN LiteralExpr [LONG] [20]
+
+ELSE LiteralExpr [LONG] [10]
+
+END
]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.ast
index 279175b..1292f1a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.ast
@@ -14,23 +14,24 @@
FunctionCall tpch.sum@1[
(
SELECT ELEMENT [
- FunctionCall tpch.switch-case@5[
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=s_name
+ CASE LiteralExpr [TRUE]
+
+ WHEN OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=s_name
+ ]
+ =
+ LiteralExpr [STRING] [BRAZIL]
]
- =
- LiteralExpr [STRING] [BRAZIL]
- ]
- LiteralExpr [TRUE]
- FieldAccessor [
- Variable [ Name=$i ]
- Field=revenue
- ]
- LiteralExpr [FALSE]
- LiteralExpr [DOUBLE] [0.0]
- ]
+ THEN FieldAccessor [
+ Variable [ Name=$i ]
+ Field=revenue
+ ]
+
+ ELSE LiteralExpr [DOUBLE] [0.0]
+
+ END
]
FROM [ Variable [ Name=$t ]
AS Variable [ Name=$i ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.ast
index b1fee8a..3da470a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.ast
@@ -13,31 +13,35 @@
FunctionCall tpch.sum@1[
(
SELECT ELEMENT [
- FunctionCall tpch.switch-case@5[
- OperatorExpr [
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=o_orderpriority
+ CASE OperatorExpr [
+ OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=o_orderpriority
+ ]
+ =
+ LiteralExpr [STRING] [1-URGENT]
]
- =
- LiteralExpr [STRING] [1-URGENT]
- ]
- or
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=o_orderpriority
+ or
+ OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=o_orderpriority
+ ]
+ =
+ LiteralExpr [STRING] [2-HIGH]
]
- =
- LiteralExpr [STRING] [2-HIGH]
]
- ]
- LiteralExpr [TRUE]
- LiteralExpr [LONG] [1]
- LiteralExpr [FALSE]
- LiteralExpr [LONG] [0]
- ]
+
+ WHEN LiteralExpr [TRUE]
+ THEN LiteralExpr [LONG] [1]
+
+ WHEN LiteralExpr [FALSE]
+ THEN LiteralExpr [LONG] [0]
+
+ ELSE LiteralExpr [NULL]
+
+ END
]
FROM [ Variable [ Name=$o ]
AS Variable [ Name=$i ]
@@ -51,31 +55,35 @@
FunctionCall tpch.sum@1[
(
SELECT ELEMENT [
- FunctionCall tpch.switch-case@5[
- OperatorExpr [
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=o_orderpriority
+ CASE OperatorExpr [
+ OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=o_orderpriority
+ ]
+ =
+ LiteralExpr [STRING] [1-URGENT]
]
- =
- LiteralExpr [STRING] [1-URGENT]
- ]
- or
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=o_orderpriority
+ or
+ OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=o_orderpriority
+ ]
+ =
+ LiteralExpr [STRING] [2-HIGH]
]
- =
- LiteralExpr [STRING] [2-HIGH]
]
- ]
- LiteralExpr [TRUE]
- LiteralExpr [LONG] [0]
- LiteralExpr [FALSE]
- LiteralExpr [LONG] [1]
- ]
+
+ WHEN LiteralExpr [TRUE]
+ THEN LiteralExpr [LONG] [0]
+
+ WHEN LiteralExpr [FALSE]
+ THEN LiteralExpr [LONG] [1]
+
+ ELSE LiteralExpr [NULL]
+
+ END
]
FROM [ Variable [ Name=$o ]
AS Variable [ Name=$i ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.ast
index f9f5c62..1bd404d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.ast
@@ -7,34 +7,38 @@
FunctionCall tpch.sum@1[
(
SELECT ELEMENT [
- FunctionCall tpch.switch-case@5[
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=p_type
- ]
- like
- LiteralExpr [STRING] [PROMO%]
- ]
- LiteralExpr [TRUE]
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=l_extendedprice
- ]
- *
- OperatorExpr [
- LiteralExpr [LONG] [1]
- -
+ CASE OperatorExpr [
FieldAccessor [
Variable [ Name=$i ]
- Field=l_discount
+ Field=p_type
+ ]
+ like
+ LiteralExpr [STRING] [PROMO%]
+ ]
+
+ WHEN LiteralExpr [TRUE]
+ THEN OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=l_extendedprice
+ ]
+ *
+ OperatorExpr [
+ LiteralExpr [LONG] [1]
+ -
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=l_discount
+ ]
]
]
- ]
- LiteralExpr [FALSE]
- LiteralExpr [DOUBLE] [0.0]
- ]
+
+ WHEN LiteralExpr [FALSE]
+ THEN LiteralExpr [DOUBLE] [0.0]
+
+ ELSE LiteralExpr [NULL]
+
+ END
]
FROM [ Variable [ Name=$lp ]
AS Variable [ Name=$i ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.ast
index 279175b..53bdb44 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.ast
@@ -14,23 +14,27 @@
FunctionCall tpch.sum@1[
(
SELECT ELEMENT [
- FunctionCall tpch.switch-case@5[
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=s_name
+ CASE OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=s_name
+ ]
+ =
+ LiteralExpr [STRING] [BRAZIL]
]
- =
- LiteralExpr [STRING] [BRAZIL]
- ]
- LiteralExpr [TRUE]
- FieldAccessor [
- Variable [ Name=$i ]
- Field=revenue
- ]
- LiteralExpr [FALSE]
- LiteralExpr [DOUBLE] [0.0]
- ]
+
+ WHEN LiteralExpr [TRUE]
+ THEN FieldAccessor [
+ Variable [ Name=$i ]
+ Field=revenue
+ ]
+
+ WHEN LiteralExpr [FALSE]
+ THEN LiteralExpr [DOUBLE] [0.0]
+
+ ELSE LiteralExpr [NULL]
+
+ END
]
FROM [ Variable [ Name=$t ]
AS Variable [ Name=$i ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q12_shipping/q12_shipping.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q12_shipping/q12_shipping.3.ast
index b1fee8a..6ad3a5b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q12_shipping/q12_shipping.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q12_shipping/q12_shipping.3.ast
@@ -13,31 +13,35 @@
FunctionCall tpch.sum@1[
(
SELECT ELEMENT [
- FunctionCall tpch.switch-case@5[
- OperatorExpr [
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=o_orderpriority
+ CASE OperatorExpr [
+ OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=o_orderpriority
+ ]
+ =
+ LiteralExpr [STRING] [1-URGENT]
]
- =
- LiteralExpr [STRING] [1-URGENT]
- ]
- or
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=o_orderpriority
+ or
+ OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=o_orderpriority
+ ]
+ =
+ LiteralExpr [STRING] [2-HIGH]
]
- =
- LiteralExpr [STRING] [2-HIGH]
]
- ]
- LiteralExpr [TRUE]
- LiteralExpr [LONG] [1]
- LiteralExpr [FALSE]
- LiteralExpr [LONG] [0]
- ]
+
+ WHEN LiteralExpr [TRUE]
+ THEN LiteralExpr [LONG] [1]
+
+ WHEN LiteralExpr [FALSE]
+ THEN LiteralExpr [LONG] [0]
+
+ ELSE LiteralExpr [NULL]
+
+ END
]
FROM [ Variable [ Name=$o ]
AS Variable [ Name=$i ]
@@ -51,31 +55,32 @@
FunctionCall tpch.sum@1[
(
SELECT ELEMENT [
- FunctionCall tpch.switch-case@5[
- OperatorExpr [
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=o_orderpriority
+ CASE LiteralExpr [TRUE]
+
+ WHEN OperatorExpr [
+ OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=o_orderpriority
+ ]
+ =
+ LiteralExpr [STRING] [1-URGENT]
]
- =
- LiteralExpr [STRING] [1-URGENT]
- ]
- or
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=o_orderpriority
+ or
+ OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=o_orderpriority
+ ]
+ =
+ LiteralExpr [STRING] [2-HIGH]
]
- =
- LiteralExpr [STRING] [2-HIGH]
]
- ]
- LiteralExpr [TRUE]
- LiteralExpr [LONG] [0]
- LiteralExpr [FALSE]
- LiteralExpr [LONG] [1]
- ]
+ THEN LiteralExpr [LONG] [0]
+
+ ELSE LiteralExpr [LONG] [1]
+
+ END
]
FROM [ Variable [ Name=$o ]
AS Variable [ Name=$i ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.ast
index f9f5c62..f619293 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.ast
@@ -7,34 +7,35 @@
FunctionCall tpch.sum@1[
(
SELECT ELEMENT [
- FunctionCall tpch.switch-case@5[
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=p_type
- ]
- like
- LiteralExpr [STRING] [PROMO%]
- ]
- LiteralExpr [TRUE]
- OperatorExpr [
- FieldAccessor [
- Variable [ Name=$i ]
- Field=l_extendedprice
- ]
- *
- OperatorExpr [
- LiteralExpr [LONG] [1]
- -
+ CASE OperatorExpr [
FieldAccessor [
Variable [ Name=$i ]
- Field=l_discount
+ Field=p_type
+ ]
+ like
+ LiteralExpr [STRING] [PROMO%]
+ ]
+
+ WHEN LiteralExpr [TRUE]
+ THEN OperatorExpr [
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=l_extendedprice
+ ]
+ *
+ OperatorExpr [
+ LiteralExpr [LONG] [1]
+ -
+ FieldAccessor [
+ Variable [ Name=$i ]
+ Field=l_discount
+ ]
]
]
- ]
- LiteralExpr [FALSE]
- LiteralExpr [DOUBLE] [0.0]
- ]
+
+ ELSE LiteralExpr [DOUBLE] [0.0]
+
+ END
]
FROM [ Variable [ Name=$lp ]
AS Variable [ Name=$i ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
index 30e99e6..279522a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -3166,6 +3166,11 @@
</compilation-unit>
</test-case>
<test-case FilePath="misc">
+ <compilation-unit name="ifthenelse_02">
+ <output-dir compare="Text">ifthenelse_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
<compilation-unit name="is-null_01">
<output-dir compare="Text">is-null_01</output-dir>
</compilation-unit>
@@ -3224,6 +3229,16 @@
<output-dir compare="Text">query-ASTERIXDB-1203</output-dir>
</compilation-unit>
</test-case>
+ <test-case FilePath="misc">
+ <compilation-unit name="query-ASTERIXDB-819">
+ <output-dir compare="Text">query-ASTERIXDB-819</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
+ <compilation-unit name="query-ASTERIXDB-819-2">
+ <output-dir compare="Text">query-ASTERIXDB-819-2</output-dir>
+ </compilation-unit>
+ </test-case>
</test-group>
<test-group name="open-index-enforced">
<test-group name="open-index-enforced/error-checking">
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index e1d728d..748d924 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -2862,6 +2862,41 @@
</test-group>
<test-group name="misc">
<test-case FilePath="misc">
+ <compilation-unit name="case_01">
+ <output-dir compare="Text">case_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
+ <compilation-unit name="case_02">
+ <output-dir compare="Text">case_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
+ <compilation-unit name="case_03">
+ <output-dir compare="Text">case_03</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
+ <compilation-unit name="case_04">
+ <output-dir compare="Text">case_04</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
+ <compilation-unit name="case_05">
+ <output-dir compare="Text">case_05</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
+ <compilation-unit name="case_06">
+ <output-dir compare="Text">case_06</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
+ <compilation-unit name="case_07">
+ <output-dir compare="Text">case_05</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="misc">
<compilation-unit name="partition-by-nonexistent-field">
<output-dir compare="Text">partition-by-nonexistent-field</output-dir>
<expected-error>java.lang.NullPointerException</expected-error>
diff --git a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
index dd1a1fb..e0579f3 100644
--- a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
+++ b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
@@ -68,14 +68,14 @@
@Override
public Boolean visit(UnionExpr u, List<FunctionDecl> fds) throws AsterixException {
- Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(u.getExprs(), fds);
+ Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(u.getExprs(), fds);
u.setExprs(p.second);
return p.first;
}
@Override
public Boolean visit(DistinctClause dc, List<FunctionDecl> arg) throws AsterixException {
- Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(dc.getDistinctByExpr(), arg);
+ Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(dc.getDistinctByExpr(), arg);
dc.setDistinctByExpr(p.second);
return p.first;
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Expression.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Expression.java
index 6b77fc7..b1df329 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Expression.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Expression.java
@@ -39,7 +39,8 @@
SELECT_EXPRESSION,
PRIMARY_EXPRESSION,
VALUE_EXPRESSION,
- INDEPENDENT_SUBQUERY
+ INDEPENDENT_SUBQUERY,
+ CASE_EXPRESSION
}
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
index e76436a..159af9f 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
@@ -103,7 +103,7 @@
@Override
public Boolean visit(ListConstructor lc, List<FunctionDecl> arg) throws AsterixException {
- Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(lc.getExprList(), arg);
+ Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(lc.getExprList(), arg);
lc.setExprList(p.second);
return p.first;
}
@@ -114,24 +114,24 @@
for (FieldBinding b : rc.getFbList()) {
Pair<Boolean, Expression> leftExprInlined = inlineUdfsInExpr(b.getLeftExpr(), arg);
b.setLeftExpr(leftExprInlined.second);
- changed = changed | leftExprInlined.first;
+ changed = changed || leftExprInlined.first;
Pair<Boolean, Expression> rightExprInlined = inlineUdfsInExpr(b.getRightExpr(), arg);
b.setRightExpr(rightExprInlined.second);
- changed = changed | rightExprInlined.first;
+ changed = changed || rightExprInlined.first;
}
return changed;
}
@Override
public Boolean visit(CallExpr pf, List<FunctionDecl> arg) throws AsterixException {
- Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(pf.getExprList(), arg);
+ Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(pf.getExprList(), arg);
pf.setExprList(p.second);
return p.first;
}
@Override
public Boolean visit(OperatorExpr ifbo, List<FunctionDecl> arg) throws AsterixException {
- Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(ifbo.getExprList(), arg);
+ Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(ifbo.getExprList(), arg);
ifbo.setExprList(p.second);
return p.first;
}
@@ -192,7 +192,7 @@
@Override
public Boolean visit(OrderbyClause oc, List<FunctionDecl> arg) throws AsterixException {
- Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(oc.getOrderbyList(), arg);
+ Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(oc.getOrderbyList(), arg);
oc.setOrderbyList(p.second);
return p.first;
}
@@ -249,53 +249,52 @@
throws AsterixException {
if (expr.getKind() != Kind.CALL_EXPRESSION) {
boolean r = expr.accept(this, arg);
- return new Pair<Boolean, Expression>(r, expr);
+ return new Pair<>(r, expr);
+ }
+ CallExpr f = (CallExpr) expr;
+ boolean r = expr.accept(this, arg);
+ FunctionDecl implem = findFuncDeclaration(f.getFunctionSignature(), arg);
+ if (implem == null) {
+ return new Pair<>(r, expr);
} else {
- CallExpr f = (CallExpr) expr;
- boolean r = expr.accept(this, arg);
- FunctionDecl implem = findFuncDeclaration(f.getFunctionSignature(), arg);
- if (implem == null) {
- return new Pair<Boolean, Expression>(r, expr);
- } else {
- // Rewrite the function body itself (without setting unbounded variables to dataset access).
- // TODO(buyingyi): throw an exception for recursive function definition or limit the stack depth.
- implem.setFuncBody(rewriteFunctionBody(implem.getFuncBody()));
- // it's one of the functions we want to inline
- List<LetClause> clauses = new ArrayList<LetClause>();
- Iterator<VarIdentifier> paramIter = implem.getParamList().iterator();
- VariableSubstitutionEnvironment subts = new VariableSubstitutionEnvironment();
- for (Expression e : f.getExprList()) {
- VarIdentifier param = paramIter.next();
- // Obs: we could do smth about passing also literals, or let
- // variable inlining to take care of this.
- if (e.getKind() == Kind.VARIABLE_EXPRESSION) {
- subts.addSubstituion(new VariableExpr(param), e);
- } else {
- VarIdentifier newV = context.newVariable();
- Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = e.accept(cloneVisitor,
- new VariableSubstitutionEnvironment());
- LetClause c = new LetClause(new VariableExpr(newV), (Expression) p1.first);
- clauses.add(c);
- subts.addSubstituion(new VariableExpr(param), new VariableExpr(newV));
- }
- }
-
- Pair<ILangExpression, VariableSubstitutionEnvironment> p2 = implem.getFuncBody().accept(cloneVisitor,
- subts);
- Expression resExpr;
- if (clauses.isEmpty()) {
- resExpr = (Expression) p2.first;
+ // Rewrite the function body itself (without setting unbounded variables to dataset access).
+ // TODO(buyingyi): throw an exception for recursive function definition or limit the stack depth.
+ implem.setFuncBody(rewriteFunctionBody(implem.getFuncBody()));
+ // it's one of the functions we want to inline
+ List<LetClause> clauses = new ArrayList<>();
+ Iterator<VarIdentifier> paramIter = implem.getParamList().iterator();
+ VariableSubstitutionEnvironment subts = new VariableSubstitutionEnvironment();
+ for (Expression e : f.getExprList()) {
+ VarIdentifier param = paramIter.next();
+ // Obs: we could do smth about passing also literals, or let
+ // variable inlining to take care of this.
+ if (e.getKind() == Kind.VARIABLE_EXPRESSION) {
+ subts.addSubstituion(new VariableExpr(param), e);
} else {
- resExpr = generateQueryExpression(clauses, (Expression) p2.first);
+ VarIdentifier newV = context.newVariable();
+ Pair<ILangExpression, VariableSubstitutionEnvironment> p1 =
+ e.accept(cloneVisitor, new VariableSubstitutionEnvironment());
+ LetClause c = new LetClause(new VariableExpr(newV), (Expression) p1.first);
+ clauses.add(c);
+ subts.addSubstituion(new VariableExpr(param), new VariableExpr(newV));
}
- return new Pair<Boolean, Expression>(true, resExpr);
}
+
+ Pair<ILangExpression, VariableSubstitutionEnvironment> p2 =
+ implem.getFuncBody().accept(cloneVisitor, subts);
+ Expression resExpr;
+ if (clauses.isEmpty()) {
+ resExpr = (Expression) p2.first;
+ } else {
+ resExpr = generateQueryExpression(clauses, (Expression) p2.first);
+ }
+ return new Pair<>(true, resExpr);
}
}
- protected Pair<Boolean, ArrayList<Expression>> inlineUdfsInExprList(List<Expression> exprList,
- List<FunctionDecl> fds) throws AsterixException {
- ArrayList<Expression> newList = new ArrayList<Expression>();
+ protected Pair<Boolean, List<Expression>> inlineUdfsInExprList(List<Expression> exprList, List<FunctionDecl> fds)
+ throws AsterixException {
+ ArrayList<Expression> newList = new ArrayList<>();
boolean changed = false;
for (Expression e : exprList) {
Pair<Boolean, Expression> p = inlineUdfsInExpr(e, fds);
@@ -304,7 +303,7 @@
changed = true;
}
}
- return new Pair<Boolean, ArrayList<Expression>>(changed, newList);
+ return new Pair<>(changed, newList);
}
protected Expression rewriteFunctionBody(Expression expr) throws AsterixException {
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java
index 1fd561e..073e413 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java
@@ -48,7 +48,7 @@
public abstract class SubstituteExpressionVisitor
extends AbstractQueryExpressionVisitor<Expression, ExpressionSubstitutionEnvironment> {
- private final DeepCopier deepCopier;
+ protected final DeepCopier deepCopier;
public SubstituteExpressionVisitor(DeepCopier deepCopier) {
this.deepCopier = deepCopier;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/CaseExpression.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/CaseExpression.java
new file mode 100644
index 0000000..45ff082
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/CaseExpression.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.lang.sqlpp.expression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.expression.LiteralExpr;
+import org.apache.asterix.lang.common.literal.NullLiteral;
+import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.commons.lang3.ObjectUtils;
+
+public class CaseExpression implements Expression {
+
+ private Expression conditionExpr;
+ private List<Expression> whenExprs = new ArrayList<>();
+ private List<Expression> thenExprs = new ArrayList<>();
+ private Expression elseExpr; // elseExpr could be null.
+
+ public CaseExpression(Expression conditionExpr, List<Expression> whenExprs, List<Expression> thenExprs,
+ Expression elseExpr) {
+ this.conditionExpr = conditionExpr;
+ this.whenExprs.addAll(whenExprs);
+ this.thenExprs.addAll(thenExprs);
+
+ // If no when expression matches the case expr, we return null
+ this.elseExpr = elseExpr == null ? new LiteralExpr(NullLiteral.INSTANCE) : elseExpr;
+ }
+
+ @Override
+ public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
+ return ((ISqlppVisitor<R, T>) visitor).visit(this, arg);
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.CASE_EXPRESSION;
+ }
+
+ public Expression getConditionExpr() {
+ return conditionExpr;
+ }
+
+ public Expression getElseExpr() {
+ return elseExpr;
+ }
+
+ public List<Expression> getWhenExprs() {
+ return whenExprs;
+ }
+
+ public List<Expression> getThenExprs() {
+ return thenExprs;
+ }
+
+ public void setConditionExpr(Expression conditionExpr) {
+ this.conditionExpr = conditionExpr;
+ }
+
+ public void setElseExpr(Expression elseExpr) {
+ this.elseExpr = elseExpr;
+ }
+
+ public void setWhenExprs(List<Expression> whenExprs) {
+ this.whenExprs = whenExprs;
+ }
+
+ public void setThenExprs(List<Expression> thenExprs) {
+ this.thenExprs = thenExprs;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("CASE ");
+ sb.append(conditionExpr);
+ sb.append("\n");
+ for (int index = 0; index < whenExprs.size(); ++index) {
+ sb.append("WHEN ");
+ sb.append(whenExprs.get(index));
+ sb.append(" THEN ");
+ sb.append(thenExprs.get(index));
+ sb.append("\n");
+ }
+ sb.append("ELSE ");
+ sb.append(elseExpr);
+ sb.append("END\n");
+ return sb.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(conditionExpr, elseExpr, thenExprs, whenExprs);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof CaseExpression)) {
+ return false;
+ }
+ CaseExpression target = (CaseExpression) object;
+ return ObjectUtils.equals(conditionExpr, target.conditionExpr) && ObjectUtils.equals(elseExpr, target.elseExpr)
+ && ObjectUtils.equals(thenExprs, target.thenExprs) && ObjectUtils.equals(thenExprs, thenExprs);
+ }
+
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index d0e2aa3..c85097d 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -45,6 +45,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.parser.FunctionParser;
@@ -441,5 +442,18 @@
return null;
}
+ @Override
+ public Void visit(CaseExpression caseExpression, Void arg) throws AsterixException {
+ caseExpression.getConditionExpr().accept(this, arg);
+ for (Expression expr : caseExpression.getWhenExprs()) {
+ expr.accept(this, arg);
+ }
+ for (Expression expr : caseExpression.getThenExprs()) {
+ expr.accept(this, arg);
+ }
+ caseExpression.getElseExpr().accept(this, arg);
+ return null;
+ }
+
}
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
index 57cbdc5..4aa25d7 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
@@ -64,6 +64,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -462,6 +463,19 @@
return null;
}
+ @Override
+ public Void visit(CaseExpression caseExpression, Boolean overwriteWithGbyKeyVarRefs) throws AsterixException {
+ caseExpression.getConditionExpr().accept(this, overwriteWithGbyKeyVarRefs);
+ for (Expression expr : caseExpression.getWhenExprs()) {
+ expr.accept(this, overwriteWithGbyKeyVarRefs);
+ }
+ for (Expression expr : caseExpression.getThenExprs()) {
+ expr.accept(this, overwriteWithGbyKeyVarRefs);
+ }
+ caseExpression.getElseExpr().accept(this, overwriteWithGbyKeyVarRefs);
+ return null;
+ }
+
private void removeSubsutitions(AbstractBinaryCorrelateClause unnestClause) {
scopeChecker.getCurrentScope().removeSymbolExpressionMapping(unnestClause.getRightVariable());
if (unnestClause.hasPositionalVariable()) {
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
index e046ccf..a3346ed 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
@@ -21,13 +21,20 @@
import java.util.ArrayList;
import java.util.List;
+import org.apache.asterix.common.config.MetadataConstants;
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.common.functions.FunctionSignature;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.ILangExpression;
import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.LiteralExpr;
+import org.apache.asterix.lang.common.expression.OperatorExpr;
+import org.apache.asterix.lang.common.literal.TrueLiteral;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
+import org.apache.asterix.lang.sqlpp.util.SqlppRewriteUtil;
import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppSimpleExpressionVisitor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
public class SqlppBuiltinFunctionRewriteVisitor extends AbstractSqlppSimpleExpressionVisitor {
@@ -44,4 +51,49 @@
return callExpr;
}
+ @Override
+ public Expression visit(CaseExpression caseExpr, ILangExpression arg) throws AsterixException {
+ Expression expr = super.visit(caseExpr, arg); // Visits it as usual first.
+ if (expr != caseExpr) {
+ return expr.accept(this, arg);
+ }
+ CaseExpression newCaseExpr = normalizeCaseExpr(caseExpr);
+ if (SqlppRewriteUtil.constainsSubquery(newCaseExpr)) {
+ // If the CASE expression contains a subquery, we do not rewrite it to a switch-case function call.
+ return newCaseExpr;
+ }
+ // If the CASE expression does not contain a subquery, we rewrite it to a switch-case function call.
+ FunctionSignature functionSignature = new FunctionSignature(MetadataConstants.METADATA_DATAVERSE_NAME,
+ "switch-case", FunctionIdentifier.VARARGS);
+ List<Expression> whenExprList = newCaseExpr.getWhenExprs();
+ List<Expression> thenExprList = newCaseExpr.getThenExprs();
+ List<Expression> newExprList = new ArrayList<>();
+ newExprList.add(newCaseExpr.getConditionExpr());
+ for (int index = 0; index < whenExprList.size(); ++index) {
+ newExprList.add(whenExprList.get(index));
+ newExprList.add(thenExprList.get(index));
+ }
+ newExprList.add(newCaseExpr.getElseExpr());
+ return new CallExpr(functionSignature, newExprList);
+ }
+
+ // Normalizes WHEN expressions so that it can have correct NULL/MISSING semantics as well
+ // as type promotion semantics.
+ private CaseExpression normalizeCaseExpr(CaseExpression caseExpr) throws AsterixException {
+ LiteralExpr trueLiteral = new LiteralExpr(TrueLiteral.INSTANCE);
+ Expression conditionExpr = caseExpr.getConditionExpr();
+ if (trueLiteral.equals(conditionExpr)) {
+ return caseExpr;
+ }
+ List<Expression> normalizedWhenExprs = new ArrayList<>();
+ for (Expression expr : caseExpr.getWhenExprs()) {
+ OperatorExpr operatorExpr = new OperatorExpr();
+ operatorExpr.addOperand((Expression) SqlppRewriteUtil.deepCopy(expr));
+ operatorExpr.addOperand(caseExpr.getConditionExpr());
+ operatorExpr.addOperator("=");
+ normalizedWhenExprs.add(operatorExpr);
+ }
+ return new CaseExpression(trueLiteral, normalizedWhenExprs, caseExpr.getThenExprs(), caseExpr.getElseExpr());
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
index 194c029..d2730ff 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
@@ -43,6 +43,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -75,9 +76,7 @@
protected Expression generateQueryExpression(List<LetClause> letClauses, Expression returnExpr)
throws AsterixException {
Map<VariableExpr, Expression> varExprMap = extractLetBindingVariableExpressionMappings(letClauses);
- Expression inlinedReturnExpr = (Expression) SqlppVariableSubstitutionUtil
- .substituteVariableWithoutContext(returnExpr, varExprMap);
- return inlinedReturnExpr;
+ return (Expression) SqlppVariableSubstitutionUtil.substituteVariableWithoutContext(returnExpr, varExprMap);
}
@Override
@@ -231,9 +230,28 @@
return p.first;
}
+ @Override
+ public Boolean visit(CaseExpression caseExpr, List<FunctionDecl> funcs) throws AsterixException {
+ Pair<Boolean, Expression> result = inlineUdfsInExpr(caseExpr.getConditionExpr(), funcs);
+ caseExpr.setConditionExpr(result.second);
+ boolean inlined = result.first;
+
+ Pair<Boolean, List<Expression>> inlinedList = inlineUdfsInExprList(caseExpr.getWhenExprs(), funcs);
+ inlined = inlined || inlinedList.first;
+ caseExpr.setWhenExprs(inlinedList.second);
+
+ inlinedList = inlineUdfsInExprList(caseExpr.getThenExprs(), funcs);
+ inlined = inlined || inlinedList.first;
+ caseExpr.setThenExprs(inlinedList.second);
+
+ result = inlineUdfsInExpr(caseExpr.getElseExpr(), funcs);
+ caseExpr.setElseExpr(result.second);
+ return inlined || result.first;
+ }
+
private Map<VariableExpr, Expression> extractLetBindingVariableExpressionMappings(List<LetClause> letClauses)
throws AsterixException {
- Map<VariableExpr, Expression> varExprMap = new HashMap<VariableExpr, Expression>();
+ Map<VariableExpr, Expression> varExprMap = new HashMap<>();
for (LetClause lc : letClauses) {
// inline let variables one by one iteratively.
lc.setBindingExpr((Expression) SqlppVariableSubstitutionUtil
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
index 4a8c69d..9bc1813 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
@@ -28,6 +28,7 @@
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGroupBySugarVisitor;
+import org.apache.asterix.lang.sqlpp.visitor.CheckSubqueryVisitor;
import org.apache.asterix.lang.sqlpp.visitor.DeepCopyVisitor;
import org.apache.asterix.lang.sqlpp.visitor.FreeVariableVisitor;
@@ -60,4 +61,13 @@
return expr.accept(visitor, null);
}
+ // Checks if an ILangExpression contains a subquery.
+ public static boolean constainsSubquery(ILangExpression expr) throws AsterixException {
+ if (expr == null) {
+ return false;
+ }
+ CheckSubqueryVisitor visitor = new CheckSubqueryVisitor();
+ return expr.accept(visitor, null);
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSql92AggregateVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSql92AggregateVisitor.java
index 669b0a8..ca25775 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSql92AggregateVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSql92AggregateVisitor.java
@@ -55,13 +55,14 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor;
/**
- * This visitor checks if a language construct contains SQL-92 aggregates.
+ * This visitor checks if a non-subquery language construct contains SQL-92 aggregates.
*/
public class CheckSql92AggregateVisitor extends AbstractSqlppQueryExpressionVisitor<Boolean, ILangExpression> {
@@ -271,4 +272,10 @@
return false;
}
+ @Override
+ public Boolean visit(CaseExpression caseExpr, ILangExpression arg) throws AsterixException {
+ return caseExpr.getConditionExpr().accept(this, arg) || visitExprList(caseExpr.getWhenExprs(), arg)
+ || visitExprList(caseExpr.getThenExprs(), arg) || caseExpr.getElseExpr().accept(this, arg);
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
new file mode 100644
index 0000000..e772df5
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.lang.sqlpp.visitor;
+
+import java.util.List;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.ILangExpression;
+import org.apache.asterix.lang.common.clause.GroupbyClause;
+import org.apache.asterix.lang.common.clause.LetClause;
+import org.apache.asterix.lang.common.clause.LimitClause;
+import org.apache.asterix.lang.common.clause.OrderbyClause;
+import org.apache.asterix.lang.common.clause.WhereClause;
+import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.FieldAccessor;
+import org.apache.asterix.lang.common.expression.FieldBinding;
+import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
+import org.apache.asterix.lang.common.expression.IfExpr;
+import org.apache.asterix.lang.common.expression.IndexAccessor;
+import org.apache.asterix.lang.common.expression.ListConstructor;
+import org.apache.asterix.lang.common.expression.LiteralExpr;
+import org.apache.asterix.lang.common.expression.OperatorExpr;
+import org.apache.asterix.lang.common.expression.QuantifiedExpression;
+import org.apache.asterix.lang.common.expression.RecordConstructor;
+import org.apache.asterix.lang.common.expression.UnaryExpr;
+import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.statement.FunctionDecl;
+import org.apache.asterix.lang.common.statement.Query;
+import org.apache.asterix.lang.common.struct.Identifier;
+import org.apache.asterix.lang.common.struct.QuantifiedPair;
+import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
+import org.apache.asterix.lang.sqlpp.clause.FromClause;
+import org.apache.asterix.lang.sqlpp.clause.FromTerm;
+import org.apache.asterix.lang.sqlpp.clause.HavingClause;
+import org.apache.asterix.lang.sqlpp.clause.JoinClause;
+import org.apache.asterix.lang.sqlpp.clause.NestClause;
+import org.apache.asterix.lang.sqlpp.clause.Projection;
+import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
+import org.apache.asterix.lang.sqlpp.clause.SelectClause;
+import org.apache.asterix.lang.sqlpp.clause.SelectElement;
+import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
+import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
+import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
+import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
+import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
+import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
+import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor;
+import org.apache.hyracks.algebricks.common.utils.Pair;
+
+/**
+ * This visitor recursively checks if there is a subquery in the argument language construct.
+ */
+public class CheckSubqueryVisitor extends AbstractSqlppQueryExpressionVisitor<Boolean, ILangExpression> {
+
+ @Override
+ public Boolean visit(FromClause fromClause, ILangExpression arg) throws AsterixException {
+ for (FromTerm fromTerm : fromClause.getFromTerms()) {
+ if (fromTerm.accept(this, arg)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public Boolean visit(FromTerm fromTerm, ILangExpression arg) throws AsterixException {
+ if (visit(fromTerm.getLeftExpression(), arg)) {
+ return true;
+ }
+ for (AbstractBinaryCorrelateClause correlateClause : fromTerm.getCorrelateClauses()) {
+ if (correlateClause.accept(this, arg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Boolean visit(JoinClause joinClause, ILangExpression arg) throws AsterixException {
+ return visit(joinClause.getRightExpression(), arg) || visit(joinClause.getConditionExpression(), arg);
+ }
+
+ @Override
+ public Boolean visit(NestClause nestClause, ILangExpression arg) throws AsterixException {
+ return nestClause.accept(this, arg);
+ }
+
+ @Override
+ public Boolean visit(Projection projection, ILangExpression arg) throws AsterixException {
+ if (projection.star()) {
+ return false;
+ }
+ return visit(projection.getExpression(), arg);
+ }
+
+ @Override
+ public Boolean visit(SelectBlock selectBlock, ILangExpression arg) throws AsterixException {
+ boolean hasSubquery = visit(selectBlock.getFromClause(), arg) || visit(selectBlock.getGroupbyClause(), arg)
+ || visit(selectBlock.getHavingClause(), arg) || visit(selectBlock.getWhereClause(), arg);
+ return hasSubquery || visit(selectBlock.getSelectClause(), arg) || visit(selectBlock.getLetList(), arg)
+ || visit(selectBlock.getLetListAfterGroupby(), arg);
+ }
+
+ @Override
+ public Boolean visit(SelectClause selectClause, ILangExpression arg) throws AsterixException {
+ return visit(selectClause.getSelectElement(), arg) || visit(selectClause.getSelectRegular(), arg);
+ }
+
+ @Override
+ public Boolean visit(SelectElement selectElement, ILangExpression arg) throws AsterixException {
+ return visit(selectElement.getExpression(), arg);
+ }
+
+ @Override
+ public Boolean visit(SelectRegular selectRegular, ILangExpression arg) throws AsterixException {
+ return visit(selectRegular.getProjections(), arg);
+ }
+
+ @Override
+ public Boolean visit(SelectSetOperation selectSetOperation, ILangExpression arg) throws AsterixException {
+ if (selectSetOperation.getLeftInput().accept(this, arg)) {
+ return true;
+ }
+ for (SetOperationRight right : selectSetOperation.getRightInputs()) {
+ if (right.getSetOperationRightInput().accept(this, arg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Boolean visit(SelectExpression selectStatement, ILangExpression arg) throws AsterixException {
+ if (selectStatement.isSubquery()) {
+ return true;
+ }
+ return visit(selectStatement.getLetList(), arg) || visit(selectStatement.getSelectSetOperation(), arg)
+ || visit(selectStatement.getOrderbyClause(), arg) || visit(selectStatement.getLimitClause(), arg);
+
+ }
+
+ @Override
+ public Boolean visit(UnnestClause unnestClause, ILangExpression arg) throws AsterixException {
+ return visit(unnestClause.getRightExpression(), arg);
+ }
+
+ @Override
+ public Boolean visit(HavingClause havingClause, ILangExpression arg) throws AsterixException {
+ return visit(havingClause.getFilterExpression(), arg);
+ }
+
+ @Override
+ public Boolean visit(IndependentSubquery independentSubquery, ILangExpression arg) throws AsterixException {
+ return visit(independentSubquery.getExpr(), arg);
+ }
+
+ @Override
+ public Boolean visit(CaseExpression caseExpression, ILangExpression arg) throws AsterixException {
+ return visit(caseExpression.getConditionExpr(), arg) || visit(caseExpression.getWhenExprs(), arg)
+ || visit(caseExpression.getThenExprs(), arg) || visit(caseExpression.getElseExpr(), arg);
+ }
+
+ @Override
+ public Boolean visit(Query q, ILangExpression arg) throws AsterixException {
+ return visit(q.getBody(), arg);
+ }
+
+ @Override
+ public Boolean visit(FunctionDecl fd, ILangExpression arg) throws AsterixException {
+ return fd.getFuncBody().accept(this, arg);
+ }
+
+ @Override
+ public Boolean visit(LiteralExpr l, ILangExpression arg) throws AsterixException {
+ return false;
+ }
+
+ @Override
+ public Boolean visit(VariableExpr v, ILangExpression arg) throws AsterixException {
+ return false;
+ }
+
+ @Override
+ public Boolean visit(ListConstructor lc, ILangExpression arg) throws AsterixException {
+ return visit(lc.getExprList(), arg);
+ }
+
+ @Override
+ public Boolean visit(RecordConstructor rc, ILangExpression arg) throws AsterixException {
+ for (FieldBinding fb : rc.getFbList()) {
+ if (visit(fb.getLeftExpr(), arg)) {
+ return true;
+ }
+ if (visit(fb.getRightExpr(), arg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Boolean visit(OperatorExpr operatorExpr, ILangExpression arg) throws AsterixException {
+ return visit(operatorExpr.getExprList(), arg);
+ }
+
+ @Override
+ public Boolean visit(FieldAccessor fa, ILangExpression arg) throws AsterixException {
+ return visit(fa.getExpr(), arg);
+ }
+
+ @Override
+ public Boolean visit(IndexAccessor ia, ILangExpression arg) throws AsterixException {
+ return visit(ia.getExpr(), arg) || visit(ia.getIndexExpr(), arg);
+ }
+
+ @Override
+ public Boolean visit(IfExpr ifexpr, ILangExpression arg) throws AsterixException {
+ return visit(ifexpr.getCondExpr(), arg) || visit(ifexpr.getThenExpr(), arg) || visit(ifexpr.getElseExpr(), arg);
+ }
+
+ @Override
+ public Boolean visit(QuantifiedExpression qe, ILangExpression arg) throws AsterixException {
+ for (QuantifiedPair qf : qe.getQuantifiedList()) {
+ if (visit(qf.getExpr(), arg)) {
+ return true;
+ }
+ }
+ return visit(qe.getSatisfiesExpr(), arg);
+ }
+
+ @Override
+ public Boolean visit(LetClause lc, ILangExpression arg) throws AsterixException {
+ return visit(lc.getBindingExpr(), arg);
+ }
+
+ @Override
+ public Boolean visit(WhereClause wc, ILangExpression arg) throws AsterixException {
+ return visit(wc.getWhereExpr(), arg);
+ }
+
+ @Override
+ public Boolean visit(OrderbyClause oc, ILangExpression arg) throws AsterixException {
+ return visit(oc.getOrderbyList(), arg);
+ }
+
+ @Override
+ public Boolean visit(GroupbyClause gc, ILangExpression arg) throws AsterixException {
+ for (GbyVariableExpressionPair key : gc.getGbyPairList()) {
+ if (visit(key.getExpr(), arg)) {
+ return true;
+ }
+ }
+ for (GbyVariableExpressionPair key : gc.getDecorPairList()) {
+ if (visit(key.getExpr(), arg)) {
+ return true;
+ }
+ }
+ for (Pair<Expression, Identifier> field : gc.getGroupFieldList()) {
+ if (visit(field.first, arg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Boolean visit(LimitClause lc, ILangExpression arg) throws AsterixException {
+ return visit(lc.getLimitExpr(), arg) || visit(lc.getOffset(), arg);
+ }
+
+ @Override
+ public Boolean visit(UnaryExpr u, ILangExpression arg) throws AsterixException {
+ return visit(u.getExpr(), arg);
+ }
+
+ @Override
+ public Boolean visit(CallExpr callExpr, ILangExpression arg) throws AsterixException {
+ return visit(callExpr.getExprList(), arg);
+ }
+
+ private boolean visit(List<?> langExprs, ILangExpression arg) throws AsterixException {
+ for (Object o : langExprs) {
+ ILangExpression langExpr = (ILangExpression) o;
+ if (langExpr.accept(this, arg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean visit(ILangExpression langExpr, ILangExpression arg) throws AsterixException {
+ if (langExpr == null) {
+ return false;
+ }
+ return langExpr.accept(this, arg);
+ }
+}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
index bafb8c0..01f3524 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
@@ -60,6 +60,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
@@ -334,11 +335,7 @@
@Override
public ListConstructor visit(ListConstructor lc, Void arg) throws AsterixException {
- List<Expression> newExprList = new ArrayList<>();
- for (Expression expr : lc.getExprList()) {
- newExprList.add((Expression) expr.accept(this, arg));
- }
- return new ListConstructor(lc.getType(), newExprList);
+ return new ListConstructor(lc.getType(), copyExprList(lc.getExprList(), arg));
}
@Override
@@ -354,12 +351,8 @@
@Override
public OperatorExpr visit(OperatorExpr operatorExpr, Void arg) throws AsterixException {
- List<Expression> newExprList = new ArrayList<>();
- for (Expression expr : operatorExpr.getExprList()) {
- newExprList.add((Expression) expr.accept(this, arg));
- }
- return new OperatorExpr(newExprList, operatorExpr.getExprBroadcastIdx(), operatorExpr.getOpList(),
- operatorExpr.isCurrentop());
+ return new OperatorExpr(copyExprList(operatorExpr.getExprList(), arg), operatorExpr.getExprBroadcastIdx(),
+ operatorExpr.getOpList(), operatorExpr.isCurrentop());
}
@Override
@@ -415,7 +408,7 @@
Expression expr = (Expression) ia.getExpr().accept(this, arg);
Expression indexExpr = null;
if (ia.getIndexExpr() != null) {
- indexExpr = ia.getIndexExpr();
+ indexExpr = (Expression) ia.getIndexExpr().accept(this, arg);
}
return new IndexAccessor(expr, indexExpr);
}
@@ -425,4 +418,21 @@
return new IndependentSubquery((Expression) independentSubquery.getExpr().accept(this, arg));
}
+ @Override
+ public ILangExpression visit(CaseExpression caseExpr, Void arg) throws AsterixException {
+ Expression conditionExpr = (Expression) caseExpr.getConditionExpr().accept(this, arg);
+ List<Expression> whenExprList = copyExprList(caseExpr.getWhenExprs(), arg);
+ List<Expression> thenExprList = copyExprList(caseExpr.getThenExprs(), arg);
+ Expression elseExpr = (Expression) caseExpr.getElseExpr().accept(this, arg);
+ return new CaseExpression(conditionExpr, whenExprList, thenExprList, elseExpr);
+ }
+
+ private List<Expression> copyExprList(List<Expression> exprs, Void arg) throws AsterixException {
+ List<Expression> newExprList = new ArrayList<>();
+ for (Expression expr : exprs) {
+ newExprList.add((Expression) expr.accept(this, arg));
+ }
+ return newExprList;
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
index 37c19ab..20b144c 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
@@ -60,6 +60,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -159,8 +160,8 @@
Collection<VariableExpr> fromBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause());
Collection<VariableExpr> letsBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getLetList());
Collection<VariableExpr> gbyBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getGroupbyClause());
- Collection<VariableExpr> gbyLetsBindingVars = SqlppVariableUtil
- .getBindingVariables(selectBlock.getLetListAfterGroupby());
+ Collection<VariableExpr> gbyLetsBindingVars =
+ SqlppVariableUtil.getBindingVariables(selectBlock.getLetListAfterGroupby());
selectBlock.getSelectClause().accept(this, selectFreeVars);
// Removes group-by, from, let, and gby-let binding vars.
@@ -270,9 +271,7 @@
@Override
public Void visit(OrderbyClause oc, Collection<VariableExpr> freeVars) throws AsterixException {
- for (Expression orderExpr : oc.getOrderbyList()) {
- orderExpr.accept(this, freeVars);
- }
+ visit(oc.getOrderbyList(), freeVars);
return null;
}
@@ -340,9 +339,7 @@
@Override
public Void visit(ListConstructor lc, Collection<VariableExpr> freeVars) throws AsterixException {
- for (Expression expr : lc.getExprList()) {
- expr.accept(this, freeVars);
- }
+ visit(lc.getExprList(), freeVars);
return null;
}
@@ -357,9 +354,7 @@
@Override
public Void visit(OperatorExpr operatorExpr, Collection<VariableExpr> freeVars) throws AsterixException {
- for (Expression expr : operatorExpr.getExprList()) {
- expr.accept(this, freeVars);
- }
+ visit(operatorExpr.getExprList(), freeVars);
return null;
}
@@ -416,8 +411,18 @@
}
@Override
- public Void visit(IndependentSubquery independentSubquery, Collection<VariableExpr> arg) throws AsterixException {
- independentSubquery.getExpr().accept(this, arg);
+ public Void visit(IndependentSubquery independentSubquery, Collection<VariableExpr> freeVars)
+ throws AsterixException {
+ independentSubquery.getExpr().accept(this, freeVars);
+ return null;
+ }
+
+ @Override
+ public Void visit(CaseExpression caseExpr, Collection<VariableExpr> freeVars) throws AsterixException {
+ caseExpr.getConditionExpr().accept(this, freeVars);
+ visit(caseExpr.getWhenExprs(), freeVars);
+ visit(caseExpr.getThenExprs(), freeVars);
+ caseExpr.getElseExpr().accept(this, freeVars);
return null;
}
@@ -454,6 +459,12 @@
freeVars.addAll(conditionFreeVars);
}
+ private void visit(List<Expression> exprs, Collection<VariableExpr> arg) throws AsterixException {
+ for (Expression expr : exprs) {
+ expr.accept(this, arg);
+ }
+ }
+
/**
* Removes all binding variables defined in the select block for a free variable collection.
*
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
index 589381a..4413961 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
@@ -19,6 +19,7 @@
package org.apache.asterix.lang.sqlpp.visitor;
import java.io.PrintWriter;
+import java.util.List;
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.common.functions.FunctionSignature;
@@ -42,6 +43,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -250,8 +252,8 @@
@Override
public Void visit(CallExpr pf, Integer step) throws AsterixException {
FunctionSignature functionSignature = pf.getFunctionSignature();
- FunctionSignature normalizedFunctionSignature = FunctionMapUtil
- .normalizeBuiltinFunctionSignature(functionSignature, false);
+ FunctionSignature normalizedFunctionSignature =
+ FunctionMapUtil.normalizeBuiltinFunctionSignature(functionSignature, false);
if (AsterixBuiltinFunctions.isBuiltinCompilerFunction(normalizedFunctionSignature, true)) {
functionSignature = normalizedFunctionSignature;
}
@@ -299,4 +301,25 @@
return null;
}
+ @Override
+ public Void visit(CaseExpression caseExpr, Integer step) throws AsterixException {
+ out.print(skip(step) + "CASE");
+ caseExpr.getConditionExpr().accept(this, step + 2);
+ out.println();
+ List<Expression> whenExprs = caseExpr.getWhenExprs();
+ List<Expression> thenExprs = caseExpr.getThenExprs();
+ for (int index = 0; index < whenExprs.size(); ++index) {
+ out.print(skip(step) + "WHEN ");
+ whenExprs.get(index).accept(this, step + 2);
+ out.print(skip(step) + "THEN ");
+ thenExprs.get(index).accept(this, step + 2);
+ out.println();
+ }
+ out.print(skip(step) + "ELSE ");
+ caseExpr.getElseExpr().accept(this, step + 2);
+ out.println();
+ out.println(skip(step) + "END");
+ return null;
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
index d380cad..23181e4 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
@@ -33,6 +33,7 @@
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
+import org.apache.asterix.lang.common.util.VariableCloneAndSubstitutionUtil;
import org.apache.asterix.lang.common.visitor.CloneAndSubstituteVariablesVisitor;
import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
import org.apache.asterix.lang.sqlpp.clause.FromClause;
@@ -47,6 +48,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
@@ -377,4 +379,17 @@
return new Pair<>(newSubquery, p.second);
}
+ @Override
+ public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(CaseExpression caseExpr,
+ VariableSubstitutionEnvironment env) throws AsterixException {
+ Expression conditionExpr = (Expression) caseExpr.getConditionExpr().accept(this, env).first;
+ List<Expression> whenExprList =
+ VariableCloneAndSubstitutionUtil.visitAndCloneExprList(caseExpr.getWhenExprs(), env, this);
+ List<Expression> thenExprList =
+ VariableCloneAndSubstitutionUtil.visitAndCloneExprList(caseExpr.getThenExprs(), env, this);
+ Expression elseExpr = (Expression) caseExpr.getElseExpr().accept(this, env).first;
+ CaseExpression newCaseExpr = new CaseExpression(conditionExpr, whenExprList, thenExprList, elseExpr);
+ return new Pair<>(newCaseExpr, env);
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
index 2dca532..0363e20 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
@@ -41,6 +41,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -307,4 +308,25 @@
return null;
}
+ @Override
+ public Void visit(CaseExpression caseExpr, Integer step) throws AsterixException {
+ out.print(skip(step) + "case ");
+ caseExpr.getConditionExpr().accept(this, step + 2);
+ out.println();
+ List<Expression> whenExprs = caseExpr.getWhenExprs();
+ List<Expression> thenExprs = caseExpr.getThenExprs();
+ for (int index = 0; index < whenExprs.size(); ++index) {
+ out.print(skip(step) + "when ");
+ whenExprs.get(index).accept(this, step + 2);
+ out.print(" then ");
+ thenExprs.get(index).accept(this, step + 2);
+ out.println();
+ }
+ out.print(skip(step) + "else ");
+ caseExpr.getElseExpr().accept(this, step + 2);
+ out.println();
+ out.println(skip(step) + "end");
+ return null;
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java
index af160bf..d9b2698 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java
@@ -41,6 +41,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -269,4 +270,18 @@
return null;
}
+ @Override
+ public Expression visit(CaseExpression caseExpr, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newCaseExpr = env.findSubstitution(caseExpr, deepCopier);
+ if (newCaseExpr == caseExpr) {
+ caseExpr.setConditionExpr(caseExpr.getConditionExpr().accept(this, env));
+ caseExpr.setWhenExprs(rewriteExpressionList(caseExpr.getWhenExprs(), env));
+ caseExpr.setThenExprs(rewriteExpressionList(caseExpr.getThenExprs(), env));
+ caseExpr.setElseExpr(caseExpr.getElseExpr().accept(this, env));
+ return caseExpr;
+ } else {
+ return newCaseExpr.accept(this, env);
+ }
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppAstVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppAstVisitor.java
index e5bf513..c0947f3 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppAstVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppAstVisitor.java
@@ -32,6 +32,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
@@ -110,4 +111,9 @@
return null;
}
+ @Override
+ public R visit(CaseExpression caseExpr, T arg) throws AsterixException {
+ return null;
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
index 9fd5a6e..423eb40 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
@@ -58,6 +58,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -267,11 +268,7 @@
@Override
public Expression visit(ListConstructor lc, ILangExpression arg) throws AsterixException {
- List<Expression> newExprList = new ArrayList<>();
- for (Expression expr : lc.getExprList()) {
- newExprList.add(expr.accept(this, lc));
- }
- lc.setExprList(newExprList);
+ lc.setExprList(visit(lc.getExprList(), arg));
return lc;
}
@@ -286,11 +283,7 @@
@Override
public Expression visit(OperatorExpr operatorExpr, ILangExpression arg) throws AsterixException {
- List<Expression> newExprList = new ArrayList<>();
- for (Expression expr : operatorExpr.getExprList()) {
- newExprList.add(expr.accept(this, operatorExpr));
- }
- operatorExpr.setExprList(newExprList);
+ operatorExpr.setExprList(visit(operatorExpr.getExprList(), arg));
return operatorExpr;
}
@@ -353,4 +346,21 @@
return independentSubquery;
}
+ @Override
+ public Expression visit(CaseExpression caseExpr, ILangExpression arg) throws AsterixException {
+ caseExpr.setConditionExpr(caseExpr.getConditionExpr().accept(this, arg));
+ caseExpr.setWhenExprs(visit(caseExpr.getWhenExprs(), arg));
+ caseExpr.setThenExprs(visit(caseExpr.getThenExprs(), arg));
+ caseExpr.setElseExpr(caseExpr.getElseExpr().accept(this, arg));
+ return caseExpr;
+ }
+
+ private List<Expression> visit(List<Expression> exprs, ILangExpression arg) throws AsterixException {
+ List<Expression> newExprList = new ArrayList<>();
+ for (Expression expr : exprs) {
+ newExprList.add(expr.accept(this, arg));
+ }
+ return newExprList;
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/ISqlppVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/ISqlppVisitor.java
index 4e5e58d..2827e37 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/ISqlppVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/ISqlppVisitor.java
@@ -32,6 +32,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
@@ -64,4 +65,6 @@
R visit(HavingClause havingClause, T arg) throws AsterixException;
R visit(IndependentSubquery independentSubquery, T arg) throws AsterixException;
+
+ R visit(CaseExpression caseExpression, T arg) throws AsterixException;
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html
index 8d093d9..7b37ab4 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html
@@ -42,6 +42,7 @@
| <ELEMENT: "element">
| <ELSE: "else">
| <ENFORCED: "enforced">
+| <END: "end">
| <EVERY: "every">
| <EXCEPT: "except">
| <EXISTS: "exists">
@@ -674,7 +675,7 @@
<TR>
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod44">Expression</A></TD>
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod63">OperatorExpr</A> | <A HREF="#prod64">IfThenElse</A> | <A HREF="#prod65">QuantifiedExpression</A> )</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod63">OperatorExpr</A> | <A HREF="#prod64">CaseExpr</A> | <A HREF="#prod65">QuantifiedExpression</A> )</TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod63">OperatorExpr</A></TD>
@@ -797,9 +798,9 @@
<TD ALIGN=LEFT VALIGN=BASELINE>( <LEFTPAREN> <A HREF="#prod44">Expression</A> <RIGHTPAREN> | <A HREF="#prod88">Subquery</A> )</TD>
</TR>
<TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod64">IfThenElse</A></TD>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod64">CaseExpr</A></TD>
<TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE><IF> <LEFTPAREN> <A HREF="#prod44">Expression</A> <RIGHTPAREN> <THEN> <A HREF="#prod44">Expression</A> <ELSE> <A HREF="#prod44">Expression</A></TD>
+<TD ALIGN=LEFT VALIGN=BASELINE><CASE> ( <A HREF="#prod44">Expression</A> )? ( <WHEN> <A HREF="#prod44">Expression</A> <THEN> <A HREF="#prod44">Expression</A> )* ( <ELSE> <A HREF="#prod44">Expression</A> )? <END></TD>
</TR>
<TR>
<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod62">SelectExpression</A></TD>
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 99b875a..d496027 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -136,6 +136,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.optype.JoinType;
import org.apache.asterix.lang.sqlpp.optype.SetOpType;
@@ -1591,7 +1592,7 @@
(
LOOKAHEAD(2)
expr = OperatorExpr()
- | expr = IfThenElse()
+ | expr = CaseExpr()
| expr = QuantifiedExpression()
)
{
@@ -2212,22 +2213,34 @@
}
}
-Expression IfThenElse() throws ParseException:
+
+Expression CaseExpr() throws ParseException:
{
- Expression condExpr;
- Expression thenExpr;
- Expression elseExpr;
- IfExpr ifExpr = new IfExpr();
+ Expression conditionExpr = new LiteralExpr(TrueLiteral.INSTANCE);
+ List<Expression> whenExprs = new ArrayList<Expression>();
+ List<Expression> thenExprs = new ArrayList<Expression>();
+ Expression elseExpr = null;
+
+ Expression whenExpr = null;
+ Expression thenExpr = null;
}
{
- <IF> <LEFTPAREN> condExpr = Expression() <RIGHTPAREN> <THEN> thenExpr = Expression() <ELSE> elseExpr = Expression()
-
- {
- ifExpr.setCondExpr(condExpr);
- ifExpr.setThenExpr(thenExpr);
- ifExpr.setElseExpr(elseExpr);
- return ifExpr;
- }
+ <CASE> ( conditionExpr = Expression() )?
+ (
+ <WHEN> whenExpr = Expression()
+ {
+ whenExprs.add(whenExpr);
+ }
+ <THEN> thenExpr = Expression()
+ {
+ thenExprs.add(thenExpr);
+ }
+ )*
+ (<ELSE> elseExpr = Expression() )?
+ <END>
+ {
+ return new CaseExpression(conditionExpr, whenExprs, thenExprs, elseExpr);
+ }
}
SelectExpression SelectExpression(boolean subquery) throws ParseException: {
@@ -2821,6 +2834,7 @@
| <ELEMENT : "element">
| <ELSE : "else">
| <ENFORCED : "enforced">
+ | <END : "end">
| <EVERY : "every">
| <EXCEPT : "except">
| <EXISTS : "exists">
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
index e5950e3..e303d97 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -55,8 +55,7 @@
import org.apache.asterix.om.typecomputer.impl.AnyTypeComputer;
import org.apache.asterix.om.typecomputer.impl.BooleanFunctionTypeComputer;
import org.apache.asterix.om.typecomputer.impl.BooleanOnlyTypeComputer;
-import org.apache.asterix.om.typecomputer.impl.CastListResultTypeComputer;
-import org.apache.asterix.om.typecomputer.impl.CastRecordResultTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.CastTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ClosedRecordConstructorResultType;
import org.apache.asterix.om.typecomputer.impl.CollectionMemberResultType;
import org.apache.asterix.om.typecomputer.impl.CollectionToSequenceTypeComputer;
@@ -584,12 +583,10 @@
public static final FunctionIdentifier INJECT_FAILURE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"inject-failure", 2);
- public static final FunctionIdentifier CAST_RECORD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
- "cast-record", 1);
public static final FunctionIdentifier FLOW_RECORD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"flow-record", 1);
- public static final FunctionIdentifier CAST_LIST = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "cast-list",
- 1);
+ public static final FunctionIdentifier CAST_TYPE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "cast", 1);
public static final FunctionIdentifier CREATE_UUID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"create-uuid", 0);
@@ -942,8 +939,7 @@
addFunction(SWITCH_CASE, SwitchCaseComputer.INSTANCE, true);
addPrivateFunction(REG_EXP, ABooleanTypeComputer.INSTANCE, true);
addPrivateFunction(INJECT_FAILURE, InjectFailureTypeComputer.INSTANCE, true);
- addPrivateFunction(CAST_RECORD, CastRecordResultTypeComputer.INSTANCE, true);
- addPrivateFunction(CAST_LIST, CastListResultTypeComputer.INSTANCE, true);
+ addPrivateFunction(CAST_TYPE, CastTypeComputer.INSTANCE, true);
addFunction(TID, AInt64TypeComputer.INSTANCE, true);
addFunction(TIME_CONSTRUCTOR, ATimeTypeComputer.INSTANCE, true);
@@ -1416,4 +1412,4 @@
return similarityFunctions.contains(getAsterixFunctionInfo(fi));
}
-}
\ No newline at end of file
+}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastRecordResultTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastRecordResultTypeComputer.java
deleted file mode 100644
index e95571b..0000000
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastRecordResultTypeComputer.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.asterix.om.typecomputer.impl;
-
-import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
-import org.apache.asterix.om.typecomputer.base.TypeCastUtils;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
-import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
-
-public class CastRecordResultTypeComputer implements IResultTypeComputer {
-
- public static final CastRecordResultTypeComputer INSTANCE = new CastRecordResultTypeComputer();
-
- @Override
- public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
- IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
- ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) expression;
- return TypeCastUtils.getRequiredType(funcExpr);
- }
-}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastListResultTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastTypeComputer.java
similarity index 91%
rename from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastListResultTypeComputer.java
rename to asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastTypeComputer.java
index fc4242d..64f85cb 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastListResultTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastTypeComputer.java
@@ -33,9 +33,9 @@
*
* @author yingyib
*/
-public class CastListResultTypeComputer implements IResultTypeComputer {
+public class CastTypeComputer implements IResultTypeComputer {
- public static final CastListResultTypeComputer INSTANCE = new CastListResultTypeComputer();
+ public static final CastTypeComputer INSTANCE = new CastTypeComputer();
@Override
public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
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 167cb44..0eb60cb 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
@@ -48,19 +48,28 @@
IAType currentType = null;
boolean any = false;
- boolean missable = false;
- for (int i = 2; i < fce.getArguments().size(); i += 2) {
- IAType type = (IAType) env.getType(fce.getArguments().get(i).getValue());
- if (type.getTypeTag() == ATypeTag.UNION) {
- type = ((AUnionType) type).getActualType();
- missable = true;
+ boolean unknownable = false;
+ int argSize = fce.getArguments().size();
+ // Checks return types of different branches' return types.
+ // The last return expression is from the ELSE branch and it is optional.
+ for (int argIndex = 2; argIndex < argSize; argIndex += (argIndex + 2 == argSize) ? 1 : 2) {
+ IAType type = (IAType) env.getType(fce.getArguments().get(argIndex).getValue());
+ ATypeTag typeTag = type.getTypeTag();
+ if (typeTag == ATypeTag.NULL || typeTag == ATypeTag.MISSING) {
+ unknownable = true;
+ } else {
+ if (typeTag == ATypeTag.UNION) {
+ type = ((AUnionType) type).getActualType();
+ unknownable = true;
+ }
+ if (currentType != null && !type.equals(currentType)) {
+ any = true;
+ break;
+ }
+ currentType = type;
}
- if (currentType != null && !type.equals(currentType)) {
- any = true;
- break;
- }
- currentType = type;
}
- return any ? BuiltinType.ANY : missable ? AUnionType.createMissableType(currentType) : currentType;
+ currentType = currentType == null ? BuiltinType.ANULL : currentType;
+ return any ? BuiltinType.ANY : unknownable ? AUnionType.createUnknownableType(currentType) : currentType;
}
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/AbstractTypeCheckEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/AbstractTypeCheckEvaluator.java
index 800afd7..2866f7b 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/AbstractTypeCheckEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/AbstractTypeCheckEvaluator.java
@@ -23,6 +23,7 @@
import org.apache.asterix.dataflow.data.nontagged.serde.AObjectSerializerDeserializer;
import org.apache.asterix.om.base.ABoolean;
+import org.apache.asterix.om.types.ATypeTag;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
import org.apache.hyracks.api.exceptions.HyracksDataException;
@@ -33,6 +34,13 @@
public abstract class AbstractTypeCheckEvaluator implements IScalarEvaluator {
+ protected enum Value {
+ TRUE,
+ FALSE,
+ MISSING
+ }
+
+ private static final byte[] MISSING_BYTES = new byte[] { ATypeTag.SERIALIZED_MISSING_TYPE_TAG };
private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
private final DataOutput out = resultStorage.getDataOutput();
private final IPointable argPtr = new VoidPointable();
@@ -46,8 +54,12 @@
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
eval.evaluate(tuple, argPtr);
- boolean match = isMatch(argPtr.getByteArray()[argPtr.getStartOffset()]);
- ABoolean res = match ? ABoolean.TRUE : ABoolean.FALSE;
+ Value match = isMatch(argPtr.getByteArray()[argPtr.getStartOffset()]);
+ if (match == Value.MISSING) {
+ result.set(MISSING_BYTES, 0, MISSING_BYTES.length);
+ return;
+ }
+ ABoolean res = match == Value.TRUE ? ABoolean.TRUE : ABoolean.FALSE;
try {
resultStorage.reset();
aObjSerDer.serialize(res, out);
@@ -57,6 +69,6 @@
}
}
- protected abstract boolean isMatch(byte typeTag);
+ protected abstract Value isMatch(byte typeTag);
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastListDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastListDescriptor.java
deleted file mode 100644
index f776d1d..0000000
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastListDescriptor.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.runtime.evaluators.functions;
-
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
-import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.pointables.PointableAllocator;
-import org.apache.asterix.om.pointables.base.IVisitablePointable;
-import org.apache.asterix.om.pointables.cast.ACastVisitor;
-import org.apache.asterix.om.types.AbstractCollectionType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.common.utils.Triple;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
-import org.apache.hyracks.api.context.IHyracksTaskContext;
-import org.apache.hyracks.data.std.api.IPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-
-/**
- * The runtime function for casting a list(unordered list or ordered list)
- *
- * @author yingyib
- */
-public class CastListDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-
- public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
- @Override
- public IFunctionDescriptor createFunctionDescriptor() {
- return new CastListDescriptor();
- }
- };
-
- private static final long serialVersionUID = 1L;
- private AbstractCollectionType reqType;
- private AbstractCollectionType inputType;
-
- public void reset(AbstractCollectionType reqType, AbstractCollectionType inputType) {
- this.reqType = reqType;
- this.inputType = inputType;
- }
-
- @Override
- public FunctionIdentifier getIdentifier() {
- return AsterixBuiltinFunctions.CAST_LIST;
- }
-
- @Override
- public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
- final IScalarEvaluatorFactory recordEvalFactory = args[0];
-
- return new IScalarEvaluatorFactory() {
- private static final long serialVersionUID = 1L;
-
- @Override
- public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
- final IPointable recordPtr = new VoidPointable();
- final IScalarEvaluator recEvaluator = recordEvalFactory.createScalarEvaluator(ctx);
-
- return new IScalarEvaluator() {
- // pointable allocator
- private PointableAllocator allocator = new PointableAllocator();
- final IVisitablePointable recAccessor = allocator.allocateListValue(inputType);
- final IVisitablePointable resultAccessor = allocator.allocateListValue(reqType);
- final ACastVisitor castVisitor = new ACastVisitor();
- final Triple<IVisitablePointable, IAType, Boolean> arg = new Triple<IVisitablePointable, IAType, Boolean>(
- resultAccessor, reqType, Boolean.FALSE);
-
- @Override
- public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
- try {
- recEvaluator.evaluate(tuple, recordPtr);
- recAccessor.set(recordPtr);
- recAccessor.accept(castVisitor, arg);
- result.set(resultAccessor);
- } catch (Exception ioe) {
- throw new AlgebricksException(ioe);
- }
- }
- };
- }
- };
- }
-}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastRecordDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
deleted file mode 100644
index 81e132a..0000000
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.asterix.runtime.evaluators.functions;
-
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
-import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.pointables.PointableAllocator;
-import org.apache.asterix.om.pointables.base.IVisitablePointable;
-import org.apache.asterix.om.pointables.cast.ACastVisitor;
-import org.apache.asterix.om.types.ARecordType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.common.utils.Triple;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
-import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
-import org.apache.hyracks.api.context.IHyracksTaskContext;
-import org.apache.hyracks.data.std.api.IPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-
-public class CastRecordDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-
- private CastRecordDescriptor() {
- }
-
- public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
- @Override
- public IFunctionDescriptor createFunctionDescriptor() {
- return new CastRecordDescriptor();
- }
- };
-
- private static final long serialVersionUID = 1L;
- private ARecordType reqType;
- private ARecordType inputType;
-
- public void reset(ARecordType reqType, ARecordType inputType) {
- this.reqType = reqType;
- this.inputType = inputType;
- }
-
- @Override
- public FunctionIdentifier getIdentifier() {
- return AsterixBuiltinFunctions.CAST_RECORD;
- }
-
- @Override
- public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
- final IScalarEvaluatorFactory recordEvalFactory = args[0];
-
- return new IScalarEvaluatorFactory() {
- private static final long serialVersionUID = 1L;
-
- @Override
- public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
- final IPointable recordPtr = new VoidPointable();
- final IScalarEvaluator recEvaluator = recordEvalFactory.createScalarEvaluator(ctx);
-
- return new IScalarEvaluator() {
- // pointable allocator
- private PointableAllocator allocator = new PointableAllocator();
- final IVisitablePointable recAccessor = allocator.allocateRecordValue(inputType);
- final IVisitablePointable resultAccessor = allocator.allocateRecordValue(reqType);
- final ACastVisitor castVisitor = new ACastVisitor();
- final Triple<IVisitablePointable, IAType, Boolean> arg = new Triple<>(resultAccessor, reqType,
- Boolean.FALSE);
-
- @Override
- public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
- try {
- recEvaluator.evaluate(tuple, recordPtr);
- recAccessor.set(recordPtr);
- recAccessor.accept(castVisitor, arg);
- result.set(resultAccessor);
- } catch (Exception ioe) {
- throw new AlgebricksException(ioe);
- }
- }
- };
- }
- };
- }
-}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeDescriptor.java
new file mode 100644
index 0000000..5c754cf
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeDescriptor.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.runtime.evaluators.functions;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.pointables.PointableAllocator;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.pointables.base.IVisitablePointable;
+import org.apache.asterix.om.pointables.cast.ACastVisitor;
+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.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.common.utils.Triple;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+/**
+ * This runtime function casts an input ADM instance of a certain type into the form
+ * that confirms a required type.
+ */
+public class CastTypeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new CastTypeDescriptor();
+ }
+ };
+
+ private static final long serialVersionUID = 1L;
+ private IAType reqType;
+ private IAType inputType;
+
+ private CastTypeDescriptor() {
+ }
+
+ public void reset(IAType reqType, IAType inputType) {
+ // If reqType or inputType is null, or they are the same, it indicates there is a bug in the compiler.
+ if (reqType == null || inputType == null || reqType.equals(inputType)) {
+ throw new IllegalStateException(
+ "Invalid types for casting, required type " + reqType + ", input type " + inputType);
+ }
+ this.reqType = reqType;
+ this.inputType = inputType;
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return AsterixBuiltinFunctions.CAST_TYPE;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ final IScalarEvaluatorFactory recordEvalFactory = args[0];
+
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+ return new CastTypeEvaluator(reqType, inputType, recordEvalFactory.createScalarEvaluator(ctx));
+ }
+ };
+ }
+}
+
+class CastTypeEvaluator implements IScalarEvaluator {
+
+ private final IScalarEvaluator argEvaluator;
+ private final IPointable argPointable = new VoidPointable();
+
+ private final PointableAllocator allocator = new PointableAllocator();
+ private final IVisitablePointable inputPointable;
+ private final IVisitablePointable resultPointable;
+
+ private final ACastVisitor castVisitor = new ACastVisitor();
+ private final Triple<IVisitablePointable, IAType, Boolean> arg;
+
+ public CastTypeEvaluator(IAType reqType, IAType inputType, IScalarEvaluator argEvaluator)
+ throws AlgebricksException {
+ try {
+ this.argEvaluator = argEvaluator;
+ this.inputPointable = allocateResultPointable(inputType, reqType);
+ this.resultPointable = allocateResultPointable(reqType, inputType);
+ this.arg = new Triple<>(resultPointable, reqType, Boolean.FALSE);
+ } catch (AsterixException e) {
+ throw new AlgebricksException(e);
+ }
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
+ try {
+ argEvaluator.evaluate(tuple, argPointable);
+ inputPointable.set(argPointable);
+ inputPointable.accept(castVisitor, arg);
+ result.set(resultPointable);
+ } catch (Exception ioe) {
+ throw new AlgebricksException(ioe);
+ }
+ }
+
+ // Allocates the result pointable.
+ private final IVisitablePointable allocateResultPointable(IAType typeForPointable, IAType typeForOtherSide)
+ throws AsterixException {
+ if (!typeForPointable.equals(BuiltinType.ANY)) {
+ return allocator.allocateFieldValue(typeForPointable);
+ }
+ return allocatePointableForAny(typeForOtherSide);
+ }
+
+ // Allocates an input or result pointable if the input or required type is ANY.
+ private IVisitablePointable allocatePointableForAny(IAType type) {
+ ATypeTag tag = type.getTypeTag();
+ switch (tag) {
+ case RECORD:
+ return allocator.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+ case ORDEREDLIST:
+ return allocator.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
+ case UNORDEREDLIST:
+ return allocator.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE);
+ default:
+ return allocator.allocateFieldValue(null);
+ }
+ }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsMissingDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsMissingDescriptor.java
index 45c3f6d..a3bdb30 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsMissingDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsMissingDescriptor.java
@@ -51,8 +51,8 @@
return new AbstractTypeCheckEvaluator(eval) {
@Override
- protected boolean isMatch(byte typeTag) {
- return typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG;
+ protected Value isMatch(byte typeTag) {
+ return typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG ? Value.TRUE : Value.FALSE;
}
};
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsNullDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsNullDescriptor.java
index 3ae3bd9..33db8f3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsNullDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsNullDescriptor.java
@@ -51,8 +51,11 @@
return new AbstractTypeCheckEvaluator(eval) {
@Override
- protected boolean isMatch(byte typeTag) {
- return typeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG;
+ protected Value isMatch(byte typeTag) {
+ if (typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
+ return Value.MISSING;
+ }
+ return typeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG ? Value.TRUE : Value.FALSE;
}
};
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsUnknownDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsUnknownDescriptor.java
index be04c86..ef5f42c 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsUnknownDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsUnknownDescriptor.java
@@ -51,9 +51,9 @@
return new AbstractTypeCheckEvaluator(eval) {
@Override
- protected boolean isMatch(byte typeTag) {
- return typeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG
- || typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG;
+ protected Value isMatch(byte typeTag) {
+ return (typeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG
+ || typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) ? Value.TRUE : Value.FALSE;
}
};
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java
index df0b973..9e14bff 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java
@@ -93,13 +93,14 @@
}
private boolean equals(IPointable out1, IPointable out2) {
- if (out1.getStartOffset() != out2.getStartOffset() || out1.getLength() != out2.getLength()) {
+ if (out1.getLength() != out2.getLength()) {
return false;
}
byte[] data1 = out1.getByteArray();
byte[] data2 = out2.getByteArray();
- for (int i = out1.getStartOffset(); i < out1.getLength(); i++) {
- if (data1[i] != data2[i]) {
+ for (int i = out1.getStartOffset(), j = out2.getStartOffset(), k = 0; k < out1
+ .getLength(); ++i, ++j, ++k) {
+ if (data1[i] != data2[j]) {
return false;
}
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
index 64735ff..8737360 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -60,15 +60,12 @@
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.AUnorderedListType;
-import org.apache.asterix.om.types.AbstractCollectionType;
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.runtime.aggregates.collections.ListifyAggregateDescriptor;
import org.apache.asterix.runtime.evaluators.common.CreateMBREvalFactory;
import org.apache.asterix.runtime.evaluators.common.FunctionManagerImpl;
import org.apache.asterix.runtime.evaluators.constructors.ClosedRecordConstructorDescriptor;
import org.apache.asterix.runtime.evaluators.constructors.OpenRecordConstructorDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.CastListDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.CastRecordDescriptor;
import org.apache.asterix.runtime.evaluators.functions.OrderedListConstructorDescriptor;
import org.apache.asterix.runtime.evaluators.functions.UnorderedListConstructorDescriptor;
import org.apache.asterix.runtime.evaluators.functions.records.FieldAccessByIndexEvalFactory;
@@ -210,8 +207,8 @@
} catch (HyracksDataException e) {
throw new AlgebricksException(e);
}
- IScalarEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(
- Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
+ IScalarEvaluatorFactory fldIndexEvalFactory =
+ new ConstantEvalFactory(Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory, fldIndexEvalFactory, recType);
return evalFactory;
@@ -256,8 +253,8 @@
int dimension, List<String> filterFieldName) throws AlgebricksException {
IScalarEvaluatorFactory evalFactory = getFieldAccessEvaluatorFactory(recType, fldName, recordColumn);
int numOfFields = dimension * 2;
- IScalarEvaluatorFactory[] evalFactories = new IScalarEvaluatorFactory[numOfFields
- + (filterFieldName == null ? 0 : 1)];
+ IScalarEvaluatorFactory[] evalFactories =
+ new IScalarEvaluatorFactory[numOfFields + (filterFieldName == null ? 0 : 1)];
ArrayBackedValueStorage abvs1 = new ArrayBackedValueStorage();
DataOutput dos1 = abvs1.getDataOutput();
@@ -267,8 +264,8 @@
} catch (HyracksDataException e) {
throw new AlgebricksException(e);
}
- IScalarEvaluatorFactory dimensionEvalFactory = new ConstantEvalFactory(
- Arrays.copyOf(abvs1.getByteArray(), abvs1.getLength()));
+ IScalarEvaluatorFactory dimensionEvalFactory =
+ new ConstantEvalFactory(Arrays.copyOf(abvs1.getByteArray(), abvs1.getLength()));
for (int i = 0; i < numOfFields; i++) {
ArrayBackedValueStorage abvs2 = new ArrayBackedValueStorage();
@@ -279,8 +276,8 @@
} catch (HyracksDataException e) {
throw new AlgebricksException(e);
}
- IScalarEvaluatorFactory coordinateEvalFactory = new ConstantEvalFactory(
- Arrays.copyOf(abvs2.getByteArray(), abvs2.getLength()));
+ IScalarEvaluatorFactory coordinateEvalFactory =
+ new ConstantEvalFactory(Arrays.copyOf(abvs2.getByteArray(), abvs2.getLength()));
evalFactories[i] = new CreateMBREvalFactory(evalFactory, dimensionEvalFactory, coordinateEvalFactory);
}
@@ -299,8 +296,8 @@
if (fldName.size() > 1) {
for (int i = 0; i < n; i++) {
if (names[i].equals(fldName.get(0))) {
- IScalarEvaluatorFactory recordEvalFactory = new ColumnAccessEvalFactory(
- GlobalConfig.DEFAULT_INPUT_DATA_COLUMN);
+ IScalarEvaluatorFactory recordEvalFactory =
+ new ColumnAccessEvalFactory(GlobalConfig.DEFAULT_INPUT_DATA_COLUMN);
ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
DataOutput dos = abvs.getDataOutput();
try {
@@ -310,10 +307,10 @@
} catch (HyracksDataException e) {
throw new AlgebricksException(e);
}
- IScalarEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(
- Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
- IScalarEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory,
- fldIndexEvalFactory, recType);
+ IScalarEvaluatorFactory fldIndexEvalFactory =
+ new ConstantEvalFactory(Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
+ IScalarEvaluatorFactory evalFactory =
+ new FieldAccessByIndexEvalFactory(recordEvalFactory, fldIndexEvalFactory, recType);
IFunctionInfo finfoAccess = AsterixBuiltinFunctions
.getAsterixFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX);
@@ -326,8 +323,8 @@
}
}
} else {
- IScalarEvaluatorFactory recordEvalFactory = new ColumnAccessEvalFactory(
- GlobalConfig.DEFAULT_INPUT_DATA_COLUMN);
+ IScalarEvaluatorFactory recordEvalFactory =
+ new ColumnAccessEvalFactory(GlobalConfig.DEFAULT_INPUT_DATA_COLUMN);
ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
DataOutput dos = abvs.getDataOutput();
AOrderedList as = new AOrderedList(fldName);
@@ -337,8 +334,8 @@
throw new AlgebricksException(e);
}
IScalarEvaluatorFactory evalFactory = new FieldAccessNestedEvalFactory(recordEvalFactory, recType, fldName);
- IFunctionInfo finfoAccess = AsterixBuiltinFunctions
- .getAsterixFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_NESTED);
+ IFunctionInfo finfoAccess =
+ AsterixBuiltinFunctions.getAsterixFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_NESTED);
ScalarFunctionCallExpression partitionFun = new ScalarFunctionCallExpression(finfoAccess,
new MutableObject<ILogicalExpression>(new VariableReferenceExpression(METADATA_DUMMY_VAR)),
@@ -445,31 +442,15 @@
+ " org.apache.asterix.om.types.IAType)", outType, type0, type1);
}
});
-
- functionTypeInferers.put(AsterixBuiltinFunctions.CAST_RECORD, new FunctionTypeInferer() {
+ functionTypeInferers.put(AsterixBuiltinFunctions.CAST_TYPE, new FunctionTypeInferer() {
@Override
public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context)
throws AlgebricksException {
AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
- ARecordType rt = (ARecordType) TypeCastUtils.getRequiredType(funcExpr);
+ IAType rt = TypeCastUtils.getRequiredType(funcExpr);
IAType it = (IAType) context.getType(funcExpr.getArguments().get(0).getValue());
- if (it.getTypeTag().equals(ATypeTag.ANY)) {
- it = DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
- }
- ((CastRecordDescriptor) fd).reset(rt, (ARecordType) it);
- }
- });
- functionTypeInferers.put(AsterixBuiltinFunctions.CAST_LIST, new FunctionTypeInferer() {
- @Override
- public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context)
- throws AlgebricksException {
- AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
- AbstractCollectionType rt = (AbstractCollectionType) TypeCastUtils.getRequiredType(funcExpr);
- IAType it = (IAType) context.getType(funcExpr.getArguments().get(0).getValue());
- if (it.getTypeTag().equals(ATypeTag.ANY)) {
- it = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
- }
- ((CastListDescriptor) fd).reset(rt, (AbstractCollectionType) it);
+ PA.invokeMethod(fd, "reset(org.apache.asterix.om.types.IAType, org.apache.asterix.om.types.IAType)", rt,
+ it);
}
});
functionTypeInferers.put(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR, new FunctionTypeInferer() {
@@ -488,8 +469,9 @@
Mutable<ILogicalExpression> argRef = expr.getArguments().get(2 * i);
ILogicalExpression arg = argRef.getValue();
if (arg.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
- String fn = ((AString) ((AsterixConstantValue) ((ConstantExpression) arg).getValue())
- .getObject()).getStringValue();
+ String fn =
+ ((AString) ((AsterixConstantValue) ((ConstantExpression) arg).getValue()).getObject())
+ .getStringValue();
open[i] = true;
for (String s : recType.getFieldNames()) {
if (s.equals(fn)) {