Murtadha Hubail has submitted this change and it was merged. Change subject: [NO ISSUE][FUN] Implement object-values() ......................................................................
[NO ISSUE][FUN] Implement object-values() - user model changes: no - storage format changes: no - interface changes: no Details: - Implement object-values function that returns an array of values of the fileds in a given object. - Add new functions to docs. - Add test cases. Change-Id: I804fb75d20837ae01b8f34f6389dcb3480ce5548 Reviewed-on: https://asterix-gerrit.ics.uci.edu/2718 Reviewed-by: Murtadha Hubail <[email protected]> Sonar-Qube: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Contrib: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> Reviewed-by: Till Westmann <[email protected]> --- M asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.1.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.2.update.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.3.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.4.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_values/object_values.3.adm M asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesDescriptor.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesEvaluator.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java 11 files changed, 354 insertions(+), 1 deletion(-) Approvals: Anon. E. Moose #1000171: Till Westmann: Looks good to me, approved Jenkins: Verified; No violations found; ; Verified Murtadha Hubail: Looks good to me, but someone else must approve diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml index 42eeedd..9eca213 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml @@ -151,6 +151,11 @@ </compilation-unit> </test-case> <test-case FilePath="objects"> + <compilation-unit name="object_values"> + <output-dir compare="Text">object_values</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="objects"> <compilation-unit name="object_pairs"> <output-dir compare="Text">object_pairs</output-dir> </compilation-unit> diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.1.ddl.sqlpp new file mode 100644 index 0000000..1242661 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.1.ddl.sqlpp @@ -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. + */ + +/* + * Description : Testing object_values under different queries. + * Expected Res : Success + */ + +drop dataverse TinySocial if exists; +create dataverse TinySocial; + +use TinySocial; + +create type TinySocial.TwitterUserType as +{ + `screen-name` : string, + lang : string, + friends_count : bigint, + statuses_count : bigint +}; + +create type TinySocial.TweetMessageType as closed { + tweetid : string, + user : TwitterUserType, + `sender-location` : point?, + `send-time` : datetime, + `referred-topics` : {{string}}, + `message-text` : string +}; + +create dataset TwitterUsers(TwitterUserType) primary key `screen-name`; + +create dataset TweetMessages(TweetMessageType) primary key tweetid; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.2.update.sqlpp new file mode 100644 index 0000000..72edf0c --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.2.update.sqlpp @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * Description : Testing object_values under different queries. + * Expected Res : Success + */ + +use TinySocial; + +load dataset TwitterUsers using localfs ((`path`=`asterix_nc1://data/tinysocial/twu.adm`),(`format`=`adm`)); + +load dataset TweetMessages using localfs ((`path`=`asterix_nc1://data/tinysocial/twm.adm`),(`format`=`adm`)); diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.3.query.sqlpp new file mode 100644 index 0000000..ebd0a80 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.3.query.sqlpp @@ -0,0 +1,50 @@ +/* + * 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. + */ + +/* + * Description : Testing object_values under different queries. + * Expected Res : Success + */ + +use TinySocial; + +{ + "t1": [ + object_values(missing) is missing, + object_values(null) is null, + object_values("non-object") is null + ], + "t2": object_values({"object":{"a":3}, "array":[1,2], "primitive": 4}), + + /* open type */ + "t3": ( + select value object_values(u) + from TwitterUsers as u + order by u.screen-name + limit 1 + ), + + /* closed type */ + "t4": ( + select value object_values(m) + from TweetMessages as m + order by m.tweetid + limit 1 + ) +}; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.4.ddl.sqlpp new file mode 100644 index 0000000..158cefa --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_values/object_values.4.ddl.sqlpp @@ -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. + */ + +/* + * Description : Testing object_values under different queries. + * Expected Res : Success + */ + +drop dataverse TinySocial; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_values/object_values.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_values/object_values.3.adm new file mode 100644 index 0000000..2216760 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_values/object_values.3.adm @@ -0,0 +1 @@ +{ "t1": [ true, true, true ], "t2": [ { "a": 3 }, [ 1, 2 ], 4 ], "t3": [ [ "ChangEwing_573", "en", 182, 394, "Chang Ewing", 32136 ] ], "t4": [ [ "1", { "screen-name": "NathanGiesen@211", "lang": "en", "friends_count": 39339, "statuses_count": 473, "name": "Nathan Giesen", "followers_count": 49416 }, point("47.44,80.65"), datetime("2008-04-26T10:10:00.000Z"), {{ "t-mobile", "customization" }}, " love t-mobile its customization is good:)" ] ] } \ No newline at end of file diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md b/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md index be2e008..6596b99 100644 --- a/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md +++ b/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md @@ -498,3 +498,35 @@ "project": "Apache AsterixDB", "location": {"city": "Irvine", "state": "CA"} } + +### object_values ### + * Syntax: + + object_values(input_object) + + * Returns an array of the values of the fields in `input_object`. + * Arguments: + * `input_object` : an object value. + * Return Value: + * An array of the values of the fields in `input_object`, + * `missing` if `input_object` is `missing`, + * `null` if `input_object` is null or any non-object value. + + * Example: + + object_values( + { + "id": 1, + "project": "AsterixDB", + "address": {"city": "Irvine", "state": "CA"} + } + ); + + * The expected result is: + + [ + 1, + "AsterixDB", + {"city": "Irvine", "state": "CA"} + ] + diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java index c73680c..249e169 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java @@ -232,6 +232,8 @@ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-add", 3); public static final FunctionIdentifier RECORD_PUT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-put", 3); + public static final FunctionIdentifier RECORD_VALUES = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-values", 1); // numeric public static final FunctionIdentifier NUMERIC_UNARY_MINUS = @@ -1483,6 +1485,7 @@ addFunction(RECORD_REPLACE, OpenARecordTypeComputer.INSTANCE, true); addFunction(RECORD_ADD, OpenARecordTypeComputer.INSTANCE, true); addFunction(RECORD_PUT, OpenARecordTypeComputer.INSTANCE, true); + addFunction(RECORD_VALUES, OrderedListOfAnyTypeComputer.INSTANCE, true); // temporal type accessors addFunction(ACCESSOR_TEMPORAL_YEAR, AInt64TypeComputer.INSTANCE, true); diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesDescriptor.java new file mode 100644 index 0000000..6e7bf03 --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesDescriptor.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.asterix.runtime.evaluators.functions.records; + +import org.apache.asterix.om.functions.BuiltinFunctions; +import org.apache.asterix.om.functions.IFunctionDescriptor; +import org.apache.asterix.om.functions.IFunctionDescriptorFactory; +import org.apache.asterix.om.functions.IFunctionTypeInferer; +import org.apache.asterix.om.types.ARecordType; +import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; +import org.apache.asterix.runtime.functions.FunctionTypeInferers; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; +import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; +import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; +import org.apache.hyracks.api.context.IHyracksTaskContext; +import org.apache.hyracks.api.exceptions.HyracksDataException; + +public class RecordValuesDescriptor extends AbstractScalarFunctionDynamicDescriptor { + + public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { + @Override + public IFunctionDescriptor createFunctionDescriptor() { + return new RecordValuesDescriptor(); + } + + @Override + public IFunctionTypeInferer createFunctionTypeInferer() { + return FunctionTypeInferers.RecordAccessorTypeInferer.INSTANCE_LAX; + } + }; + + private static final long serialVersionUID = 1L; + private ARecordType recordType; + + @Override + public void setImmutableStates(Object... states) { + recordType = (ARecordType) states[0]; + } + + @Override + public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) { + return new IScalarEvaluatorFactory() { + private static final long serialVersionUID = 1L; + + @Override + public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws HyracksDataException { + return new RecordValuesEvaluator(args[0].createScalarEvaluator(ctx), recordType); + } + }; + } + + @Override + public FunctionIdentifier getIdentifier() { + return BuiltinFunctions.RECORD_VALUES; + } +} diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesEvaluator.java new file mode 100644 index 0000000..83de818 --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesEvaluator.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.asterix.runtime.evaluators.functions.records; + +import java.io.DataOutput; +import java.util.List; + +import org.apache.asterix.builders.OrderedListBuilder; +import org.apache.asterix.om.pointables.ARecordVisitablePointable; +import org.apache.asterix.om.pointables.base.DefaultOpenFieldType; +import org.apache.asterix.om.pointables.base.IVisitablePointable; +import org.apache.asterix.om.types.AOrderedListType; +import org.apache.asterix.om.types.ARecordType; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.asterix.om.types.BuiltinType; +import org.apache.asterix.runtime.evaluators.functions.CastTypeEvaluator; +import org.apache.asterix.runtime.evaluators.functions.PointableHelper; +import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; +import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.apache.hyracks.data.std.api.IPointable; +import org.apache.hyracks.data.std.primitive.VoidPointable; +import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; +import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; + +class RecordValuesEvaluator implements IScalarEvaluator { + + private final IPointable inputRecordPointable = new VoidPointable(); + private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); + private final DataOutput resultOutput = resultStorage.getDataOutput(); + private final IScalarEvaluator eval0; + private OrderedListBuilder listBuilder; + private ARecordVisitablePointable openRecordPointable; + private CastTypeEvaluator inputRecordCaster; + + RecordValuesEvaluator(IScalarEvaluator eval0, ARecordType recordType) { + this.eval0 = eval0; + if (recordType != null) { + openRecordPointable = new ARecordVisitablePointable(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE); + inputRecordCaster = new CastTypeEvaluator(BuiltinType.ANY, recordType, eval0); + listBuilder = new OrderedListBuilder(); + } + } + + @Override + public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException { + resultStorage.reset(); + eval0.evaluate(tuple, inputRecordPointable); + final ATypeTag inputTypeTag = PointableHelper.getTypeTag(inputRecordPointable); + if (inputTypeTag != ATypeTag.OBJECT) { + PointableHelper.setNull(result); + return; + } + inputRecordCaster.evaluate(tuple, inputRecordPointable); + resultStorage.reset(); + buildOutputList(); + result.set(resultStorage); + } + + private void buildOutputList() throws HyracksDataException { + listBuilder.reset(AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE); + openRecordPointable.set(inputRecordPointable); + final List<IVisitablePointable> fieldValues = openRecordPointable.getFieldValues(); + for (int i = 0, valuesCount = fieldValues.size(); i < valuesCount; i++) { + listBuilder.addItem(fieldValues.get(i)); + } + listBuilder.write(resultOutput, true); + } +} \ No newline at end of file diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java index f69ee7c..406c5b9 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java @@ -287,8 +287,9 @@ import org.apache.asterix.runtime.evaluators.functions.records.RecordRemoveDescriptor; import org.apache.asterix.runtime.evaluators.functions.records.RecordRemoveFieldsDescriptor; import org.apache.asterix.runtime.evaluators.functions.records.RecordRenameDescriptor; -import org.apache.asterix.runtime.evaluators.functions.records.RecordUnwrapDescriptor; import org.apache.asterix.runtime.evaluators.functions.records.RecordReplaceDescriptor; +import org.apache.asterix.runtime.evaluators.functions.records.RecordUnwrapDescriptor; +import org.apache.asterix.runtime.evaluators.functions.records.RecordValuesDescriptor; import org.apache.asterix.runtime.evaluators.functions.temporal.AdjustDateTimeForTimeZoneDescriptor; import org.apache.asterix.runtime.evaluators.functions.temporal.AdjustTimeForTimeZoneDescriptor; import org.apache.asterix.runtime.evaluators.functions.temporal.CalendarDuartionFromDateDescriptor; @@ -660,6 +661,7 @@ fc.add(RecordReplaceDescriptor.FACTORY); fc.add(RecordAddDescriptor.FACTORY); fc.add(RecordPutDescriptor.FACTORY); + fc.addGenerated(RecordValuesDescriptor.FACTORY); // Spatial and temporal type accessors fc.addGenerated(TemporalYearAccessor.FACTORY); -- To view, visit https://asterix-gerrit.ics.uci.edu/2718 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: I804fb75d20837ae01b8f34f6389dcb3480ce5548 Gerrit-PatchSet: 5 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Murtadha Hubail <[email protected]> Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Dmitry Lychagin <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Murtadha Hubail <[email protected]> Gerrit-Reviewer: Till Westmann <[email protected]>
