Implement descendant-objects and descendant-pairs
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-functions.xml b/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-functions.xml
index 1cbda7a..93f2cb3 100644
--- a/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-functions.xml
+++ b/vxquery-core/src/main/java/org/apache/vxquery/functions/builtin-functions.xml
@@ -1220,10 +1220,25 @@
<return type="item()*"/>
<runtime type="scalar" class="org.apache.vxquery.runtime.functions.json.LibjnFlattenScalarEvaluatorFactory"/>
</function>
+
<!-- libjn:values($sequence as item()*) as item()* -->
<function name="libjn:values">
<param name="sequence" type="item()*"/>
<return type="item()*"/>
<runtime type="scalar" class="org.apache.vxquery.runtime.functions.json.LibjnValuesScalarEvaluatorFactory"/>
</function>
+
+ <!-- libjn:descendant-objects($sequence as item()*) as object()* -->
+ <function name="libjn:descendant-objects">
+ <param name="sequence" type="item()*"/>
+ <return type="object()*"/>
+ <runtime type="scalar" class="org.apache.vxquery.runtime.functions.json.LibjnDescendantObjectsScalarEvaluatorFactory"/>
+ </function>
+
+ <!-- libjn:descendant-pairs($sequence as item()*) object()* -->
+ <function name="libjn:descendant-pairs">
+ <param name="sequence" type="item()*"/>
+ <return type="object()*"/>
+ <runtime type="scalar" class="org.apache.vxquery.runtime.functions.json.LibjnDescendantPairsScalarEvaluatorFactory"/>
+ </function>
</functions>
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/AbstractLibjnDescendantScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/AbstractLibjnDescendantScalarEvaluator.java
new file mode 100644
index 0000000..7083291
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/AbstractLibjnDescendantScalarEvaluator.java
@@ -0,0 +1,120 @@
+/*
+* 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.json;
+
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+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.jsonitem.ArrayPointable;
+import org.apache.vxquery.datamodel.accessors.jsonitem.ObjectPointable;
+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 java.io.IOException;
+
+public abstract class AbstractLibjnDescendantScalarEvaluator extends AbstractTaggedValueArgumentScalarEvaluator {
+ protected final IHyracksTaskContext ctx;
+ protected final UTF8StringPointable stringp;
+ protected final SequencePointable sp, sp1;
+ protected final SequenceBuilder sb;
+ protected final ArrayBackedValueStorage abvs;
+
+ public AbstractLibjnDescendantScalarEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) {
+ super(args);
+ this.ctx = ctx;
+ stringp = (UTF8StringPointable) UTF8StringPointable.FACTORY.createPointable();
+ sp = (SequencePointable) SequencePointable.FACTORY.createPointable();
+ sp1 = (SequencePointable) SequencePointable.FACTORY.createPointable();
+ sb = new SequenceBuilder();
+ abvs = new ArrayBackedValueStorage();
+ }
+
+ @Override
+ protected void evaluate(TaggedValuePointable[] args, IPointable result) throws SystemException {
+ try {
+ abvs.reset();
+ sb.reset(abvs);
+ TaggedValuePointable tvp = args[0];
+ if (tvp.getTag() == ValueTag.SEQUENCE_TAG) {
+ TaggedValuePointable tempTvp = ppool.takeOne(TaggedValuePointable.class);
+ tvp.getValue(sp);
+ int size = sp.getEntryCount();
+ for (int i = 0; i < size; i++) {
+ sp.getEntry(i, tempTvp);
+ process(tempTvp);
+ }
+ ppool.giveBack(tempTvp);
+ } else {
+ process(tvp);
+ }
+ sb.finish();
+ result.set(abvs);
+ } catch (IOException e) {
+ throw new SystemException(ErrorCode.SYSE0001, e);
+ }
+ }
+
+ protected void processObject(TaggedValuePointable tvp) throws IOException {
+ TaggedValuePointable tempTvp = ppool.takeOne(TaggedValuePointable.class);
+ ObjectPointable tempOp = ppool.takeOne(ObjectPointable.class);
+ tvp.getValue(tempOp);
+ tempOp.getKeys(tempTvp);
+ if (tempTvp.getTag() == ValueTag.XS_STRING_TAG) {
+ processPair(tempTvp, tempOp);
+ process(tempTvp);
+ } else if (tempTvp.getTag() == ValueTag.SEQUENCE_TAG) {
+ tempTvp.getValue(sp1);
+ int size = sp1.getEntryCount();
+ for (int i = 0; i < size; i++) {
+ sp1.getEntry(i, tempTvp);
+ processPair(tempTvp, tempOp);
+ process(tempTvp);
+ }
+ }
+ ppool.giveBack(tempOp);
+ ppool.giveBack(tempTvp);
+ }
+
+ protected abstract void processPair(TaggedValuePointable tempTvp, ObjectPointable tempOp) throws IOException;
+
+ protected void process(TaggedValuePointable tvp) throws IOException {
+ if (tvp.getTag() == ValueTag.OBJECT_TAG) {
+ processObject(tvp);
+ } else if (tvp.getTag() == ValueTag.ARRAY_TAG) {
+ processArray(tvp);
+ }
+ }
+
+ protected void processArray(TaggedValuePointable tvp) throws IOException {
+ ArrayPointable ap = ppool.takeOne(ArrayPointable.class);
+ tvp.getValue(ap);
+ TaggedValuePointable tempTvp = ppool.takeOne(TaggedValuePointable.class);
+ for (int i = 0; i < ap.getEntryCount(); i++) {
+ ap.getEntry(i, tempTvp);
+ process(tempTvp);
+ }
+ ppool.giveBack(ap);
+ ppool.giveBack(tempTvp);
+ }
+}
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantObjectsScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantObjectsScalarEvaluator.java
new file mode 100644
index 0000000..898f596
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantObjectsScalarEvaluator.java
@@ -0,0 +1,43 @@
+/*
+* 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.json;
+
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.vxquery.datamodel.accessors.TaggedValuePointable;
+import org.apache.vxquery.datamodel.accessors.jsonitem.ObjectPointable;
+
+import java.io.IOException;
+
+public class LibjnDescendantObjectsScalarEvaluator extends AbstractLibjnDescendantScalarEvaluator {
+
+ public LibjnDescendantObjectsScalarEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) {
+ super(ctx, args);
+ }
+
+ @Override
+ protected void processPair(TaggedValuePointable tvp, ObjectPointable op) {
+ tvp.getValue(stringp);
+ op.getValue(stringp, tvp);
+ }
+
+ @Override
+ protected void processObject(TaggedValuePointable tvp) throws IOException {
+ sb.addItem(tvp);
+ super.processObject(tvp);
+ }
+}
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantObjectsScalarEvaluatorFactory.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantObjectsScalarEvaluatorFactory.java
new file mode 100644
index 0000000..f905493
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantObjectsScalarEvaluatorFactory.java
@@ -0,0 +1,39 @@
+/*
+* 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.json;
+
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+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.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluatorFactory;
+
+public class LibjnDescendantObjectsScalarEvaluatorFactory extends AbstractTaggedValueArgumentScalarEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ public LibjnDescendantObjectsScalarEvaluatorFactory(IScalarEvaluatorFactory[] args) {
+ super(args);
+ }
+
+ @Override
+ protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args)
+ throws AlgebricksException {
+ return new LibjnDescendantObjectsScalarEvaluator(ctx, args);
+ }
+
+}
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantPairsScalarEvaluator.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantPairsScalarEvaluator.java
new file mode 100644
index 0000000..12f2c47
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantPairsScalarEvaluator.java
@@ -0,0 +1,49 @@
+/*
+* 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.json;
+
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.vxquery.datamodel.accessors.TaggedValuePointable;
+import org.apache.vxquery.datamodel.accessors.jsonitem.ObjectPointable;
+import org.apache.vxquery.datamodel.builders.jsonitem.ObjectBuilder;
+
+import java.io.IOException;
+
+public class LibjnDescendantPairsScalarEvaluator extends AbstractLibjnDescendantScalarEvaluator {
+
+ private final ObjectBuilder ob;
+ private final ArrayBackedValueStorage abvs1;
+
+ public LibjnDescendantPairsScalarEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args) {
+ super(ctx, args);
+ abvs1 = new ArrayBackedValueStorage();
+ ob = new ObjectBuilder();
+ }
+
+ @Override
+ protected void processPair(TaggedValuePointable tvp, ObjectPointable op) throws IOException {
+ abvs1.reset();
+ ob.reset(abvs1);
+ tvp.getValue(stringp);
+ op.getValue(stringp, tvp);
+ ob.addItem(stringp, tvp);
+ ob.finish();
+ sb.addItem(abvs1);
+ }
+}
diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantPairsScalarEvaluatorFactory.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantPairsScalarEvaluatorFactory.java
new file mode 100644
index 0000000..b2bfa9d
--- /dev/null
+++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/json/LibjnDescendantPairsScalarEvaluatorFactory.java
@@ -0,0 +1,39 @@
+/*
+* 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.json;
+
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+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.vxquery.runtime.functions.base.AbstractTaggedValueArgumentScalarEvaluatorFactory;
+
+public class LibjnDescendantPairsScalarEvaluatorFactory extends AbstractTaggedValueArgumentScalarEvaluatorFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ public LibjnDescendantPairsScalarEvaluatorFactory(IScalarEvaluatorFactory[] args) {
+ super(args);
+ }
+
+ @Override
+ protected IScalarEvaluator createEvaluator(IHyracksTaskContext ctx, IScalarEvaluator[] args)
+ throws AlgebricksException {
+ return new LibjnDescendantPairsScalarEvaluator(ctx, args);
+ }
+
+}
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Libraries/descendant_objects.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Libraries/descendant_objects.txt
new file mode 100644
index 0000000..fb50329
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Libraries/descendant_objects.txt
@@ -0,0 +1,5 @@
+{"foo":{"bar":[1,2]}}
+{"bar":[1,2]}
+{"foo":"bar","bar":"foo","array":["x",{"name":"riyafa","key":"value"},122,{"xy":123}]}
+{"name":"riyafa","key":"value"}
+{"xy":123}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Libraries/descendant_pairs.txt b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Libraries/descendant_pairs.txt
new file mode 100644
index 0000000..211a80a
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/ExpectedTestResults/Json/Libraries/descendant_pairs.txt
@@ -0,0 +1,4 @@
+{"foo":{"bar":[1,2]}}
+{"bar":[1,2]}
+{"foo":"bar"}
+{"bar":"foo"}
\ No newline at end of file
diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Libraries/descendant_objects.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Libraries/descendant_objects.xq
new file mode 100644
index 0000000..7cd1b14
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Libraries/descendant_objects.xq
@@ -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. :)
+
+(: JSONiq libjn:descendant_objects :)
+libjn:descendant-objects(
+ (
+ {
+ "foo":{
+ "bar":[
+ 1,
+ 2
+ ]
+ }
+ },
+ [
+ [
+ {
+ "foo":"bar",
+ "bar":"foo",
+ "array":[
+ "x",
+ {
+ "name":"riyafa",
+ "key":"value"
+ },
+ 122,
+ {
+ "xy":123
+ }
+ ]
+ }
+ ]
+ ],
+ true(),
+ 1,
+ jn:null()
+ )
+),
+
+libjn:descendant-objects([1, 2, 3]),
+
+libjn:descendant-objects(null)
diff --git a/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Libraries/descendant_pairs.xq b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Libraries/descendant_pairs.xq
new file mode 100644
index 0000000..91d2124
--- /dev/null
+++ b/vxquery-xtest/src/test/resources/Queries/XQuery/Json/Libraries/descendant_pairs.xq
@@ -0,0 +1,27 @@
+(: 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. :)
+
+(: JSONiq libjn:descendant_pairs :)
+libjn:descendant-pairs(
+ (
+ { "foo" : { "bar" : [ 1, 2 ] } },
+ [ [ { "foo" : "bar", "bar" : "foo" } ] ],
+ true(),
+ 1,
+ jn:null()
+ )
+)
diff --git a/vxquery-xtest/src/test/resources/cat/LibrariesInJSONiq.xml b/vxquery-xtest/src/test/resources/cat/LibrariesInJSONiq.xml
index 4de12e4..fcd0eac 100644
--- a/vxquery-xtest/src/test/resources/cat/LibrariesInJSONiq.xml
+++ b/vxquery-xtest/src/test/resources/cat/LibrariesInJSONiq.xml
@@ -40,9 +40,20 @@
<query name="flatten" date="2016-07-20"/>
<output-file compare="Text">flatten.txt</output-file>
</test-case>
+
<test-case name="values" FilePath="Json/Libraries/" Creator="Riyafa Abdul Hameed">
<description>Json Libraries.</description>
<query name="values" date="2016-07-31"/>
<output-file compare="Text">values.txt</output-file>
</test-case>
+ <test-case name="descendant_objects" FilePath="Json/Libraries/" Creator="Riyafa Abdul Hameed">
+ <description>Json Libraries.</description>
+ <query name="descendant_objects" date="2016-07-28"/>
+ <output-file compare="Text">descendant_objects.txt</output-file>
+ </test-case>
+ <test-case name="descendant_pairs" FilePath="Json/Libraries/" Creator="Riyafa Abdul Hameed">
+ <description>Json Libraries.</description>
+ <query name="descendant_pairs" date="2016-07-29"/>
+ <output-file compare="Text">descendant_pairs.txt</output-file>
+ </test-case>
</test-group>