Implementation of Union
Change-Id: I9049c89f7e3cd84cab1b4080af049f6042be9fb1
Reviewed-on: http://fulliautomatix.ics.uci.edu:8443/236
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ildar Absalyamov <ildar.absalyamov@gmail.com>
Reviewed-by: Preston Carman <ecarm002@ucr.edu>
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
index 74eca1f..ebc98fe 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
@@ -42,6 +42,7 @@
import edu.uci.ics.asterix.optimizer.rules.IntroduceRapidFrameFlushProjectAssignRule;
import edu.uci.ics.asterix.optimizer.rules.IntroduceSecondaryIndexInsertDeleteRule;
import edu.uci.ics.asterix.optimizer.rules.IntroduceStaticTypeCastForInsertRule;
+import edu.uci.ics.asterix.optimizer.rules.IntroduceUnionRule;
import edu.uci.ics.asterix.optimizer.rules.IntroduceUnnestForCollectionToSequenceRule;
import edu.uci.ics.asterix.optimizer.rules.LoadRecordFieldsRule;
import edu.uci.ics.asterix.optimizer.rules.NestGroupByRule;
@@ -104,6 +105,7 @@
import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushSelectIntoJoinRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushSubplanIntoGroupByRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushSubplanWithAggregateDownThroughProductRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushUnnestDownThroughUnionRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.ReinferAllTypesRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.RemoveRedundantGroupByDecorVars;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.RemoveRedundantVariablesRule;
@@ -228,6 +230,11 @@
consolidation.add(new RemoveUnusedAssignAndAggregateRule());
consolidation.add(new RemoveRedundantGroupByDecorVars());
consolidation.add(new NestedSubplanToJoinRule());
+ //unionRule => PushUnnestDownUnion => RemoveRedundantListifyRule cause these rules are correlated
+ consolidation.add(new IntroduceUnionRule());
+ consolidation.add(new PushUnnestDownThroughUnionRule());
+ consolidation.add(new RemoveRedundantListifyRule());
+
return consolidation;
}
@@ -310,5 +317,4 @@
prepareForJobGenRewrites.add(new SweepIllegalNonfunctionalFunctions());
return prepareForJobGenRewrites;
}
-
}
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceUnionRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceUnionRule.java
new file mode 100644
index 0000000..050a2cd
--- /dev/null
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/IntroduceUnionRule.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.asterix.optimizer.rules;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
+import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
+import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
+
+/**
+ * @author kereno, ecarm002, ildar.absalyamov
+ * Generates a union operator and puts it instead of "assign <- [function-call: asterix:union]"
+ * Before rule:
+ * ============
+ * assign [var] <- [asterix:union(left_branch, right_branch)]
+ * join (TRUE)
+ * left_branch
+ * right_branch
+ * After rule:
+ * ============
+ * union (left_branch, right_branch, result_var)
+ * left_branch
+ * right_branch
+ */
+public class IntroduceUnionRule implements IAlgebraicRewriteRule {
+
+ @Override
+ public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
+ return false;
+ }
+
+ @Override
+ public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
+ throws AlgebricksException {
+
+ if (!opRef.getValue().getOperatorTag().equals(LogicalOperatorTag.ASSIGN)) {
+ return false;
+ }
+
+ AssignOperator assignUnion = (AssignOperator) opRef.getValue();
+
+ if (assignUnion.getExpressions().get(0).getValue().getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL)
+ return false;
+
+ AbstractFunctionCallExpression u = (AbstractFunctionCallExpression) assignUnion.getExpressions().get(0)
+ .getValue();
+ if (!AsterixBuiltinFunctions.UNION.equals(u.getFunctionIdentifier())) {
+ return false;
+ }
+
+ //Retrieving the logical variables for the union from the two aggregates which are inputs to the join
+ Mutable<ILogicalOperator> join = assignUnion.getInputs().get(0);
+
+ LogicalOperatorTag tag1 = join.getValue().getOperatorTag();
+ if (tag1 != LogicalOperatorTag.INNERJOIN && tag1 != LogicalOperatorTag.LEFTOUTERJOIN) {
+ return false;
+ }
+ AbstractBinaryJoinOperator join1 = (AbstractBinaryJoinOperator) join.getValue();
+ ILogicalExpression cond1 = join1.getCondition().getValue();
+ // don't try to push a product down
+ if (!OperatorPropertiesUtil.isAlwaysTrueCond(cond1)) {
+ return false;
+ }
+
+ List<Mutable<ILogicalOperator>> joinInputs = join.getValue().getInputs();
+
+ Mutable<ILogicalOperator> left_branch = joinInputs.get(0);
+ Mutable<ILogicalOperator> right_branch = joinInputs.get(1);
+
+ List<LogicalVariable> input1Var = new ArrayList<LogicalVariable>();
+ VariableUtilities.getProducedVariables(left_branch.getValue(), input1Var);
+
+ List<LogicalVariable> input2Var = new ArrayList<LogicalVariable>();
+ VariableUtilities.getProducedVariables(right_branch.getValue(), input2Var);
+
+ List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap = new ArrayList<Triple<LogicalVariable, LogicalVariable, LogicalVariable>>(
+ 1);
+ Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple = new Triple<LogicalVariable, LogicalVariable, LogicalVariable>(
+ input1Var.get(0), input2Var.get(0), assignUnion.getVariables().get(0));
+ varMap.add(triple);
+ UnionAllOperator unionOp = new UnionAllOperator(varMap);
+
+ unionOp.getInputs().add(left_branch);
+ unionOp.getInputs().add(right_branch);
+
+ context.computeAndSetTypeEnvironmentForOperator(unionOp);
+
+ opRef.setValue(unionOp);
+
+ return true;
+
+ }
+}
\ No newline at end of file
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
index 7a6078f..d1268e5 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlExpressionToPlanTranslator.java
@@ -120,7 +120,6 @@
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
import edu.uci.ics.hyracks.algebricks.common.exceptions.NotImplementedException;
import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
-import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.Counter;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
@@ -159,7 +158,6 @@
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SinkOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
-import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
import edu.uci.ics.hyracks.algebricks.core.algebra.properties.LocalOrderProperty;
@@ -266,10 +264,8 @@
additionalFilteringVars = new ArrayList<LogicalVariable>();
additionalFilteringAssignExpressions = new ArrayList<Mutable<ILogicalExpression>>();
additionalFilteringExpressions = new ArrayList<Mutable<ILogicalExpression>>();
-
prepareVarAndExpression(additionalFilteringField, payloadVar, additionalFilteringVars,
additionalFilteringAssignExpressions, additionalFilteringExpressions);
-
additionalFilteringAssign = new AssignOperator(additionalFilteringVars,
additionalFilteringAssignExpressions);
}
@@ -1110,54 +1106,22 @@
@Override
public Pair<ILogicalOperator, LogicalVariable> visitUnionExpr(UnionExpr unionExpr,
Mutable<ILogicalOperator> tupSource) throws AsterixException {
+ //Translate the AQL union into an assign [var] <- [function-call: asterix:union, Args:[..]]
+ //The rule "IntroduceUnionRule" will translates this assign operator into the UnionAll operator.
Mutable<ILogicalOperator> ts = tupSource;
- ILogicalOperator lastOp = null;
- LogicalVariable lastVar = null;
- boolean first = true;
+ LogicalVariable assignedVar = context.newVar();
+ List<Mutable<ILogicalExpression>> inputVars = new ArrayList<Mutable<ILogicalExpression>>();
for (Expression e : unionExpr.getExprs()) {
- if (first) {
- first = false;
- } else {
- ts = new MutableObject<ILogicalOperator>(new EmptyTupleSourceOperator());
- }
- Pair<ILogicalOperator, LogicalVariable> p1 = e.accept(this, ts);
- if (lastOp == null) {
- lastOp = p1.first;
- lastVar = p1.second;
- } else {
- LogicalVariable unnestVar1 = context.newVar();
- UnnestOperator unnest1 = new UnnestOperator(unnestVar1, new MutableObject<ILogicalExpression>(
- makeUnnestExpression(new VariableReferenceExpression(lastVar))));
- unnest1.getInputs().add(new MutableObject<ILogicalOperator>(lastOp));
- LogicalVariable unnestVar2 = context.newVar();
- UnnestOperator unnest2 = new UnnestOperator(unnestVar2, new MutableObject<ILogicalExpression>(
- makeUnnestExpression(new VariableReferenceExpression(p1.second))));
- unnest2.getInputs().add(new MutableObject<ILogicalOperator>(p1.first));
- List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap = new ArrayList<Triple<LogicalVariable, LogicalVariable, LogicalVariable>>(
- 1);
- LogicalVariable resultVar = context.newVar();
- Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple = new Triple<LogicalVariable, LogicalVariable, LogicalVariable>(
- unnestVar1, unnestVar2, resultVar);
- varMap.add(triple);
- UnionAllOperator unionOp = new UnionAllOperator(varMap);
- unionOp.getInputs().add(new MutableObject<ILogicalOperator>(unnest1));
- unionOp.getInputs().add(new MutableObject<ILogicalOperator>(unnest2));
- lastVar = resultVar;
- lastOp = unionOp;
- }
+ Pair<ILogicalOperator, LogicalVariable> op_var = e.accept(this, ts);
+ ts = new MutableObject<ILogicalOperator>(op_var.first);
+ VariableReferenceExpression var = new VariableReferenceExpression(op_var.second);
+ inputVars.add(new MutableObject<ILogicalExpression>(var));
}
- LogicalVariable aggVar = context.newVar();
- ArrayList<LogicalVariable> aggregVars = new ArrayList<LogicalVariable>(1);
- aggregVars.add(aggVar);
- List<Mutable<ILogicalExpression>> afcExprs = new ArrayList<Mutable<ILogicalExpression>>(1);
- afcExprs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(lastVar)));
- AggregateFunctionCallExpression afc = AsterixBuiltinFunctions.makeAggregateFunctionExpression(
- AsterixBuiltinFunctions.LISTIFY, afcExprs);
- ArrayList<Mutable<ILogicalExpression>> aggregExprs = new ArrayList<Mutable<ILogicalExpression>>(1);
- aggregExprs.add(new MutableObject<ILogicalExpression>(afc));
- AggregateOperator agg = new AggregateOperator(aggregVars, aggregExprs);
- agg.getInputs().add(new MutableObject<ILogicalOperator>(lastOp));
- return new Pair<ILogicalOperator, LogicalVariable>(agg, aggVar);
+ AbstractFunctionCallExpression union = new ScalarFunctionCallExpression(
+ FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.UNION), inputVars);
+ AssignOperator a = new AssignOperator(assignedVar, new MutableObject<ILogicalExpression>(union));
+ a.getInputs().add(ts);
+ return new Pair<ILogicalOperator, LogicalVariable>(a, assignedVar);
}
private AbstractFunctionCallExpression createComparisonExpression(OperatorType t) {
@@ -1371,7 +1335,7 @@
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.INDEX_ACCESSOR_EXPRESSION || k == Kind.UNARY_EXPRESSION || k == Kind.UNION_EXPRESSION;
}
private <T> ArrayList<T> mkSingletonArrayList(T item) {
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlPlusExpressionToPlanTranslator.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlPlusExpressionToPlanTranslator.java
index 1ac27a1..e21eb9b 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlPlusExpressionToPlanTranslator.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/translator/AqlPlusExpressionToPlanTranslator.java
@@ -27,9 +27,8 @@
import edu.uci.ics.asterix.aql.base.Expression;
import edu.uci.ics.asterix.aql.base.Expression.Kind;
import edu.uci.ics.asterix.aql.expression.CallExpr;
-import edu.uci.ics.asterix.aql.expression.ConnectFeedStatement;
-import edu.uci.ics.asterix.aql.expression.DisconnectFeedStatement;
import edu.uci.ics.asterix.aql.expression.CompactStatement;
+import edu.uci.ics.asterix.aql.expression.ConnectFeedStatement;
import edu.uci.ics.asterix.aql.expression.CreateDataverseStatement;
import edu.uci.ics.asterix.aql.expression.CreateFeedStatement;
import edu.uci.ics.asterix.aql.expression.CreateFunctionStatement;
@@ -38,6 +37,7 @@
import edu.uci.ics.asterix.aql.expression.DataverseDecl;
import edu.uci.ics.asterix.aql.expression.DataverseDropStatement;
import edu.uci.ics.asterix.aql.expression.DeleteStatement;
+import edu.uci.ics.asterix.aql.expression.DisconnectFeedStatement;
import edu.uci.ics.asterix.aql.expression.DistinctClause;
import edu.uci.ics.asterix.aql.expression.DropStatement;
import edu.uci.ics.asterix.aql.expression.FLWOGRExpression;
@@ -102,7 +102,6 @@
import edu.uci.ics.asterix.metadata.declared.FileSplitSinkId;
import edu.uci.ics.asterix.metadata.entities.Dataset;
import edu.uci.ics.asterix.metadata.utils.DatasetUtils;
-import edu.uci.ics.asterix.om.base.AInt32;
import edu.uci.ics.asterix.om.base.AString;
import edu.uci.ics.asterix.om.constants.AsterixConstantValue;
import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
@@ -428,11 +427,11 @@
FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.ANY_COLLECTION_MEMBER));
f.getArguments().add(new MutableObject<ILogicalExpression>(p.first));
} else {
- Pair<ILogicalExpression, Mutable<ILogicalOperator>> indexPair = aqlExprToAlgExpression(ia.getIndexExpr(), tupSource);
+ Pair<ILogicalExpression, Mutable<ILogicalOperator>> indexPair = aqlExprToAlgExpression(ia.getIndexExpr(),
+ tupSource);
f = new ScalarFunctionCallExpression(FunctionUtils.getFunctionInfo(AsterixBuiltinFunctions.GET_ITEM));
f.getArguments().add(new MutableObject<ILogicalExpression>(p.first));
- f.getArguments().add(
- new MutableObject<ILogicalExpression>(indexPair.first));
+ f.getArguments().add(new MutableObject<ILogicalExpression>(indexPair.first));
}
AssignOperator a = new AssignOperator(v, new MutableObject<ILogicalExpression>(f));
a.getInputs().add(p.second);
diff --git a/asterix-app/src/test/resources/runtimets/queries/union/union/union.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/union/union/union.1.ddl.aql
new file mode 100644
index 0000000..96796f4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/union/union/union.1.ddl.aql
@@ -0,0 +1,17 @@
+drop dataverse TinySocial if exists;
+create dataverse TinySocial;
+use dataverse TinySocial;
+
+create type FacebookUserType as open {
+ id: int
+}
+
+create type FacebookMessageType as open {
+ message-id: int
+}
+
+create dataset FacebookUsers(FacebookUserType)
+primary key id;
+
+create dataset FacebookMessages(FacebookMessageType)
+primary key message-id;
diff --git a/asterix-app/src/test/resources/runtimets/queries/union/union/union.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/union/union/union.2.update.aql
new file mode 100644
index 0000000..be7b8e7
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/union/union/union.2.update.aql
@@ -0,0 +1,8 @@
+use dataverse TinySocial;
+
+load dataset FacebookUsers using localfs
+(("path"="nc1://data/tinysocial/fbu.adm"),("format"="adm"));
+
+load dataset FacebookMessages using localfs
+(("path"="nc1://data/tinysocial/fbm.adm"),("format"="adm"));
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/union/union/union.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/union/union/union.3.query.aql
new file mode 100644
index 0000000..0b92416
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/union/union/union.3.query.aql
@@ -0,0 +1,6 @@
+use dataverse TinySocial;
+
+let $t1 := for $t in dataset FacebookUsers return $t.id
+let $t2 := for $s in dataset FacebookMessages return $s.message-id
+let $c := $t1 union $t2
+for $res in $c distinct by $res return $res
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/union/union/union.1.adm b/asterix-app/src/test/resources/runtimets/results/union/union/union.1.adm
new file mode 100644
index 0000000..50e9210
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/union/union/union.1.adm
@@ -0,0 +1,16 @@
+[ 6
+, 11
+, 12
+, 14
+, 1
+, 2
+, 4
+, 13
+, 15
+, 8
+, 9
+, 10
+, 3
+, 5
+, 7
+ ]
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 4820ecb..214056f 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -59,6 +59,13 @@
</compilation-unit>
</test-case>
</test-group>
+ <test-group name="union">
+ <test-case FilePath="union">
+ <compilation-unit name="union">
+ <output-dir compare="Text">union</output-dir>
+ </compilation-unit>
+ </test-case>
+ </test-group>
<test-case FilePath="flwor">
<compilation-unit name="let33">
<output-dir compare="Text">let33</output-dir>
@@ -2769,16 +2776,17 @@
<output-dir compare="Text">scan-collection_01</output-dir>
</compilation-unit>
</test-case>
- <test-case FilePath="list">
- <compilation-unit name="union_01">
- <output-dir compare="Text">union_01</output-dir>
- </compilation-unit>
+<!-- <test-case FilePath="list">
+ <compilation-unit name="union_01">
+ <output-dir compare="Text">union_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="list">
+ <compilation-unit name="union_02">
+ <output-dir compare="Text">union_02</output-dir>
+ </compilation-unit>
</test-case>
- <test-case FilePath="list">
- <compilation-unit name="union_02">
- <output-dir compare="Text">union_02</output-dir>
- </compilation-unit>
- </test-case>
+ -->
<test-case FilePath="list">
<compilation-unit name="unordered-list-constructor_01">
<output-dir compare="Text">unordered-list-constructor_01</output-dir>
diff --git a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
index 8bb78ac..99afe9a 100644
--- a/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
+++ b/asterix-common/src/test/java/edu/uci/ics/asterix/test/aql/TestsUtils.java
@@ -385,7 +385,6 @@
LOGGER.info("Starting [TEST]: " + testCaseCtx.getTestCase().getFilePath() + "/" + cUnit.getName() + " ... ");
testFileCtxs = testCaseCtx.getTestFiles(cUnit);
expectedResultFileCtxs = testCaseCtx.getExpectedResultFiles(cUnit);
-
for (TestFileContext ctx : testFileCtxs) {
testFile = ctx.getFile();
statement = TestsUtils.readTestFile(testFile);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
index 8f6c721..6b7b871 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -458,11 +458,10 @@
"null", 1);
public final static FunctionIdentifier STRING_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"string", 1);
- public final static FunctionIdentifier BINARY_HEX_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
- "hex", 1);
+ public final static FunctionIdentifier BINARY_HEX_CONSTRUCTOR = new FunctionIdentifier(
+ FunctionConstants.ASTERIX_NS, "hex", 1);
public final static FunctionIdentifier BINARY_BASE64_CONSTRUCTOR = new FunctionIdentifier(
- FunctionConstants.ASTERIX_NS,
- "base64", 1);
+ FunctionConstants.ASTERIX_NS, "base64", 1);
public final static FunctionIdentifier INT8_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"int8", 1);
public final static FunctionIdentifier INT16_CONSTRUCTOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -679,6 +678,8 @@
public final static FunctionIdentifier GET_POINTS_LINE_RECTANGLE_POLYGON_ACCESSOR = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "get-points", 1);
+ public final static FunctionIdentifier UNION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "union", 2);
+
public static final FunctionIdentifier EQ = AlgebricksBuiltinFunctions.EQ;
public static final FunctionIdentifier LE = AlgebricksBuiltinFunctions.LE;
public static final FunctionIdentifier GE = AlgebricksBuiltinFunctions.GE;
@@ -693,7 +694,6 @@
public static final FunctionIdentifier IS_SYSTEM_NULL = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"is-system-null", 1);
- ;
public static final FunctionIdentifier NOT_NULL = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "not-null",
1);
public static final FunctionIdentifier COLLECTION_TO_SEQUENCE = new FunctionIdentifier(
@@ -919,6 +919,9 @@
addFunction(STRING_CONSTRUCTOR, OptionalAStringTypeComputer.INSTANCE, true);
addFunction(BINARY_HEX_CONSTRUCTOR, OptionalABinaryTypeComputer.INSTANCE, true);
addFunction(BINARY_BASE64_CONSTRUCTOR, OptionalABinaryTypeComputer.INSTANCE, true);
+
+ addPrivateFunction(UNION, UnorderedListConstructorResultType.INSTANCE, true);
+
addPrivateFunction(SUBSET_COLLECTION, new IResultTypeComputer() {
@Override
@@ -1257,8 +1260,7 @@
|| (includePrivateFunctions && builtinPrivateFunctionsSet.keySet().contains(finfo))) {
return true;
}
- fi = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS, signature.getName(),
- signature.getArity());
+ fi = new FunctionIdentifier(AlgebricksBuiltinFunctions.ALGEBRICKS_NS, signature.getName(), signature.getArity());
finfo = getAsterixFunctionInfo(fi);
if (builtinPublicFunctionsSet.keySet().contains(finfo)
|| (includePrivateFunctions && builtinPrivateFunctionsSet.keySet().contains(finfo))) {
@@ -1371,8 +1373,7 @@
registeredFunctionsDomain.put(functionInfo, funcDomain);
}
- public static void addPrivateFunction(FunctionIdentifier fi, IResultTypeComputer typeComputer,
- boolean isFunctional) {
+ public static void addPrivateFunction(FunctionIdentifier fi, IResultTypeComputer typeComputer, boolean isFunctional) {
IFunctionInfo functionInfo = new AsterixFunctionInfo(fi, isFunctional);
builtinPrivateFunctionsSet.put(functionInfo, functionInfo);
funTypeComputer.put(functionInfo, typeComputer);