diff --git a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/RewriteRuleset.java b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/RewriteRuleset.java index aa1dd551a..54a466c74 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/RewriteRuleset.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/RewriteRuleset.java @@ -34,7 +34,6 @@ import org.apache.hyracks.algebricks.rewriter.rules.FactorRedundantGroupAndDecorVarsRule; import org.apache.hyracks.algebricks.rewriter.rules.InferTypesRule; import org.apache.hyracks.algebricks.rewriter.rules.InlineAssignIntoAggregateRule; -import org.apache.hyracks.algebricks.rewriter.rules.InlineVariablesRule; import org.apache.hyracks.algebricks.rewriter.rules.IntroJoinInsideSubplanRule; import org.apache.hyracks.algebricks.rewriter.rules.IntroduceAggregateCombinerRule; import org.apache.hyracks.algebricks.rewriter.rules.IntroduceGroupByCombinerRule; @@ -92,6 +91,7 @@ import org.apache.vxquery.compiler.rewriter.rules.algebricksalternatives.ExtractFunctionsFromJoinConditionRule; import org.apache.vxquery.compiler.rewriter.rules.algebricksalternatives.InlineNestedVariablesRule; import org.apache.vxquery.compiler.rewriter.rules.algebricksalternatives.MoveFreeVariableOperatorOutOfSubplanRule; +import org.apache.vxquery.compiler.rewriter.rules.algebricksalternatives.VXQueryInlineVariablesRule; public class RewriteRuleset { RewriteRuleset() { @@ -272,7 +272,7 @@ public static final List buildNormalizationRuleCollection public static final List buildCondPushDownRuleCollection() { List condPushDown = new LinkedList<>(); condPushDown.add(new PushSelectDownRule()); - condPushDown.add(new InlineVariablesRule()); + condPushDown.add(new VXQueryInlineVariablesRule()); condPushDown.add(new SubplanOutOfGroupRule()); condPushDown.add(new RemoveRedundantVariablesRule()); condPushDown.add(new RemoveUnusedAssignAndAggregateRule()); @@ -289,7 +289,7 @@ public static final List buildCondPushDownRuleCollection( public static final List buildJoinInferenceRuleCollection() { List joinInference = new LinkedList<>(); - joinInference.add(new InlineVariablesRule()); + joinInference.add(new VXQueryInlineVariablesRule()); joinInference.add(new ComplexJoinInferenceRule()); return joinInference; } diff --git a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/algebricksalternatives/InlineNestedVariablesRule.java b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/algebricksalternatives/InlineNestedVariablesRule.java index 16e3e9877..32091a713 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/algebricksalternatives/InlineNestedVariablesRule.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/algebricksalternatives/InlineNestedVariablesRule.java @@ -29,16 +29,18 @@ 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.functions.FunctionIdentifier; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans; import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator; import org.apache.hyracks.algebricks.rewriter.rules.InlineVariablesRule; +import org.apache.vxquery.functions.BuiltinOperators; /** * Modifies the InlineVariablesRule to also process nested plans. */ -public class InlineNestedVariablesRule extends InlineVariablesRule { - +public class InlineNestedVariablesRule extends VXQueryInlineVariablesRule { + protected boolean inlineVariables(Mutable opRef, IOptimizationContext context) throws AlgebricksException { AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); diff --git a/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/algebricksalternatives/VXQueryInlineVariablesRule.java b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/algebricksalternatives/VXQueryInlineVariablesRule.java new file mode 100644 index 000000000..3f793daa7 --- /dev/null +++ b/vxquery-core/src/main/java/org/apache/vxquery/compiler/rewriter/rules/algebricksalternatives/VXQueryInlineVariablesRule.java @@ -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. + */ +package org.apache.vxquery.compiler.rewriter.rules.algebricksalternatives; + +import org.apache.hyracks.algebricks.rewriter.rules.InlineVariablesRule; +import org.apache.vxquery.functions.BuiltinOperators; + +// VXQuery implementation of InlineVariablesRule to specify functions we should not inline +public class VXQueryInlineVariablesRule extends InlineVariablesRule { + + public VXQueryInlineVariablesRule() { + // Ignore element constructor because we need to assign each instance a unique ID + doNotInlineFuncs.add(BuiltinOperators.ELEMENT_CONSTRUCTOR.getFunctionIdentifier()); + } +} diff --git a/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml b/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml index ec2786414..8da386346 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml +++ b/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-operators.xml @@ -252,6 +252,7 @@ + @@ -493,6 +494,7 @@ + diff --git a/vxquery-core/src/main/java/org/apache/vxquery/metadata/VXQueryCollectionOperatorDescriptor.java b/vxquery-core/src/main/java/org/apache/vxquery/metadata/VXQueryCollectionOperatorDescriptor.java index 5ae5ed79d..c61a37c4e 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/metadata/VXQueryCollectionOperatorDescriptor.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/metadata/VXQueryCollectionOperatorDescriptor.java @@ -226,6 +226,7 @@ public void nextFrame(ByteBuffer buffer) throws HyracksDataException { // file currently reading and // send it to parser InputStream in = fs.open(xmlDocument).getWrappedStream(); + parser.parseHDFSElements(in, writer, fta, tupleIndex); in.close(); } @@ -260,7 +261,10 @@ public void xmlAndJsonCollection(File directory) throws HyracksDataException { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Starting to read XML document: " + file.getAbsolutePath()); } - parser.parseElements(file, writer, tupleIndex); + ITreeNodeIdProvider myNodeIdProvider = new TreeNodeIdProvider(partitionId, dataSourceId, totalDataSources, file.getAbsolutePath()); + XMLParser myparser = new XMLParser(false, myNodeIdProvider, nodeId, appender, childSeq, + dCtx.getStaticContext()); + myparser.parseElements(file, writer, tupleIndex); } else if (fileName.endsWith(".json")) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Starting to read JSON document: " + file.getAbsolutePath()); diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/AbstractNodeConstructorScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/AbstractNodeConstructorScalarEvaluator.java index dba35946e..e07a1c9a0 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/AbstractNodeConstructorScalarEvaluator.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/AbstractNodeConstructorScalarEvaluator.java @@ -26,7 +26,8 @@ import org.apache.vxquery.exceptions.ErrorCode; import org.apache.vxquery.exceptions.SystemException; import org.apache.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluator; - +import org.apache.vxquery.xmlparser.ITreeNodeIdProvider; +import org.apache.vxquery.xmlparser.TreeNodeIdProvider; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; import org.apache.hyracks.api.context.IHyracksTaskContext; import org.apache.hyracks.data.std.api.IMutableValueStorage; @@ -34,6 +35,8 @@ import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; public abstract class AbstractNodeConstructorScalarEvaluator extends AbstractTaggedValueArgumentScalarEvaluator { + protected final static ITreeNodeIdProvider NodeConstructorIdProvider = new TreeNodeIdProvider((short) 0); + protected final IHyracksTaskContext ctx; private final ArrayBackedValueStorage abvs; @@ -42,12 +45,19 @@ public abstract class AbstractNodeConstructorScalarEvaluator extends AbstractTag private final ArrayBackedValueStorage contentAbvs; + protected final ITreeNodeIdProvider nodeIdProvider; + public AbstractNodeConstructorScalarEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) { super(args); this.ctx = ctx; abvs = new ArrayBackedValueStorage(); db = createsDictionary() ? new DictionaryBuilder() : null; contentAbvs = createsDictionary() ? new ArrayBackedValueStorage() : abvs; + if (createsNodeId()) { + nodeIdProvider = NodeConstructorIdProvider; + } else { + nodeIdProvider = null; + } } @Override @@ -58,7 +68,13 @@ protected final void evaluate(TaggedValuePointable[] args, IPointable result) th DataOutput mainOut = abvs.getDataOutput(); mainOut.write(ValueTag.NODE_TREE_TAG); byte header = (byte) (createsDictionary() ? NodeTreePointable.HEADER_DICTIONARY_EXISTS_MASK : 0); + + header |= (byte) (nodeIdProvider != null ? NodeTreePointable.HEADER_NODEID_EXISTS_MASK : 0); mainOut.write(header); + + if (nodeIdProvider != null) { + mainOut.writeInt(nodeIdProvider.getId()); + } constructNode(db, args, contentAbvs); if (createsDictionary()) { db.write(abvs); @@ -74,4 +90,6 @@ protected abstract void constructNode(DictionaryBuilder db, TaggedValuePointable throws IOException, SystemException; protected abstract boolean createsDictionary(); + + protected abstract boolean createsNodeId(); } diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/AttributeNodeConstructorScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/AttributeNodeConstructorScalarEvaluator.java index 39216f4cb..a41e29b09 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/AttributeNodeConstructorScalarEvaluator.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/AttributeNodeConstructorScalarEvaluator.java @@ -70,4 +70,9 @@ protected void constructNode(DictionaryBuilder db, TaggedValuePointable[] args, protected boolean createsDictionary() { return true; } + + @Override + protected boolean createsNodeId() { + return false; + } } diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/CommentNodeConstructorScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/CommentNodeConstructorScalarEvaluator.java index 917600a3d..7317d955d 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/CommentNodeConstructorScalarEvaluator.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/CommentNodeConstructorScalarEvaluator.java @@ -58,4 +58,9 @@ protected void constructNode(DictionaryBuilder db, TaggedValuePointable[] args, protected boolean createsDictionary() { return false; } + + @Override + protected boolean createsNodeId() { + return false; + } } diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ElementNodeConstructorScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ElementNodeConstructorScalarEvaluator.java index cfcdd1358..e7825d1e4 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ElementNodeConstructorScalarEvaluator.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/ElementNodeConstructorScalarEvaluator.java @@ -39,7 +39,8 @@ import org.apache.vxquery.datamodel.values.ValueTag; import org.apache.vxquery.exceptions.ErrorCode; import org.apache.vxquery.exceptions.SystemException; - +import org.apache.vxquery.xmlparser.ITreeNodeIdProvider; +import org.apache.vxquery.xmlparser.TreeNodeIdProvider; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; import org.apache.hyracks.api.context.IHyracksTaskContext; import org.apache.hyracks.data.std.api.IMutableValueStorage; @@ -71,6 +72,10 @@ public class ElementNodeConstructorScalarEvaluator extends AbstractNodeConstruct private final IMutableValueStorage abvs; + private final boolean createNodeIds; + + private static int nodeIdCounter = 0; + public ElementNodeConstructorScalarEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) { super(ctx, args); anb = new AttributeNodeBuilder(); @@ -84,6 +89,8 @@ public ElementNodeConstructorScalarEvaluator(IHyracksTaskContext ctx, IScalarEva cqp = (CodedQNamePointable) CodedQNamePointable.FACTORY.createPointable(); strp = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable(); seqp = (SequencePointable) SequencePointable.FACTORY.createPointable(); + + createNodeIds = nodeIdProvider != null; } @Override @@ -102,6 +109,10 @@ protected void constructNode(DictionaryBuilder db, TaggedValuePointable[] args, namep.getLocalName(strp); int localCode = db.lookup(strp); enb.setName(uriCode, localCode, prefixCode); + + if (createNodeIds) + enb.setLocalNodeId(nodeIdCounter++); + TaggedValuePointable valueArg = args[1]; enb.startAttributeChunk(); int index = processAttributes(valueArg, db); @@ -173,6 +184,11 @@ private void copyAttribute(ElementNodeBuilder enb, DictionaryBuilder db, NodeTre int newPrefixCode = recode(cqp.getPrefixCode(), ntp, db, strp); int newLocalCode = recode(cqp.getLocalCode(), ntp, db, strp); anb.setName(newURICode, newLocalCode, newPrefixCode); + + if (createNodeIds) { + anb.setLocalNodeId(nodeIdCounter++); + } + anp.getValue(ntp, vp); anb.setValue(vp); enb.endAttribute(anb); @@ -198,6 +214,11 @@ private void copyElement(ElementNodeBuilder enb, DictionaryBuilder db, NodeTreeP int newPrefixCode = recode(cqp.getPrefixCode(), ntp, db, strp); int newLocalCode = recode(cqp.getLocalCode(), ntp, db, strp); tempEnb.setName(newURICode, newLocalCode, newPrefixCode); + + if (createNodeIds) { + tempEnb.setLocalNodeId(nodeIdCounter++); + } + tempEnb.startAttributeChunk(); if (enp.attributesChunkExists()) { enp.getAttributeSequence(ntp, seqp); @@ -286,8 +307,8 @@ private int recode(int oldCode, NodeTreePointable ntp, DictionaryBuilder db, UTF return db.lookup(tempStrp); } - private void processChildren(TaggedValuePointable tvp, int start, DictionaryBuilder db) throws IOException, - SystemException { + private void processChildren(TaggedValuePointable tvp, int start, DictionaryBuilder db) + throws IOException, SystemException { if (tvp.getTag() == ValueTag.SEQUENCE_TAG) { tvp.getValue(seqp); TaggedValuePointable tempTvp = ppool.takeOne(TaggedValuePointable.class); @@ -379,6 +400,11 @@ protected boolean createsDictionary() { return true; } + @Override + protected boolean createsNodeId() { + return true; + } + private void copyComment(TaggedValuePointable tvp, NodeTreePointable ntp, IMutableValueStorage mvs) throws IOException { VoidPointable vp = ppool.takeOne(VoidPointable.class); @@ -388,6 +414,11 @@ private void copyComment(TaggedValuePointable tvp, NodeTreePointable ntp, IMutab tcnp.getValue(ntp, vp); cnb.reset(mvs); + + if (createNodeIds) { + cnb.setLocalNodeId(nodeIdCounter++); + } + cnb.setValue(vp); ppool.giveBack(vp); @@ -404,6 +435,11 @@ private void copyPI(TaggedValuePointable tvp, NodeTreePointable ntp, IMutableVal pnp.getTarget(ntp, vp2); pnb.reset(mvs); + + if (createNodeIds) { + pnb.setLocalNodeId(nodeIdCounter++); + } + pnb.setContent(vp2); pnb.setTarget(vp1); @@ -412,13 +448,19 @@ private void copyPI(TaggedValuePointable tvp, NodeTreePointable ntp, IMutableVal ppool.giveBack(vp2); } - private void copyText(TaggedValuePointable tvp, NodeTreePointable ntp, IMutableValueStorage mvs) throws IOException { + private void copyText(TaggedValuePointable tvp, NodeTreePointable ntp, IMutableValueStorage mvs) + throws IOException { VoidPointable vp = ppool.takeOne(VoidPointable.class); TextOrCommentNodePointable tcnp = ppool.takeOne(TextOrCommentNodePointable.class); tvp.getValue(tcnp); tcnp.getValue(ntp, vp); tnb.reset(mvs); + + if (createNodeIds) { + tnb.setLocalNodeId(nodeIdCounter++); + } + tnb.setValue(vp); ppool.giveBack(vp); @@ -431,6 +473,11 @@ private void convertToText(TaggedValuePointable tvp, IMutableValueStorage mvs) t TextNodeBuilder tnb = new TextNodeBuilder(); tvp.getValue(vp); tnb.reset(mvs); + + if (createNodeIds) { + tnb.setLocalNodeId(nodeIdCounter++); + } + tnb.setValue(vp); ppool.giveBack(vp); diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/FnDocScalarEvaluatorFactory.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/FnDocScalarEvaluatorFactory.java index e3157afdb..f4e8f29ec 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/FnDocScalarEvaluatorFactory.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/FnDocScalarEvaluatorFactory.java @@ -17,6 +17,8 @@ package org.apache.vxquery.runtime.functions.node; import java.io.DataInputStream; +import java.util.HashMap; +import java.util.Map; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; @@ -56,8 +58,7 @@ protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvalu final ByteBufferInputStream bbis = new ByteBufferInputStream(); final DataInputStream di = new DataInputStream(bbis); final int partition = ctx.getTaskAttemptId().getTaskId().getPartition(); - final ITreeNodeIdProvider nodeIdProvider = new TreeNodeIdProvider((short) partition); - final String nodeId = ctx.getJobletContext().getServiceContext().getNodeId(); + final String nodeId = ctx.getJobletContext().getApplicationContext().getNodeId(); return new AbstractTaggedValueArgumentScalarEvaluator(args) { @Override @@ -78,6 +79,7 @@ protected void evaluate(TaggedValuePointable[] args, IPointable result) throws S tvp.getValue(stringp); try { // Only one document should be parsed so its ok to have a unique parser. + ITreeNodeIdProvider nodeIdProvider = new TreeNodeIdProvider((short) partition, stringp.toString()); IParser parser = new XMLParser(false, nodeIdProvider, nodeId); FunctionHelper.readInDocFromPointable(stringp, abvs, parser); } catch (Exception e) { diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/PINodeConstructorScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/PINodeConstructorScalarEvaluator.java index 839b79b1e..69248afb6 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/PINodeConstructorScalarEvaluator.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/PINodeConstructorScalarEvaluator.java @@ -56,4 +56,9 @@ protected void constructNode(DictionaryBuilder db, TaggedValuePointable[] args, protected boolean createsDictionary() { return false; } + + @Override + protected boolean createsNodeId() { + return false; + } } diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/TextNodeConstructorScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/TextNodeConstructorScalarEvaluator.java index 7d69a14fc..3f5e18ecf 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/TextNodeConstructorScalarEvaluator.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/node/TextNodeConstructorScalarEvaluator.java @@ -58,4 +58,9 @@ protected void constructNode(DictionaryBuilder db, TaggedValuePointable[] args, protected boolean createsDictionary() { return false; } + + @Override + protected boolean createsNodeId() { + return false; + } } diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/sequence/OpIntersectScalarEvaluatorFactory.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/sequence/OpIntersectScalarEvaluatorFactory.java new file mode 100644 index 000000000..f70cba281 --- /dev/null +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/sequence/OpIntersectScalarEvaluatorFactory.java @@ -0,0 +1,180 @@ +/* + * 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.vxquery.runtime.functions.sequence; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +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.api.exceptions.HyracksDataException; +import org.apache.hyracks.data.std.api.IPointable; +import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; +import org.apache.vxquery.datamodel.accessors.SequencePointable; +import org.apache.vxquery.datamodel.accessors.TaggedValuePointable; +import org.apache.vxquery.datamodel.accessors.TypedPointables; +import org.apache.vxquery.datamodel.builders.sequence.SequenceBuilder; +import org.apache.vxquery.datamodel.values.ValueTag; +import org.apache.vxquery.exceptions.ErrorCode; +import org.apache.vxquery.exceptions.SystemException; +import org.apache.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluator; +import org.apache.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluatorFactory; +import org.apache.vxquery.runtime.functions.util.FunctionHelper; + +public class OpIntersectScalarEvaluatorFactory extends AbstractTaggedValueArgumentScalarEvaluatorFactory { + private static final long serialVersionUID = 1L; + + class Pair { + private int localId; + private byte fileId; + + Pair(int l, byte f) { + localId = l; + fileId = f; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + localId; + result = prime * result + fileId; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Pair other = (Pair) obj; + if (localId != other.localId) + return false; + if (fileId != other.fileId) + return false; + return true; + } + } + + public OpIntersectScalarEvaluatorFactory(IScalarEvaluatorFactory[] args) { + super(args); + } + + @Override + protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) + throws HyracksDataException { + final ArrayBackedValueStorage abvs = new ArrayBackedValueStorage(); + final SequenceBuilder sb = new SequenceBuilder(); + + final SequencePointable seqleft = (SequencePointable) SequencePointable.FACTORY.createPointable(); + final SequencePointable seqright = (SequencePointable) SequencePointable.FACTORY.createPointable(); + final TaggedValuePointable tvpleft = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable(); + final TaggedValuePointable tvpright = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable(); + + // a set of node ids in the left operand + Set nodes = new HashSet(); + // a set of node ids that will appear in the final result + Set resultNodes = new HashSet(); + + return new AbstractTaggedValueArgumentScalarEvaluator(args) { + @Override + protected void evaluate(TaggedValuePointable[] args, IPointable result) throws SystemException { + try { + abvs.reset(); + sb.reset(abvs); + TaggedValuePointable tvp1 = args[0]; + TaggedValuePointable tvp2 = args[1]; + + if ((tvp1.getTag() != ValueTag.SEQUENCE_TAG && tvp1.getTag() != ValueTag.NODE_TREE_TAG) + || (tvp2.getTag() != ValueTag.SEQUENCE_TAG && tvp2.getTag() != ValueTag.NODE_TREE_TAG)) { + throw new SystemException(ErrorCode.FORG0006); + } + + // If an operand has one item then it is a node tree + // If an operand has more than one item then it is a sequence + // IF an operand has 0 items then it is an empty sequence + + // Add items from the left operand into the hash set; this removes duplicates + if (tvp1.getTag() == ValueTag.SEQUENCE_TAG) { + tvp1.getValue(seqleft); + for (int i = 0; i < seqleft.getEntryCount(); ++i) { + seqleft.getEntry(i, tvpleft); + if (tvpleft.getTag() != ValueTag.NODE_TREE_TAG) + throw new SystemException(ErrorCode.XPTY0004); + Pair id = getId(tvpleft); + nodes.add(id); + } + } else { + Pair id = getId(tvp1); + nodes.add(id); + } + + // Check if node IDs from right operand are in the hash set + if (tvp2.getTag() == ValueTag.SEQUENCE_TAG) { + tvp2.getValue(seqright); + for (int i = 0; i < seqright.getEntryCount(); ++i) { + seqright.getEntry(i, tvpright); + if (tvpright.getTag() != ValueTag.NODE_TREE_TAG) + throw new SystemException(ErrorCode.XPTY0004); + + Pair temp = getId(tvpright); + if (nodes.contains(temp)) { + if (!resultNodes.contains(temp)) { + resultNodes.add(temp); + sb.addItem(tvpright); + } + } + } + } else { + Pair temp = getId(tvp2); + if (nodes.contains(temp)) { + if (!resultNodes.contains(temp)) { + resultNodes.add(temp); + sb.addItem(tvp2); + } + } + } + + sb.finish(); + result.set(abvs); + } catch (IOException e) { + throw new SystemException(ErrorCode.SYSE0001); + } + } + }; + } + + // Summary: Gets the id of a Node Tree + // Parameter tvp: The Node Tree we want to get the id of + // Return: The local node id, file id pait of tvp + // Error: if the local node id is -1 + private Pair getId(TaggedValuePointable tvp) { + TypedPointables tp = new TypedPointables(); + int nodeId = FunctionHelper.getLocalNodeId(tvp, tp); + if (nodeId == -1) { + // TODO + } + int rootNodeId = tp.ntp.getRootNodeId(); + byte fileId = (byte) (rootNodeId >> 24); + return new Pair(nodeId, fileId); + } +} \ No newline at end of file diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/sequence/OpUnionScalarEvaluatorFactory.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/sequence/OpUnionScalarEvaluatorFactory.java new file mode 100644 index 000000000..db5c9cb1c --- /dev/null +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/sequence/OpUnionScalarEvaluatorFactory.java @@ -0,0 +1,95 @@ +/* + * 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.vxquery.runtime.functions.sequence; + +import java.io.DataOutput; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +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.api.exceptions.HyracksDataException; +import org.apache.hyracks.data.std.api.IPointable; +import org.apache.hyracks.data.std.primitive.LongPointable; +import org.apache.hyracks.data.std.primitive.UTF8StringPointable; +import org.apache.hyracks.data.std.primitive.VoidPointable; +import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; +import org.apache.vxquery.context.DynamicContext; +import org.apache.vxquery.datamodel.accessors.SequencePointable; +import org.apache.vxquery.datamodel.accessors.TaggedValuePointable; +import org.apache.vxquery.datamodel.accessors.TypedPointables; +import org.apache.vxquery.datamodel.accessors.nodes.ElementNodePointable; +import org.apache.vxquery.datamodel.accessors.nodes.NodeTreePointable; +import org.apache.vxquery.datamodel.builders.sequence.SequenceBuilder; +import org.apache.vxquery.datamodel.values.ValueTag; +import org.apache.vxquery.datamodel.values.XDMConstants; +import org.apache.vxquery.exceptions.ErrorCode; +import org.apache.vxquery.exceptions.SystemException; +import org.apache.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluator; +import org.apache.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluatorFactory; +import org.apache.vxquery.runtime.functions.comparison.AbstractValueComparisonOperation; +import org.apache.vxquery.runtime.functions.comparison.ValueEqComparisonOperation; +import org.apache.vxquery.runtime.functions.comparison.general.AbstractGeneralComparisonScalarEvaluatorFactory; +import org.apache.vxquery.runtime.functions.comparison.general.GeneralEqComparisonScalarEvaluatorFactory; +import org.apache.vxquery.runtime.functions.util.FunctionHelper; + +public class OpUnionScalarEvaluatorFactory extends AbstractTaggedValueArgumentScalarEvaluatorFactory { + private static final long serialVersionUID = 1L; + + public OpUnionScalarEvaluatorFactory(IScalarEvaluatorFactory[] args) { + super(args); + } + + @Override + protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) + throws HyracksDataException { + final ArrayBackedValueStorage abvs = new ArrayBackedValueStorage(); + final SequenceBuilder sb = new SequenceBuilder(); + + final SequencePointable seqleft = (SequencePointable) SequencePointable.FACTORY.createPointable(); + final SequencePointable seqright = (SequencePointable) SequencePointable.FACTORY.createPointable(); + final TaggedValuePointable tvpleft = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable(); + final TaggedValuePointable tvpright = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable(); + final TypedPointables tpleft = new TypedPointables(); + final TypedPointables tpright = new TypedPointables(); + + Map arg1_nodes = new HashMap(); + Map intersect_nodes = new HashMap(); + + return new AbstractTaggedValueArgumentScalarEvaluator(args) { + @Override + protected void evaluate(TaggedValuePointable[] args, IPointable result) throws SystemException { + try { + abvs.reset(); + sb.reset(abvs); + TaggedValuePointable tvp1 = args[0]; + TaggedValuePointable tvp2 = args[1]; + + sb.addItem(tvp1); + sb.addItem(tvp2); + + sb.finish(); + result.set(abvs); + } catch (IOException e) { + throw new SystemException(ErrorCode.SYSE0001); + } + } + }; + } +} diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/util/FunctionHelper.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/util/FunctionHelper.java index 1d66c4eb8..424181271 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/util/FunctionHelper.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/util/FunctionHelper.java @@ -1223,12 +1223,13 @@ public static void printUTF8String(UTF8StringPointable stringp) { System.err.println(" printUTF8String END"); } - public static void readInDocFromPointable(UTF8StringPointable stringp, ArrayBackedValueStorage abvs, - IParser parser) throws IOException { + public static void readInDocFromPointable(UTF8StringPointable stringp, ArrayBackedValueStorage abvs, IParser parser) + throws IOException { readInDocFromString(stringp.toString(), abvs, parser); } - public static void readInDocFromString(String fName, ArrayBackedValueStorage abvs, IParser parser) throws IOException { + public static void readInDocFromString(String fName, ArrayBackedValueStorage abvs, IParser parser) + throws IOException { Reader input; if (!fName.contains("hdfs:/")) { File file = new File(fName); diff --git a/vxquery-core/src/main/java/org/apache/vxquery/xmlparser/TreeNodeIdProvider.java b/vxquery-core/src/main/java/org/apache/vxquery/xmlparser/TreeNodeIdProvider.java index 957b91e55..3179d5459 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/xmlparser/TreeNodeIdProvider.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/xmlparser/TreeNodeIdProvider.java @@ -16,18 +16,37 @@ */ package org.apache.vxquery.xmlparser; +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.apache.vxquery.datamodel.accessors.TaggedValuePointable; + public class TreeNodeIdProvider implements ITreeNodeIdProvider { private final short partitionDataSource; private final short dataSouceScanId; private final byte dataSourceBits; private short currentId; + private byte fileId; + private static Map Files = new HashMap(); + // File ID 0 is reserved for element constructor + private static byte nextFileId = 1; public TreeNodeIdProvider(short partitionDataSource, short dataSouceScanId, short totalDataSources) { this.partitionDataSource = partitionDataSource; this.dataSouceScanId = dataSouceScanId; this.dataSourceBits = getBitsNeeded(totalDataSources); currentId = 0; + fileId = 0; + } + + public TreeNodeIdProvider(short partitionDataSource, short dataSouceScanId, short totalDataSources, String uri) { + this.partitionDataSource = partitionDataSource; + this.dataSouceScanId = dataSouceScanId; + this.dataSourceBits = getBitsNeeded(totalDataSources); + currentId = 0; + fileId = getFileId(uri); } public TreeNodeIdProvider(short partition) { @@ -35,12 +54,38 @@ public TreeNodeIdProvider(short partition) { dataSouceScanId = 0; dataSourceBits = 0; currentId = 0; + fileId = 0; + } + + public TreeNodeIdProvider(short partition, String uri) { + this.partitionDataSource = partition; + dataSouceScanId = 0; + dataSourceBits = 0; + currentId = 0; + fileId = getFileId(uri); + } + + public byte getFileId(String uri) { + // Try to get canonical path + String path = null; + try { + path = new File(uri).getCanonicalPath(); + } catch (Exception e) { + path = uri; + } + if (Files.containsKey(path)) { + return Files.get(path); + } else { + Files.put(path, nextFileId); + return nextFileId++; + } } public int getId() { int p = partitionDataSource; int dssi = dataSouceScanId; - return (p << 16) | (dssi << (16 - dataSourceBits)) | currentId++; + int f = fileId; + return (f << 24) | (p << 16) | (dssi << (16 - dataSourceBits)) | currentId++; } private byte getBitsNeeded(int number) { diff --git a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java index 6d0b35a67..11008ee41 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/xmlquery/translator/XMLQueryTranslator.java @@ -778,35 +778,35 @@ private LogicalVariable translateExpression(ASTNode value, TranslationContext tC return translateQuantifiedExprNode(tCtx, qeNode); } - /* - case TYPESWITCH_EXPRESSION: { - TypeswitchExprNode teNode = (TypeswitchExprNode) value; - Expression sExpr = translateExpression(teNode.getSwitchExpr()); - ForLetVariable tVar = new ForLetVariable(VarTag.LET, createVarName(), sExpr); - tVar.setDeclaredStaticType(SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_STAR)); + /* + case TYPESWITCH_EXPRESSION: { + TypeswitchExprNode teNode = (TypeswitchExprNode) value; + Expression sExpr = translateExpression(teNode.getSwitchExpr()); + ForLetVariable tVar = new ForLetVariable(VarTag.LET, createVarName(), sExpr); + tVar.setDeclaredStaticType(SequenceType.create(AnyItemType.INSTANCE, Quantifier.QUANT_STAR)); + pushVariableScope(); + varScope.registerVariable(tVar); + List cases = new ArrayList(); + for (CaseClauseNode ccNode : teNode.getCaseClauses()) { + SequenceType type = createSequenceType(ccNode.getType()); + ForLetVariable caseVar = null; pushVariableScope(); - varScope.registerVariable(tVar); - List cases = new ArrayList(); - for (CaseClauseNode ccNode : teNode.getCaseClauses()) { - SequenceType type = createSequenceType(ccNode.getType()); - ForLetVariable caseVar = null; - pushVariableScope(); - if (ccNode.getCaseVar() != null) { - caseVar = new ForLetVariable(VarTag.LET, createQName(ccNode.getCaseVar()), new TreatExpression( - currCtx, new VariableReferenceExpression(currCtx, tVar), type)); - caseVar.setDeclaredStaticType(type); - varScope.registerVariable(caseVar); - } - Expression cExpr = translateExpression(ccNode.getValueExpr()); - TypeswitchExpression.Case c = new TypeswitchExpression.Case(caseVar, type, cExpr); - cases.add(c); - popVariableScope(); + if (ccNode.getCaseVar() != null) { + caseVar = new ForLetVariable(VarTag.LET, createQName(ccNode.getCaseVar()), new TreatExpression( + currCtx, new VariableReferenceExpression(currCtx, tVar), type)); + caseVar.setDeclaredStaticType(type); + varScope.registerVariable(caseVar); } - Expression dExpr = translateExpression(teNode.getDefaultClause()); + Expression cExpr = translateExpression(ccNode.getValueExpr()); + TypeswitchExpression.Case c = new TypeswitchExpression.Case(caseVar, type, cExpr); + cases.add(c); popVariableScope(); - return new TypeswitchExpression(currCtx, tVar, cases, dExpr); } - */ + Expression dExpr = translateExpression(teNode.getDefaultClause()); + popVariableScope(); + return new TypeswitchExpression(currCtx, tVar, cases, dExpr); + } + */ case COMPUTED_TEXT_CONSTRUCTOR: { ComputedTextConstructorNode cNode = (ComputedTextConstructorNode) value; @@ -974,7 +974,8 @@ private LogicalVariable translateValidateExprNode(TranslationContext tCtx, Valid throws SystemException { XQueryConstants.ValidationMode mode = vNode.getMode(); Function fn = mode == null || XQueryConstants.ValidationMode.STRICT.equals(mode) - ? BuiltinOperators.VALIDATE_STRICT : BuiltinOperators.VALIDATE_LAX; + ? BuiltinOperators.VALIDATE_STRICT + : BuiltinOperators.VALIDATE_LAX; LogicalVariable lVar = createAssignment(sfce(fn, vre(translateExpression(vNode.getExpr(), tCtx))), tCtx); return lVar; } @@ -1538,14 +1539,16 @@ private LogicalVariable translateInfixExprNode(TranslationContext tCtx, InfixExp LogicalVariable varRight = translateExpression(ie.getRightExpr(), tCtx); ILogicalExpression arg1 = normalize(vre(varLeft), sign.getParameterType(0)); ILogicalExpression arg2 = normalize(vre(varRight), sign.getParameterType(1)); + /* if (BuiltinOperators.EXCEPT.equals(operator) || BuiltinOperators.INTERSECT.equals(operator)) { arg1 = sfce(BuiltinOperators.SORT_DISTINCT_NODES_ASC, arg1); arg2 = sfce(BuiltinOperators.SORT_DISTINCT_NODES_ASC, arg2); } + */ ILogicalExpression result = sfce(operator, arg1, arg2); - if (BuiltinOperators.UNION.equals(operator)) { - result = sfce(BuiltinOperators.SORT_DISTINCT_NODES_ASC, result); - } + // if (BuiltinOperators.UNION.equals(operator)) { + // result = sfce(BuiltinOperators.SORT_DISTINCT_NODES_ASC, result); + // } LogicalVariable lVar = createAssignment(result, tCtx); return lVar; } diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect01.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect01.txt new file mode 100644 index 000000000..cad67d62e --- /dev/null +++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect01.txt @@ -0,0 +1,14 @@ + + Oberg, Bruce + The Poet's First Poem + Poem + 24.95 + The least poetic poems of the decade. + + + Nagata, Suanne + Becoming Somebody + Biography + 39 + A masterpiece of the fine art of gossiping. + \ No newline at end of file diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect02.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect02.txt new file mode 100644 index 000000000..343338bcb --- /dev/null +++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect02.txt @@ -0,0 +1,7 @@ + + Oberg, Bruce + The Poet's First Poem + Poem + 24.95 + The least poetic poems of the decade. + \ No newline at end of file diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect03.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect03.txt new file mode 100644 index 000000000..343338bcb --- /dev/null +++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect03.txt @@ -0,0 +1,7 @@ + + Oberg, Bruce + The Poet's First Poem + Poem + 24.95 + The least poetic poems of the decade. + \ No newline at end of file diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect04.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect04.txt new file mode 100644 index 000000000..e69de29bb diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect05.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect05.txt new file mode 100644 index 000000000..89142d211 --- /dev/null +++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Intersect/intersect05.txt @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect01.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect01.xq new file mode 100644 index 000000000..36a3e38dd --- /dev/null +++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect01.xq @@ -0,0 +1,21 @@ +(: 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. :) + +let $c := "catalog" +let $a := doc($c)/catalog/book[price<50] +let $b := doc($c)/catalog/book[price<40] +return $a intersect $b diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect02.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect02.xq new file mode 100644 index 000000000..351d50938 --- /dev/null +++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect02.xq @@ -0,0 +1,21 @@ +(: 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. :) + +let $c := "catalog" +let $a := doc($c)/catalog/book[price<25] +let $b := doc($c)/catalog/book[price<50] +return $a intersect $b diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect03.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect03.xq new file mode 100644 index 000000000..4d55752c9 --- /dev/null +++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect03.xq @@ -0,0 +1,21 @@ +(: 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. :) + +let $c := "catalog" +let $a := doc($c)/catalog/book[price<25] +let $b := doc($c)/catalog/book[price<50] +return $b intersect $a diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect04.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect04.xq new file mode 100644 index 000000000..d87fe5048 --- /dev/null +++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect04.xq @@ -0,0 +1,21 @@ +(: 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. :) + +let $c := "catalog" +let $a := doc($c)/catalog/book[price<40] +let $b := doc($c)/catalog/book[price>40] +return $a intersect $b diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect05.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect05.xq new file mode 100644 index 000000000..f0bc60c13 --- /dev/null +++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Intersect/intersect05.xq @@ -0,0 +1,25 @@ +(: 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. :) + +let $a := 5 +let $b := $a +return $a intersect $b + + + + + diff --git a/vxquery-xtest/src/test/resources/TestSources/xml/catalog.xml b/vxquery-xtest/src/test/resources/TestSources/xml/catalog.xml new file mode 100644 index 000000000..ffe091f05 --- /dev/null +++ b/vxquery-xtest/src/test/resources/TestSources/xml/catalog.xml @@ -0,0 +1,40 @@ + + + + + Hightower, Kim + The First Book + Fiction + 44.95 + 2000-10-01 + An amazing story of nothing. + + + + Oberg, Bruce + The Poet's First Poem + Poem + 24.95 + The least poetic poems of the decade. + + + + Nagata, Suanne + Becoming Somebody + Biography + 39 + A masterpiece of the fine art of gossiping. + + + + + diff --git a/vxquery-xtest/src/test/resources/VXQueryCatalog.xml b/vxquery-xtest/src/test/resources/VXQueryCatalog.xml index 7a4438e5e..d0e0672a1 100644 --- a/vxquery-xtest/src/test/resources/VXQueryCatalog.xml +++ b/vxquery-xtest/src/test/resources/VXQueryCatalog.xml @@ -58,6 +58,8 @@ + + ]> @@ -145,6 +147,9 @@ File + + File + @@ -381,4 +386,16 @@ &XMLInJSONQueries; + + + Set Operators + Set Operators: Intersect and Union + + + + Tests for Set Operators + + &SetOperatorQueries; + + diff --git a/vxquery-xtest/src/test/resources/cat/SetOperatorQueries.xml b/vxquery-xtest/src/test/resources/cat/SetOperatorQueries.xml new file mode 100644 index 000000000..6aa7ba67e --- /dev/null +++ b/vxquery-xtest/src/test/resources/cat/SetOperatorQueries.xml @@ -0,0 +1,52 @@ + + + + + Set Operator Test + + + + Intersects two sets both with more than 1 item + + + intersect01.txt + + + Left operand has 1 item, right operand has many + + + intersect02.txt + + + Testing reverse of test 2 + + intersect03.txt + + + Left and right operand have items that don't intersect + + + intersect04.txt + + + Text inline xml nodes + + intersect05.txt + +