Ali Alsuliman has uploaded a new change for review. https://asterix-gerrit.ics.uci.edu/2725
Change subject: [NO ISSUE][FUN] Implement array_reverse() function ...................................................................... [NO ISSUE][FUN] Implement array_reverse() function - user model changes: no - storage format changes: no - interface changes: no details: This is part of implementing array functions. The array_reverse() takes an input list and returns a new list with the elements in reverse. array_reverse(list). Change-Id: Ib9d9f8e760390a708d67a2cab357bf4722271381 --- A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.1.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.2.update.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.3.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.4.ddl.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_reverse/array_reverse.3.adm M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListTypeComputer.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayReverseDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java 10 files changed, 321 insertions(+), 0 deletions(-) git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/25/2725/1 diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.1.ddl.sqlpp new file mode 100755 index 0000000..257c4dd --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.1.ddl.sqlpp @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +drop 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, + name : string, + followers_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 TweetMessages(TweetMessageType) primary key tweetid hints (`CARDINALITY`=`100`); \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.2.update.sqlpp new file mode 100755 index 0000000..4a0e7ed --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.2.update.sqlpp @@ -0,0 +1,22 @@ +/* + * 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. + */ + +use TinySocial; + +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/array_fun/array_reverse/array_reverse.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.3.query.sqlpp new file mode 100755 index 0000000..70e09a6 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.3.query.sqlpp @@ -0,0 +1,32 @@ +/* + * 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. + */ + +use TinySocial; + +{ + "t1": (select array_reverse(t.`referred-topics`) from TweetMessages t order by t.tweetid), + "t2": (select array_reverse([5, 7, 19])), + "t3": (select array_reverse([5, 7.5, 19])), + "t4": (select array_reverse([5, 7.5, 19, "John"])), + "t5": (select array_reverse([3])), + "t6": (select array_reverse("non_array")), + "t7": (select array_reverse([])), + "t8": (select array_reverse(missing)), + "t9": (select array_reverse(null)) +}; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.4.ddl.sqlpp new file mode 100755 index 0000000..3f8c8ec --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_reverse/array_reverse.4.ddl.sqlpp @@ -0,0 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +drop dataverse TinySocial; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_reverse/array_reverse.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_reverse/array_reverse.3.adm new file mode 100644 index 0000000..57e5a3c --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_reverse/array_reverse.3.adm @@ -0,0 +1 @@ +{ "t1": [ { "$1": {{ "customization", "t-mobile" }} }, { "$1": {{ "voice-clarity", "verizon" }} }, { "$1": {{ "platform", "iphone" }} }, { "$1": {{ "voice-command", "samsung" }} }, { "$1": {{ "shortcut-menu", "verizon" }} }, { "$1": {{ "speed", "motorola" }} }, { "$1": {{ "voice-command", "sprint" }} }, { "$1": {{ "speed", "motorola" }} }, { "$1": {{ "voice-clarity", "iphone" }} }, { "$1": {{ "platform", "samsung" }} }, { "$1": {{ "shortcut-menu", "t-mobile" }} }, { "$1": {{ "voicemail-service", "verizon" }} } ], "t2": [ { "$2": [ 19, 7, 5 ] } ], "t3": [ { "$3": [ 19, 7.5, 5 ] } ], "t4": [ { "$4": [ "John", 19, 7.5, 5 ] } ], "t5": [ { "$5": [ 3 ] } ], "t6": [ { "$6": null } ], "t7": [ { "$7": [ ] } ], "t8": [ { } ], "t9": [ { "$9": null } ] } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml index 0934e56..14b4cc1 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml @@ -995,6 +995,11 @@ <expected-error>HYR0115: Cannot compare non-primitive values (in line 22, at column 8)</expected-error> </compilation-unit> </test-case> + <test-case FilePath="array_fun"> + <compilation-unit name="array_reverse"> + <output-dir compare="Text">array_reverse</output-dir> + </compilation-unit> + </test-case> </test-group> <test-group name="boolean"> <test-case FilePath="boolean"> 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 f73533c..1570cab 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 @@ -43,6 +43,7 @@ import org.apache.asterix.om.typecomputer.impl.AInt8TypeComputer; import org.apache.asterix.om.typecomputer.impl.AIntervalTypeComputer; import org.apache.asterix.om.typecomputer.impl.ALineTypeComputer; +import org.apache.asterix.om.typecomputer.impl.AListTypeComputer; import org.apache.asterix.om.typecomputer.impl.APoint3DTypeComputer; import org.apache.asterix.om.typecomputer.impl.APointTypeComputer; import org.apache.asterix.om.typecomputer.impl.APolygonTypeComputer; @@ -187,6 +188,8 @@ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "array-append", FunctionIdentifier.VARARGS); public static final FunctionIdentifier ARRAY_POSITION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "array-position", 2); + public static final FunctionIdentifier ARRAY_REVERSE = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "array-reverse", 1); // objects public static final FunctionIdentifier RECORD_MERGE = @@ -1464,6 +1467,7 @@ // array functions addFunction(ARRAY_APPEND, ArrayAppendTypeComputer.INSTANCE, true); addFunction(ARRAY_POSITION, AInt32TypeComputer.INSTANCE, true); + addFunction(ARRAY_REVERSE, AListTypeComputer.INSTANCE, true); // objects addFunction(RECORD_MERGE, RecordMergeTypeComputer.INSTANCE, true); diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListTypeComputer.java new file mode 100644 index 0000000..92730f5 --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListTypeComputer.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.asterix.om.typecomputer.impl; + +import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; +import org.apache.asterix.om.types.BuiltinType; +import org.apache.asterix.om.types.IAType; +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; + +/** + * A type computer that returns the same list type as the presumably input list at argument 0. If the argument is not a + * list, it returns "ANY". + */ +public class AListTypeComputer extends AbstractResultTypeComputer { + public static final AListTypeComputer INSTANCE = new AListTypeComputer(); + + private AListTypeComputer() { + } + + @Override + protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { + IAType argType = strippedInputTypes[0]; + switch (argType.getTypeTag()) { + case ARRAY: + case MULTISET: + return argType; + default: + return BuiltinType.ANY; + } + } +} diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayReverseDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayReverseDescriptor.java new file mode 100755 index 0000000..eed50ca --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayReverseDescriptor.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.asterix.runtime.evaluators.functions; + +import java.io.IOException; + +import org.apache.asterix.builders.IAsterixListBuilder; +import org.apache.asterix.builders.OrderedListBuilder; +import org.apache.asterix.builders.UnorderedListBuilder; +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.ATypeTag; +import org.apache.asterix.om.types.AbstractCollectionType; +import org.apache.asterix.om.types.IAType; +import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; +import org.apache.asterix.runtime.evaluators.common.ListAccessor; +import org.apache.asterix.runtime.functions.FunctionTypeInferers; +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +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; +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; + +/** + * array_reverse(list) returns a new list with the entries of the original input list in reverse order. If the input is + * not a list, it returns "null". + */ +public class ArrayReverseDescriptor extends AbstractScalarFunctionDynamicDescriptor { + private static final long serialVersionUID = 1L; + private IAType inputListType; + + public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { + @Override + public IFunctionDescriptor createFunctionDescriptor() { + return new ArrayReverseDescriptor(); + } + + @Override + public IFunctionTypeInferer createFunctionTypeInferer() { + // the type of the input list is needed in order to use the same type for the new returned list + return FunctionTypeInferers.SET_ARGUMENT_TYPE; + } + + }; + + @Override + public FunctionIdentifier getIdentifier() { + return BuiltinFunctions.ARRAY_REVERSE; + } + + @Override + public void setImmutableStates(Object... states) { + inputListType = (IAType) states[0]; + } + + @Override + public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) + throws AlgebricksException { + return new IScalarEvaluatorFactory() { + private static final long serialVersionUID = 1L; + + @Override + public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException { + return new ArrayReverseFunction(args, ctx); + } + }; + } + + public class ArrayReverseFunction implements IScalarEvaluator { + private final ArrayBackedValueStorage storage; + private final IScalarEvaluator listArgEval; + private final ListAccessor listAccessor; + private final IPointable listArg; + + public ArrayReverseFunction(IScalarEvaluatorFactory[] args, IHyracksTaskContext ctx) + throws HyracksDataException { + storage = new ArrayBackedValueStorage(); + listArg = new VoidPointable(); + listArgEval = args[0].createScalarEvaluator(ctx); + listAccessor = new ListAccessor(); + } + + @Override + public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException { + // get the list argument and make sure it's a list + listArgEval.evaluate(tuple, listArg); + byte listArgType = listArg.getByteArray()[listArg.getStartOffset()]; + + // create the new list with the same type as the input list + IAsterixListBuilder listBuilder; + if (listArgType == ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG) { + listBuilder = new OrderedListBuilder(); + } else if (listArgType == ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG) { + listBuilder = new UnorderedListBuilder(); + } else { + PointableHelper.setNull(result); + return; + } + + listBuilder.reset((AbstractCollectionType) inputListType); + listAccessor.reset(listArg.getByteArray(), listArg.getStartOffset()); + try { + // get the list items in reverse and append to the new list + for (int i = listAccessor.size() - 1; i >= 0; i--) { + storage.reset(); + listAccessor.writeItem(i, storage.getDataOutput()); + listBuilder.addItem(storage); + } + storage.reset(); + listBuilder.write(storage.getDataOutput(), true); + result.set(storage); + } catch (IOException e) { + throw HyracksDataException.create(e); + } + } + } +} 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 f64df0a..45dc76c 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 @@ -145,6 +145,7 @@ import org.apache.asterix.runtime.evaluators.functions.AnyCollectionMemberDescriptor; import org.apache.asterix.runtime.evaluators.functions.ArrayAppendDescriptor; import org.apache.asterix.runtime.evaluators.functions.ArrayPositionDescriptor; +import org.apache.asterix.runtime.evaluators.functions.ArrayReverseDescriptor; import org.apache.asterix.runtime.evaluators.functions.CastTypeDescriptor; import org.apache.asterix.runtime.evaluators.functions.CastTypeLaxDescriptor; import org.apache.asterix.runtime.evaluators.functions.CheckUnknownDescriptor; @@ -374,6 +375,7 @@ // array functions fc.addGenerated(ArrayAppendDescriptor.FACTORY); fc.addGenerated(ArrayPositionDescriptor.FACTORY); + fc.addGenerated(ArrayReverseDescriptor.FACTORY); // unnesting functions fc.add(TidRunningAggregateDescriptor.FACTORY); -- To view, visit https://asterix-gerrit.ics.uci.edu/2725 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib9d9f8e760390a708d67a2cab357bf4722271381 Gerrit-PatchSet: 1 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Ali Alsuliman <[email protected]>
