Repository: asterixdb Updated Branches: refs/heads/master 4819ea447 -> 1a288e9f9
Adds a function: object_pairs. Change-Id: If57d83c88a813f19c3e64f9eec973b691c84d39b Reviewed-on: https://asterix-gerrit.ics.uci.edu/1288 Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Integration-Tests: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Reviewed-by: Till Westmann <ti...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/1a288e9f Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/1a288e9f Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/1a288e9f Branch: refs/heads/master Commit: 1a288e9f9992b23dde3178a7470c1c31a0d6f7be Parents: 4819ea4 Author: Yingyi Bu <yin...@couchbase.com> Authored: Fri Oct 14 18:46:25 2016 -0700 Committer: Yingyi Bu <buyin...@gmail.com> Committed: Fri Oct 14 20:49:53 2016 -0700 ---------------------------------------------------------------------- .../translator/util/FunctionCollection.java | 4 + .../queries_sqlpp/records/RecordsQueries.xml | 10 ++ .../object_pairs-2/object_pairs.1.ddl.sqlpp | 30 ++++ .../object_pairs-2/object_pairs.2.update.sqlpp | 23 +++ .../object_pairs-2/object_pairs.3.query.sqlpp | 25 ++++ .../object_pairs/object_pairs.1.query.sqlpp | 21 +++ .../records/object_pairs-2/object_pairs-2.1.adm | 3 + .../records/object_pairs/object_pairs.1.adm | 3 + .../lang/common/util/CommonFunctionMapUtil.java | 3 + .../om/functions/AsterixBuiltinFunctions.java | 4 + .../impl/RecordPairsTypeComputer.java | 50 +++++++ .../asterix/om/types/AOrderedListType.java | 3 +- .../records/RecordPairsDescriptor.java | 147 +++++++++++++++++++ .../runtime/formats/NonTaggedDataFormat.java | 35 ++++- 14 files changed, 356 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java index dd45c86..fc49503 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java @@ -259,6 +259,7 @@ import org.apache.asterix.runtime.evaluators.functions.records.GetRecordFieldVal import org.apache.asterix.runtime.evaluators.functions.records.GetRecordFieldsDescriptor; import org.apache.asterix.runtime.evaluators.functions.records.RecordAddFieldsDescriptor; import org.apache.asterix.runtime.evaluators.functions.records.RecordMergeDescriptor; +import org.apache.asterix.runtime.evaluators.functions.records.RecordPairsDescriptor; import org.apache.asterix.runtime.evaluators.functions.records.RecordRemoveFieldsDescriptor; import org.apache.asterix.runtime.evaluators.functions.temporal.AdjustDateTimeForTimeZoneDescriptor; import org.apache.asterix.runtime.evaluators.functions.temporal.AdjustTimeForTimeZoneDescriptor; @@ -681,6 +682,9 @@ public class FunctionCollection { // Cast function functionsToInjectUnkownHandling.add(CastTypeDescriptor.FACTORY); + // Record function + functionsToInjectUnkownHandling.add(RecordPairsDescriptor.FACTORY); + List<IFunctionDescriptorFactory> generatedFactories = new ArrayList<>(); for (IFunctionDescriptorFactory factory : functionsToInjectUnkownHandling) { generatedFactories http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/RecordsQueries.xml ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/RecordsQueries.xml b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/RecordsQueries.xml index 7c2b0a4..10a8702 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/RecordsQueries.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/RecordsQueries.xml @@ -103,6 +103,16 @@ </compilation-unit> </test-case> <test-case FilePath="records"> + <compilation-unit name="object_pairs"> + <output-dir compare="Text">object_pairs</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="records"> + <compilation-unit name="object_pairs-2"> + <output-dir compare="Text">object_pairs-2</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="records"> <compilation-unit name="open-record-constructor_01"> <output-dir compare="Text">open-record-constructor_01</output-dir> </compilation-unit> http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.1.ddl.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.1.ddl.sqlpp new file mode 100644 index 0000000..96752bf --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.1.ddl.sqlpp @@ -0,0 +1,30 @@ +/* + * 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 FacebookUserType as + open { + id : bigint +} + +create dataset FacebookUsers(FacebookUserType) primary key id; http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.2.update.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.2.update.sqlpp new file mode 100644 index 0000000..cdb516e --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.2.update.sqlpp @@ -0,0 +1,23 @@ +/* + * 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 FacebookUsers using localfs ((`path`=`asterix_nc1://data/tinysocial/fbu.adm`),(`format`=`adm`)); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.3.query.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.3.query.sqlpp new file mode 100644 index 0000000..39edbac --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs-2/object_pairs.3.query.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. + */ + +USE TinySocial; + +SELECT kv.name, COUNT(*) values +FROM FacebookUsers fu, fu.employment emp, OBJECT_PAIRS(emp) kv +GROUP BY kv.name +ORDER BY values, kv.name; http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs/object_pairs.1.query.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs/object_pairs.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs/object_pairs.1.query.sqlpp new file mode 100644 index 0000000..d7ea115 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/records/object_pairs/object_pairs.1.query.sqlpp @@ -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. + */ + +SELECT name, `value` FROM +object_pairs({"a":1, "b": "c", "d":[1, "e"]}) t; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-app/src/test/resources/runtimets/results/records/object_pairs-2/object_pairs-2.1.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/records/object_pairs-2/object_pairs-2.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/records/object_pairs-2/object_pairs-2.1.adm new file mode 100644 index 0000000..65692e8 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/records/object_pairs-2/object_pairs-2.1.adm @@ -0,0 +1,3 @@ +{ "values": 3, "name": "end-date" } +{ "values": 10, "name": "organization-name" } +{ "values": 10, "name": "start-date" } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-app/src/test/resources/runtimets/results/records/object_pairs/object_pairs.1.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/records/object_pairs/object_pairs.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/records/object_pairs/object_pairs.1.adm new file mode 100644 index 0000000..48c6c50 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/records/object_pairs/object_pairs.1.adm @@ -0,0 +1,3 @@ +{ "name": "a", "value": 1 } +{ "name": "b", "value": "c" } +{ "name": "d", "value": [ 1, "e" ] } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java index 6e7349e..ea373cb 100644 --- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java +++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java @@ -62,6 +62,9 @@ public class CommonFunctionMapUtil { FUNCTION_NAME_MAP.put("isarray", "is-array"); // isarray, internal: is-array FUNCTION_NAME_MAP.put("isobject", "is-object"); // isobject, internal: is-object FUNCTION_NAME_MAP.put("isobj", "is-object"); // isobj, internal: is-object + + // Record functions. + FUNCTION_NAME_MAP.put("object_pairs", "record-pairs"); // object_pairs, internal: record-pairs } private CommonFunctionMapUtil() { http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java index 873ea9e..29d6e88 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java @@ -88,6 +88,7 @@ import org.apache.asterix.om.typecomputer.impl.OrderedListOfAnyTypeComputer; import org.apache.asterix.om.typecomputer.impl.PropagateTypeComputer; import org.apache.asterix.om.typecomputer.impl.RecordAddFieldsTypeComputer; import org.apache.asterix.om.typecomputer.impl.RecordMergeTypeComputer; +import org.apache.asterix.om.typecomputer.impl.RecordPairsTypeComputer; import org.apache.asterix.om.typecomputer.impl.RecordRemoveFieldsTypeComputer; import org.apache.asterix.om.typecomputer.impl.ScalarVersionOfAggregateResultType; import org.apache.asterix.om.typecomputer.impl.StringBooleanTypeComputer; @@ -188,6 +189,8 @@ public class AsterixBuiltinFunctions { "get-record-fields", 1); public static final FunctionIdentifier GET_RECORD_FIELD_VALUE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "get-record-field-value", 2); + public static final FunctionIdentifier RECORD_PAIRS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, + "record-pairs", FunctionIdentifier.VARARGS); // numeric public static final FunctionIdentifier NUMERIC_UNARY_MINUS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, @@ -1063,6 +1066,7 @@ public class AsterixBuiltinFunctions { addPrivateFunction(FIELD_ACCESS_BY_NAME, FieldAccessByNameResultType.INSTANCE, true); addFunction(GET_RECORD_FIELDS, OrderedListOfAnyTypeComputer.INSTANCE, true); addFunction(GET_RECORD_FIELD_VALUE, FieldAccessNestedResultType.INSTANCE, true); + addFunction(RECORD_PAIRS, RecordPairsTypeComputer.INSTANCE, true); // temporal type accessors addFunction(ACCESSOR_TEMPORAL_YEAR, AInt64TypeComputer.INSTANCE, true); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java new file mode 100644 index 0000000..10b115f --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPairsTypeComputer.java @@ -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. + */ +package org.apache.asterix.om.typecomputer.impl; + +import org.apache.asterix.om.functions.AsterixBuiltinFunctions; +import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; +import org.apache.asterix.om.types.AOrderedListType; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.asterix.om.types.IAType; +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; + +public class RecordPairsTypeComputer extends AbstractResultTypeComputer { + + public static final RecordPairsTypeComputer INSTANCE = new RecordPairsTypeComputer(); + + private RecordPairsTypeComputer() { + } + + @Override + protected void checkArgType(int argIndex, IAType type) throws AlgebricksException { + ATypeTag typeTag = type.getTypeTag(); + if (typeTag != ATypeTag.RECORD) { + throw new AlgebricksException("Function " + AsterixBuiltinFunctions.RECORD_PAIRS + + " expects a record as the input, " + "but get a " + typeTag); + } + } + + @Override + public IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { + return AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE; + } + +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AOrderedListType.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AOrderedListType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AOrderedListType.java index a5af127..d523124 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AOrderedListType.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AOrderedListType.java @@ -18,7 +18,6 @@ */ package org.apache.asterix.om.types; -import org.apache.asterix.om.base.AOrderedList; import org.apache.asterix.om.base.IAObject; import org.json.JSONException; import org.json.JSONObject; @@ -27,7 +26,7 @@ public class AOrderedListType extends AbstractCollectionType { private static final long serialVersionUID = 1L; - public static final AOrderedListType FULL_OPEN_ORDEREDLIST_TYPE = new AOrderedListType(null,""); + public static final AOrderedListType FULL_OPEN_ORDEREDLIST_TYPE = new AOrderedListType(BuiltinType.ANY, ""); /** * @param itemType http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPairsDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPairsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPairsDescriptor.java new file mode 100644 index 0000000..b6aedb4 --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPairsDescriptor.java @@ -0,0 +1,147 @@ +/* + * 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.io.IOException; +import java.util.List; + +import org.apache.asterix.builders.OrderedListBuilder; +import org.apache.asterix.builders.RecordBuilder; +import org.apache.asterix.dataflow.data.nontagged.serde.AObjectSerializerDeserializer; +import org.apache.asterix.om.base.AString; +import org.apache.asterix.om.functions.AsterixBuiltinFunctions; +import org.apache.asterix.om.functions.IFunctionDescriptor; +import org.apache.asterix.om.functions.IFunctionDescriptorFactory; +import org.apache.asterix.om.pointables.ARecordVisitablePointable; +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.EnumDeserializer; +import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; +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; + +public class RecordPairsDescriptor extends AbstractScalarFunctionDynamicDescriptor { + + public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { + @Override + public IFunctionDescriptor createFunctionDescriptor() { + return new RecordPairsDescriptor(); + } + }; + + private static final long serialVersionUID = 1L; + private ARecordType recType; + + public void reset(ARecordType recType) { + this.recType = recType; + } + + @Override + public FunctionIdentifier getIdentifier() { + return AsterixBuiltinFunctions.RECORD_PAIRS; + } + + @Override + public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) { + return new IScalarEvaluatorFactory() { + private static final long serialVersionUID = 1L; + + @Override + public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException { + // For writing each individual output record. + final ArrayBackedValueStorage itemStorage = new ArrayBackedValueStorage(); + final DataOutput itemOutput = itemStorage.getDataOutput(); + final RecordBuilder recBuilder = new RecordBuilder(); + recBuilder.reset(ARecordType.FULLY_OPEN_RECORD_TYPE); + + // For writing the resulting list of records. + final OrderedListBuilder listBuilder = new OrderedListBuilder(); + final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); + final DataOutput resultOut = resultStorage.getDataOutput(); + + // Sets up the constant field names, "name" for the key field, "value" for the value field. + final ArrayBackedValueStorage nameStorage = new ArrayBackedValueStorage(); + final ArrayBackedValueStorage valueStorage = new ArrayBackedValueStorage(); + AObjectSerializerDeserializer serde = AObjectSerializerDeserializer.INSTANCE; + try { + serde.serialize(new AString("name"), nameStorage.getDataOutput()); + serde.serialize(new AString("value"), valueStorage.getDataOutput()); + } catch (IOException e) { + throw new AlgebricksException(e); + } + + return new IScalarEvaluator() { + private final IScalarEvaluator argEvaluator = args[0].createScalarEvaluator(ctx); + private final IPointable argPtr = new VoidPointable(); + private final ARecordVisitablePointable recordVisitablePointable = new ARecordVisitablePointable( + recType); + + @Override + public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException { + try { + // Resets the result storage. + resultStorage.reset(); + + // Gets the input record. + argEvaluator.evaluate(tuple, argPtr); + byte inputTypeTag = argPtr.getByteArray()[argPtr.getStartOffset()]; + if (inputTypeTag != ATypeTag.SERIALIZED_RECORD_TYPE_TAG) { + throw new AlgebricksException("Function " + RecordPairsDescriptor.this.getIdentifier() + + " expects a record as the input, " + "but get a " + + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(inputTypeTag)); + } + recordVisitablePointable.set(argPtr); + + listBuilder.reset(AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE); + List<IVisitablePointable> fieldNames = recordVisitablePointable.getFieldNames(); + List<IVisitablePointable> fieldValues = recordVisitablePointable.getFieldValues(); + // Adds each field of the input record as a key-value pair into the result. + int numFields = recordVisitablePointable.getFieldNames().size(); + for (int fieldIndex = 0; fieldIndex < numFields; ++fieldIndex) { + itemStorage.reset(); + recBuilder.init(); + recBuilder.addField(nameStorage, fieldNames.get(fieldIndex)); + recBuilder.addField(valueStorage, fieldValues.get(fieldIndex)); + recBuilder.write(itemOutput, true); + listBuilder.addItem(itemStorage); + } + + // Writes the result and sets the result pointable. + listBuilder.write(resultOut, true); + result.set(resultStorage); + } catch (HyracksDataException e) { + throw new AlgebricksException(e); + } + } + }; + } + }; + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1a288e9f/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java index 5955e57..c046743 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java @@ -553,6 +553,10 @@ public class NonTaggedDataFormat implements IDataFormat { listFieldPath); break; } + case ANY: + PA.invokeMethod(fd, "reset(org.apache.asterix.om.types.ARecordType, java.util.List)", + ARecordType.FULLY_OPEN_RECORD_TYPE, listFieldPath); + break; default: { throw new NotImplementedException("field-access-nested for data of type " + t); } @@ -565,9 +569,13 @@ public class NonTaggedDataFormat implements IDataFormat { throws AlgebricksException { AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr; IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue()); - if (t.getTypeTag().equals(ATypeTag.RECORD)) { + ATypeTag typeTag = t.getTypeTag(); + if (typeTag.equals(ATypeTag.RECORD)) { ARecordType recType = (ARecordType) t; PA.invokeMethod(fd, "reset(org.apache.asterix.om.types.ARecordType)", recType); + } else if (typeTag.equals(ATypeTag.ANY)) { + PA.invokeMethod(fd, "reset(org.apache.asterix.om.types.ARecordType)", + ARecordType.FULLY_OPEN_RECORD_TYPE); } else { throw new NotImplementedException("get-record-fields for data of type " + t); } @@ -579,15 +587,36 @@ public class NonTaggedDataFormat implements IDataFormat { throws AlgebricksException { AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr; IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue()); - if (t.getTypeTag().equals(ATypeTag.RECORD)) { + ATypeTag typeTag = t.getTypeTag(); + if (typeTag.equals(ATypeTag.RECORD)) { ARecordType recType = (ARecordType) t; PA.invokeMethod(fd, "reset(org.apache.asterix.om.types.ARecordType)", recType); + } else if (typeTag.equals(ATypeTag.ANY)) { + PA.invokeMethod(fd, "reset(org.apache.asterix.om.types.ARecordType)", + ARecordType.FULLY_OPEN_RECORD_TYPE); } else { throw new NotImplementedException("get-record-field-value for data of type " + t); } } }); - + functionTypeInferers.put(AsterixBuiltinFunctions.RECORD_PAIRS, new FunctionTypeInferer() { + @Override + public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context) + throws AlgebricksException { + AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr; + IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue()); + ATypeTag typeTag = t.getTypeTag(); + if (typeTag.equals(ATypeTag.RECORD)) { + ARecordType recType = (ARecordType) t; + PA.invokeMethod(fd, "reset(org.apache.asterix.om.types.ARecordType)", recType); + } else if (typeTag.equals(ATypeTag.ANY)) { + PA.invokeMethod(fd, "reset(org.apache.asterix.om.types.ARecordType)", + ARecordType.FULLY_OPEN_RECORD_TYPE); + } else { + throw new NotImplementedException("record-fields with data of type " + t); + } + } + }); } @Override